IVGCVSW-5166 Pull out the common and server side code into standalone libraries

Change-Id: I180f84c493a9b2be4b93b25d312ebdd9e71b1735
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
diff --git a/profiling/common/src/CMakeLists.txt b/profiling/common/src/CMakeLists.txt
new file mode 100644
index 0000000..9505fb8
--- /dev/null
+++ b/profiling/common/src/CMakeLists.txt
@@ -0,0 +1,30 @@
+#
+# Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
+# SPDX-License-Identifier: MIT
+#
+
+if(BUILD_TIMELINE_DECODER)
+    set(pipeCommon_sources)
+    list(APPEND pipeCommon_sources
+        CommandHandlerFunctor.cpp
+        CommandHandlerKey.cpp
+        CommandHandlerRegistry.cpp
+        CommonProfilingUtils.cpp
+        NetworkSockets.cpp
+        PacketVersionResolver.cpp
+        SwTrace.cpp)
+
+    include_directories(${PROJECT_SOURCE_DIR}/profiling/common/include)
+    include_directories(${PROJECT_SOURCE_DIR}/common/include)
+
+    if(BUILD_UNIT_TESTS)
+        include_directories(${PROJECT_SOURCE_DIR}/src/profiling
+                            ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+        target_include_directories(UnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+    endif()
+
+    # will only build a static version of this common code
+    # to simplify the build. No extra .so file to deploy to boards etc.
+    add_library_ex(pipeCommon STATIC ${pipeCommon_sources})
+
+endif()
diff --git a/profiling/common/src/CommandHandlerFunctor.cpp b/profiling/common/src/CommandHandlerFunctor.cpp
new file mode 100644
index 0000000..ea24cfb
--- /dev/null
+++ b/profiling/common/src/CommandHandlerFunctor.cpp
@@ -0,0 +1,31 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "CommandHandlerFunctor.hpp"
+
+namespace arm
+{
+
+namespace pipe
+{
+
+uint32_t CommandHandlerFunctor::GetFamilyId() const
+{
+    return m_FamilyId;
+}
+
+uint32_t CommandHandlerFunctor::GetPacketId() const
+{
+    return m_PacketId;
+}
+
+uint32_t CommandHandlerFunctor::GetVersion() const
+{
+    return m_Version;
+}
+
+} // namespace pipe
+
+} // namespace arm
diff --git a/profiling/common/src/CommandHandlerKey.cpp b/profiling/common/src/CommandHandlerKey.cpp
new file mode 100644
index 0000000..98e4567
--- /dev/null
+++ b/profiling/common/src/CommandHandlerKey.cpp
@@ -0,0 +1,77 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "CommandHandlerKey.hpp"
+
+namespace arm
+{
+
+namespace pipe
+{
+
+uint32_t CommandHandlerKey::GetFamilyId() const
+{
+    return m_FamilyId;
+}
+
+uint32_t CommandHandlerKey::GetPacketId() const
+{
+    return m_PacketId;
+}
+
+uint32_t CommandHandlerKey::GetVersion() const
+{
+    return m_Version;
+}
+
+bool CommandHandlerKey::operator<(const CommandHandlerKey& rhs) const
+{
+    bool result = true;
+    if (m_FamilyId == rhs.m_FamilyId)
+    {
+        if (m_PacketId == rhs.m_PacketId)
+        {
+            result = m_Version < rhs.m_Version;
+        }
+        else if (m_PacketId > rhs.m_PacketId)
+        {
+            result = false;
+        }
+    }
+    else if (m_FamilyId > rhs.m_FamilyId)
+    {
+        result = false;
+    }
+    return result;
+}
+
+bool CommandHandlerKey::operator>(const CommandHandlerKey& rhs) const
+{
+    return rhs < *this;
+}
+
+bool CommandHandlerKey::operator<=(const CommandHandlerKey& rhs) const
+{
+    return !(*this > rhs);
+}
+
+bool CommandHandlerKey::operator>=(const CommandHandlerKey& rhs) const
+{
+    return !(*this < rhs);
+}
+
+bool CommandHandlerKey::operator==(const CommandHandlerKey& rhs) const
+{
+    return m_FamilyId == rhs.m_FamilyId && m_PacketId == rhs.m_PacketId && m_Version == rhs.m_Version;
+}
+
+bool CommandHandlerKey::operator!=(const CommandHandlerKey& rhs) const
+{
+    return !(*this == rhs);
+}
+
+} // namespace pipe
+
+} // namespace arm
diff --git a/profiling/common/src/CommandHandlerRegistry.cpp b/profiling/common/src/CommandHandlerRegistry.cpp
new file mode 100644
index 0000000..324737e
--- /dev/null
+++ b/profiling/common/src/CommandHandlerRegistry.cpp
@@ -0,0 +1,61 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+
+#include <common/include/Assert.hpp>
+#include <common/include/CommandHandlerRegistry.hpp>
+
+#include <sstream>
+
+namespace arm
+{
+
+namespace pipe
+{
+
+void CommandHandlerRegistry::RegisterFunctor(CommandHandlerFunctor* functor,
+                                             uint32_t familyId,
+                                             uint32_t packetId,
+                                             uint32_t version)
+{
+    ARM_PIPE_ASSERT_MSG(functor, "Provided functor should not be a nullptr");
+
+    CommandHandlerKey key(familyId, packetId, version);
+    registry[key] = functor;
+}
+
+void CommandHandlerRegistry::RegisterFunctor(CommandHandlerFunctor* functor)
+{
+    ARM_PIPE_ASSERT_MSG(functor, "Provided functor should not be a nullptr");
+
+    RegisterFunctor(functor, functor->GetFamilyId(), functor->GetPacketId(), functor->GetVersion());
+}
+
+CommandHandlerFunctor* CommandHandlerRegistry::GetFunctor(uint32_t familyId,uint32_t packetId, uint32_t version) const
+{
+    CommandHandlerKey key(familyId, packetId, version);
+
+    // Check that the requested key exists
+    if (registry.find(key) == registry.end())
+    {
+        std::stringstream ss;
+        ss << "Functor with requested PacketId=" << packetId << " and Version=" << version << " does not exist";
+        throw ProfilingException(ss.str());
+    }
+
+    CommandHandlerFunctor* commandHandlerFunctor = registry.at(key);
+    if (commandHandlerFunctor == nullptr)
+    {
+        std::stringstream ss;
+        ss << "Invalid functor registered for PacketId=" << packetId << " and Version=" << version;
+        throw ProfilingException(ss.str());
+    }
+
+    return commandHandlerFunctor;
+}
+
+} // namespace pipe
+
+} // namespace arm
diff --git a/profiling/common/src/CommonProfilingUtils.cpp b/profiling/common/src/CommonProfilingUtils.cpp
new file mode 100644
index 0000000..fe98e0a
--- /dev/null
+++ b/profiling/common/src/CommonProfilingUtils.cpp
@@ -0,0 +1,145 @@
+//
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <common/include/Assert.hpp>
+#include <common/include/CommonProfilingUtils.hpp>
+
+#include <sstream>
+
+namespace arm
+{
+
+namespace pipe
+{
+void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[])
+{
+    ARM_PIPE_ASSERT(buffer);
+    ARM_PIPE_ASSERT(outValue);
+
+    for (unsigned int i = 0; i < valueSize; i++, offset++)
+    {
+        outValue[i] = static_cast<uint8_t>(buffer[offset]);
+    }
+}
+
+uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    uint64_t value = 0;
+    value  = static_cast<uint64_t>(buffer[offset]);
+    value |= static_cast<uint64_t>(buffer[offset + 1]) << 8;
+    value |= static_cast<uint64_t>(buffer[offset + 2]) << 16;
+    value |= static_cast<uint64_t>(buffer[offset + 3]) << 24;
+    value |= static_cast<uint64_t>(buffer[offset + 4]) << 32;
+    value |= static_cast<uint64_t>(buffer[offset + 5]) << 40;
+    value |= static_cast<uint64_t>(buffer[offset + 6]) << 48;
+    value |= static_cast<uint64_t>(buffer[offset + 7]) << 56;
+
+    return value;
+}
+
+uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    uint32_t value = 0;
+    value  = static_cast<uint32_t>(buffer[offset]);
+    value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
+    value |= static_cast<uint32_t>(buffer[offset + 2]) << 16;
+    value |= static_cast<uint32_t>(buffer[offset + 3]) << 24;
+    return value;
+}
+
+uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    uint32_t value = 0;
+    value  = static_cast<uint32_t>(buffer[offset]);
+    value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
+    return static_cast<uint16_t>(value);
+}
+
+uint8_t ReadUint8(const unsigned char* buffer, unsigned int offset)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    return buffer[offset];
+}
+
+void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize)
+{
+    ARM_PIPE_ASSERT(buffer);
+    ARM_PIPE_ASSERT(value);
+
+    for (unsigned int i = 0; i < valueSize; i++, offset++)
+    {
+        buffer[offset] = *(reinterpret_cast<const unsigned char*>(value) + i);
+    }
+}
+
+void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
+    buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
+    buffer[offset + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
+    buffer[offset + 3] = static_cast<unsigned char>((value >> 24) & 0xFF);
+    buffer[offset + 4] = static_cast<unsigned char>((value >> 32) & 0xFF);
+    buffer[offset + 5] = static_cast<unsigned char>((value >> 40) & 0xFF);
+    buffer[offset + 6] = static_cast<unsigned char>((value >> 48) & 0xFF);
+    buffer[offset + 7] = static_cast<unsigned char>((value >> 56) & 0xFF);
+}
+
+void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
+    buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
+    buffer[offset + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
+    buffer[offset + 3] = static_cast<unsigned char>((value >> 24) & 0xFF);
+}
+
+void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
+    buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
+}
+
+void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value)
+{
+    ARM_PIPE_ASSERT(buffer);
+
+    buffer[offset] = static_cast<unsigned char>(value);
+}
+
+std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth)
+{
+    std::stringstream outputStream, centrePadding;
+    int padding = spacingWidth - static_cast<int>(stringToPass.size());
+
+    for (int i = 0; i < padding / 2; ++i)
+    {
+        centrePadding << " ";
+    }
+
+    outputStream << centrePadding.str() << stringToPass << centrePadding.str();
+
+    if (padding > 0 && padding %2 != 0)
+    {
+        outputStream << " ";
+    }
+
+    return outputStream.str();
+}
+
+
+} // namespace pipe
+} // namespace arm
\ No newline at end of file
diff --git a/profiling/common/src/NetworkSockets.cpp b/profiling/common/src/NetworkSockets.cpp
index 7f47c79..2a65655 100644
--- a/profiling/common/src/NetworkSockets.cpp
+++ b/profiling/common/src/NetworkSockets.cpp
@@ -1,27 +1,35 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#include "common/include/NetworkSockets.hpp"
+#include <common/include/NetworkSockets.hpp>
 
 #if defined(__unix__) || defined(__APPLE__)
 #include <unistd.h>
 #include <fcntl.h>
