Add StackString class for stack/heap allocation for MAX_LONGPATH.
authorLakshmi Priya Sekar <lasekar@microsoft.com>
Thu, 10 Sep 2015 06:18:32 +0000 (23:18 -0700)
committerLakshmi Priya Sekar <lasekar@microsoft.com>
Wed, 30 Sep 2015 18:31:46 +0000 (11:31 -0700)
Add stackstring.cpp to build.

Commit migrated from https://github.com/dotnet/coreclr/commit/662ec11f4161edbedc5c70e3e43c32c9a07f1cde

src/coreclr/src/pal/src/CMakeLists.txt
src/coreclr/src/pal/src/misc/stackstring.cpp [new file with mode: 0644]

index ce364b3..cabc04f 100644 (file)
@@ -140,6 +140,7 @@ set(SOURCES
   misc/interlock.cpp
   misc/miscpalapi.cpp
   misc/msgbox.cpp
+  misc/stackstring.cpp
   misc/strutil.cpp
   misc/sysinfo.cpp
   misc/time.cpp
diff --git a/src/coreclr/src/pal/src/misc/stackstring.cpp b/src/coreclr/src/pal/src/misc/stackstring.cpp
new file mode 100644 (file)
index 0000000..d35c0d8
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
+
+#include "pal/malloc.hpp"
+#include "pal/dbgmsg.h"
+
+SET_DEFAULT_DEBUG_CHANNEL(MISC);
+
+template <SIZE_T STACKCOUNT>
+class StackString
+{
+private:
+    WCHAR m_innerBuffer[STACKCOUNT + 1];
+    WCHAR * m_buffer;
+    SIZE_T m_count; // actual allocated count
+
+    void NullTerminate()
+    {
+        m_buffer[m_count] = W('\0');
+    }
+
+    void DeleteBuffer()
+    {
+        if (m_innerBuffer != m_buffer)
+            PAL_free(m_buffer);
+
+        m_buffer = NULL;
+        return;
+    }
+
+    void ReallocateBuffer(SIZE_T count)
+    {
+        // count is always > STACKCOUNT here.
+        WCHAR * newBuffer = (WCHAR *)PAL_malloc((count + 1) * sizeof(WCHAR));
+        if (NULL == newBuffer)
+        {
+            ERROR("malloc failed\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+            DeleteBuffer();
+            m_count = 0;
+
+            return;
+        }
+
+        DeleteBuffer();
+        m_buffer = newBuffer;
+        m_count = count;
+
+        return;
+    }
+
+    void Resize(SIZE_T count)
+    {
+        if (NULL == m_buffer)
+        {
+            if (count > STACKCOUNT)
+            {
+                ReallocateBuffer(count);
+            }
+            else
+            {
+                m_buffer = m_innerBuffer;
+                m_count = count;
+            }
+        }
+        else if (m_innerBuffer == m_buffer)
+        {
+            if (count > STACKCOUNT)
+                ReallocateBuffer(count);
+            else
+                m_count = count;
+        }
+        else
+        {
+            ReallocateBuffer(count);
+        }
+
+        return;
+    }
+
+    StackString(const StackString &s)
+    {
+        Set(s);
+    }
+
+    ~StackString()
+    {
+        DeleteBuffer();
+    }
+
+public:
+    StackString()
+        : m_count(0), m_buffer(m_innerBuffer)
+    {
+    }
+
+    BOOL Set(const WCHAR * buffer, SIZE_T count)
+    {
+        Resize(count);
+        if (NULL == m_buffer)
+            return FALSE;
+
+        CopyMemory(m_buffer, buffer, (count + 1) * sizeof(WCHAR));
+        NullTerminate();
+        return TRUE;
+    }
+
+    BOOL Set(const StackString &s)
+    {
+        return Set(s.m_buffer, s.m_count);
+    }
+
+    SIZE_T Getcount() const
+    {
+        return m_count;
+    }
+
+    CONST WCHAR * GetString() const
+    {
+        return (const WCHAR *)m_buffer;
+    }
+
+    WCHAR * OpenStringBuffer(SIZE_T count)
+    {
+        Resize(count);
+        return (WCHAR *)m_buffer;
+    }
+
+    void CloseBuffer(SIZE_T count)
+    {
+        if (m_count > count)
+            m_count = count;
+
+        NullTerminate();
+        return;
+    }
+};