From 662ec11f4161edbedc5c70e3e43c32c9a07f1cde Mon Sep 17 00:00:00 2001 From: Lakshmi Priya Sekar Date: Wed, 9 Sep 2015 23:18:32 -0700 Subject: [PATCH] Add StackString class for stack/heap allocation for MAX_LONGPATH. Add stackstring.cpp to build. --- src/pal/src/CMakeLists.txt | 1 + src/pal/src/misc/stackstring.cpp | 138 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/pal/src/misc/stackstring.cpp diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt index ce364b3..cabc04f 100644 --- a/src/pal/src/CMakeLists.txt +++ b/src/pal/src/CMakeLists.txt @@ -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/pal/src/misc/stackstring.cpp b/src/pal/src/misc/stackstring.cpp new file mode 100644 index 0000000..d35c0d8 --- /dev/null +++ b/src/pal/src/misc/stackstring.cpp @@ -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 +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; + } +}; -- 2.7.4