-#include <armnn/Conversion.hpp>
-
+#include <common/include/Conversion.hpp>
 #endif
 
-namespace armnnUtils
+#if defined(__APPLE__) || defined(_MSC_VER) || defined(__MINGW32__)
+#include <common/include/IgnoreUnused.hpp>
+#endif
+
+#if defined(__MINGW32__)
+#include <common/include/Conversion.hpp>
+#include <common/include/NumericCast.hpp>
+#endif
+
+namespace arm
 {
-namespace Sockets
+namespace pipe
 {
 
 bool Initialize()
 {
 #if defined(__unix__) || defined(__APPLE__)
     return true;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
     WSADATA wsaData;
     return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
 #endif
@@ -31,7 +39,7 @@
 {
 #if defined(__unix__) || defined(__APPLE__)
     return close(s);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
     return closesocket(s);
 #endif
 }
@@ -45,6 +53,9 @@
 #elif defined(_MSC_VER)
     u_long mode = 1;
     return ioctlsocket(s, FIONBIO, &mode) == 0;
+#elif defined(__MINGW32__)
+    u_long mode = 1;
+    return ioctlsocket(s, arm::pipe::numeric_cast<long>(FIONBIO), &mode) == 0;
 #endif
 }
 
@@ -53,7 +64,7 @@
 {
 #if defined(__unix__) || defined(__APPLE__)
     return write(s, buf, len);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
     return send(s, static_cast<const char*>(buf), static_cast<int>(len), 0);
 #endif
 }
@@ -63,7 +74,7 @@
 {
 #if defined(__unix__) || defined(__APPLE__)
     return read(s, buf, len);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
     return recv(s, static_cast<char*>(buf), static_cast<int>(len), 0);
 #endif
 }
@@ -71,11 +82,13 @@
 int Ioctl(Socket s, unsigned long int cmd, void* arg)
 {
 #if defined(__unix__) || defined(__APPLE__)
-    ARMNN_NO_CONVERSION_WARN_BEGIN
+    ARM_PIPE_NO_CONVERSION_WARN_BEGIN
     return ioctl(s, static_cast<int>(cmd), arg);
-    ARMNN_NO_CONVERSION_WARN_END
-#elif defined(_MSC_VER)
+    ARM_PIPE_NO_CONVERSION_WARN_END
+#elif defined(_MSC_VER) || defined(__MINGW32__)
+    ARM_PIPE_NO_CONVERSION_WARN_BEGIN
     return ioctlsocket(s, cmd, static_cast<u_long*>(arg));
+    ARM_PIPE_NO_CONVERSION_WARN_END
 #endif
 }
 
@@ -84,22 +97,24 @@
 {
 #if defined(__unix__) || defined(__APPLE__)
     return poll(fds, numFds, timeout);
-#elif defined(_MSC_VER)
-    return WSAPoll(fds, numFds, timeout);
+#elif defined(_MSC_VER) || defined(__MINGW32__)
+    return WSAPoll(fds, arm::pipe::numeric_cast<unsigned long>(numFds), timeout);
 #endif
 }
 
 
-armnnUtils::Sockets::Socket Accept(Socket s, sockaddr* addr, socklen_t* addrlen, int flags)
+arm::pipe::Socket Accept(Socket s, sockaddr* addr, socklen_t* addrlen, int flags)
 {
 #if defined(__unix__)
     return accept4(s, addr, addrlen, flags);
 #elif defined(__APPLE__)
+    IgnoreUnused(flags);
     return accept(s, addr, addrlen);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
+    IgnoreUnused(flags);
     return accept(s, addr, reinterpret_cast<int*>(addrlen));
 #endif
 }
 
-}
-}
+} // pipe
+} // arm
diff --git a/profiling/common/src/PacketVersionResolver.cpp b/profiling/common/src/PacketVersionResolver.cpp
new file mode 100644
index 0000000..25d92b0
--- /dev/null
+++ b/profiling/common/src/PacketVersionResolver.cpp
@@ -0,0 +1,71 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <common/include/PacketVersionResolver.hpp>
+
+namespace arm
+{
+
+namespace pipe
+{
+
+bool PacketKey::operator<(const PacketKey& rhs) const
+{
+    bool result = true;
+    if (m_FamilyId == rhs.m_FamilyId)
+    {
+            result = m_PacketId < rhs.m_PacketId;
+    }
+    else if (m_FamilyId > rhs.m_FamilyId)
+    {
+        result = false;
+    }
+    return result;
+}
+
+bool PacketKey::operator>(const PacketKey& rhs) const
+{
+    return rhs < *this;
+}
+
+bool PacketKey::operator<=(const PacketKey& rhs) const
+{
+    return !(*this > rhs);
+}
+
+bool PacketKey::operator>=(const PacketKey& rhs) const
+{
+    return !(*this < rhs);
+}
+
+bool PacketKey::operator==(const PacketKey& rhs) const
+{
+    return m_FamilyId == rhs.m_FamilyId && m_PacketId == rhs.m_PacketId;
+}
+
+bool PacketKey::operator!=(const PacketKey& rhs) const
+{
+    return !(*this == rhs);
+}
+
+Version PacketVersionResolver::ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const
+{
+    const PacketKey packetKey(familyId, packetId);
+
+    if( packetKey == ActivateTimeLinePacket )
+    {
+        return Version(1, 1, 0);
+    }
+    if( packetKey == DeactivateTimeLinePacket )
+    {
+        return Version(1, 1, 0);
+    }
+
+    return Version(1, 0, 0);
+}
+
+} // namespace pipe
+
+} // namespace arm
diff --git a/profiling/common/src/SwTrace.cpp b/profiling/common/src/SwTrace.cpp
new file mode 100644
index 0000000..5860d8c
--- /dev/null
+++ b/profiling/common/src/SwTrace.cpp
@@ -0,0 +1,128 @@
+//
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <common/include/CommonProfilingUtils.hpp>
+#include <common/include/NumericCast.hpp>
+#include <common/include/ProfilingException.hpp>
+#include <common/include/SwTrace.hpp>
+
+#include <sstream>
+
+namespace arm
+{
+
+namespace pipe
+{
+
+// Calculate the actual length an SwString will be including the terminating null character
+// padding to bring it to the next uint32_t boundary but minus the leading uint32_t encoding
+// the size to allow the offset to be correctly updated when decoding a binary packet.
+uint32_t CalculateSizeOfPaddedSwString(const std::string& str)
+{
+    std::vector<uint32_t> swTraceString;
+    StringToSwTraceString<SwTraceCharPolicy>(str, swTraceString);
+    unsigned int uint32_t_size = sizeof(uint32_t);
+    uint32_t size = (numeric_cast<uint32_t>(swTraceString.size()) - 1) * uint32_t_size;
+    return size;
+}
+
+// Read TimelineMessageDirectoryPacket from given IPacketBuffer and offset
+SwTraceMessage ReadSwTraceMessage(const unsigned char* packetBuffer,
+                                  unsigned int& offset,
+                                  const unsigned int& packetLength)
+{
+    ARM_PIPE_ASSERT(packetBuffer);
+
+    unsigned int uint32_t_size = sizeof(uint32_t);
+
+    SwTraceMessage swTraceMessage;
+
+    // Read the decl_id
+    uint32_t readDeclId = ReadUint32(packetBuffer, offset);
+    swTraceMessage.m_Id = readDeclId;
+
+    // SWTrace "namestring" format
+    // length of the string (first 4 bytes) + string + null terminator
+
+    // Check the decl_name
+    offset += uint32_t_size;
+    uint32_t swTraceDeclNameLength = ReadUint32(packetBuffer, offset);
+
+    if (swTraceDeclNameLength == 0 || swTraceDeclNameLength > packetLength)
+    {
+        throw arm::pipe::ProfilingException("Error swTraceDeclNameLength is an invalid size", LOCATION());
+    }
+
+    offset += uint32_t_size;
+    std::vector<unsigned char> swTraceStringBuffer(swTraceDeclNameLength - 1);
+    std::memcpy(swTraceStringBuffer.data(),
+                packetBuffer + offset, swTraceStringBuffer.size());
+
+    swTraceMessage.m_Name.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // name
+
+    // Check the ui_name
+    offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_Name);
+    uint32_t swTraceUINameLength = ReadUint32(packetBuffer, offset);
+
+    if (swTraceUINameLength == 0 || swTraceUINameLength > packetLength)
+    {
+        throw arm::pipe::ProfilingException("Error swTraceUINameLength is an invalid size", LOCATION());
+    }
+
+    offset += uint32_t_size;
+    swTraceStringBuffer.resize(swTraceUINameLength - 1);
+    std::memcpy(swTraceStringBuffer.data(),
+                packetBuffer  + offset, swTraceStringBuffer.size());
+
+    swTraceMessage.m_UiName.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // ui_name
+
+    // Check arg_types
+    offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_UiName);
+    uint32_t swTraceArgTypesLength = ReadUint32(packetBuffer, offset);
+
+    if (swTraceArgTypesLength == 0 || swTraceArgTypesLength > packetLength)
+    {
+        throw arm::pipe::ProfilingException("Error swTraceArgTypesLength is an invalid size", LOCATION());
+    }
+
+    offset += uint32_t_size;
+    swTraceStringBuffer.resize(swTraceArgTypesLength - 1);
+    std::memcpy(swTraceStringBuffer.data(),
+                packetBuffer  + offset, swTraceStringBuffer.size());
+
+    swTraceMessage.m_ArgTypes.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // arg_types
+
+    std::string swTraceString(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
+
+    // Check arg_names
+    offset += CalculateSizeOfPaddedSwString(swTraceString);
+    uint32_t swTraceArgNamesLength = ReadUint32(packetBuffer, offset);
+
+    if (swTraceArgNamesLength == 0 || swTraceArgNamesLength > packetLength)
+    {
+        throw arm::pipe::ProfilingException("Error swTraceArgNamesLength is an invalid size", LOCATION());
+    }
+
+    offset += uint32_t_size;
+    swTraceStringBuffer.resize(swTraceArgNamesLength - 1);
+    std::memcpy(swTraceStringBuffer.data(),
+                packetBuffer  + offset, swTraceStringBuffer.size());
+
+    swTraceString.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end());
+    std::stringstream stringStream(swTraceString);
+    std::string argName;
+    while (std::getline(stringStream, argName, ','))
+    {
+        swTraceMessage.m_ArgNames.push_back(argName);
+    }
+
+    offset += CalculateSizeOfPaddedSwString(swTraceString);
+
+    return swTraceMessage;
+}
+
+} // namespace pipe
+
+} // namespace arm