summaryrefslogtreecommitdiff
path: root/src/utilcode/sbuffer.cpp
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
committerdotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
commitef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch)
treedee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/utilcode/sbuffer.cpp
downloadcoreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/utilcode/sbuffer.cpp')
-rw-r--r--src/utilcode/sbuffer.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/utilcode/sbuffer.cpp b/src/utilcode/sbuffer.cpp
new file mode 100644
index 0000000000..7d2e719135
--- /dev/null
+++ b/src/utilcode/sbuffer.cpp
@@ -0,0 +1,147 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// ---------------------------------------------------------------------------
+
+//
+// Buffer.cpp
+// ---------------------------------------------------------------------------
+
+#include "stdafx.h"
+#include "sbuffer.h"
+#include "ex.h"
+#include "holder.h"
+#include "stdmacros.h"
+
+// Try to minimize the performance impact of contracts on CHK build.
+#if defined(_MSC_VER)
+#pragma inline_depth (20)
+#endif
+
+const DWORD g_garbageFillBuffer[GARBAGE_FILL_BUFFER_ITEMS] =
+{
+ GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
+ GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
+ GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
+ GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
+};
+
+//----------------------------------------------------------------------------
+// ReallocateBuffer
+// Low level buffer reallocate routine
+//----------------------------------------------------------------------------
+void SBuffer::ReallocateBuffer(COUNT_T allocation, Preserve preserve)
+{
+ CONTRACT_VOID
+ {
+ PRECONDITION(CheckPointer(this));
+ PRECONDITION(CheckBufferClosed());
+ PRECONDITION(CheckAllocation(allocation));
+ PRECONDITION(allocation >= m_size);
+ POSTCONDITION(m_allocation == allocation);
+ if (allocation > 0) THROWS; else NOTHROW;
+ GC_NOTRIGGER;
+ SUPPORTS_DAC_HOST_ONLY;
+ }
+ CONTRACT_END;
+
+ BYTE *newBuffer = NULL;
+ if (allocation > 0)
+ {
+ newBuffer = NewBuffer(allocation);
+
+ if (preserve == PRESERVE)
+ {
+ // Copy the relevant contents of the old buffer over
+ DebugMoveBuffer(newBuffer, m_buffer, m_size);
+ }
+ }
+
+ if (IsAllocated())
+ DeleteBuffer(m_buffer, m_allocation);
+
+ m_buffer = newBuffer;
+ m_allocation = allocation;
+
+ if (allocation > 0)
+ SetAllocated();
+ else
+ ClearAllocated();
+
+ ClearImmutable();
+
+ RETURN;
+}
+
+void SBuffer::Replace(const Iterator &i, COUNT_T deleteSize, COUNT_T insertSize)
+{
+ CONTRACT_VOID
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ PRECONDITION(CheckPointer(this));
+ PRECONDITION(CheckIteratorRange(i, deleteSize));
+ SUPPORTS_DAC_HOST_ONLY;
+ }
+ CONTRACT_END;
+
+ COUNT_T startRange = (COUNT_T) (i.m_ptr - m_buffer);
+ // The PRECONDITION(CheckIterationRange(i, deleteSize)) should check this in
+ // contract-checking builds, but this ensures we don't integer overflow if someone
+ // passes in an aggregious deleteSize by capping it to the remaining length in the
+ // buffer.
+ if ((COUNT_T)(m_buffer + m_size - i.m_ptr) < deleteSize)
+ {
+ _ASSERTE(!"Trying to replace more bytes than are remaining in the buffer.");
+ deleteSize = (COUNT_T)(m_buffer + m_size - i.m_ptr);
+ }
+ COUNT_T endRange = startRange + deleteSize;
+ COUNT_T end = m_size;
+
+ SCOUNT_T delta = insertSize - deleteSize;
+
+ if (delta < 0)
+ {
+ // Buffer is shrinking
+
+ DebugDestructBuffer(i.m_ptr, deleteSize);
+
+ DebugMoveBuffer(m_buffer + endRange + delta,
+ m_buffer + endRange,
+ end - endRange);
+
+ Resize(m_size+delta, PRESERVE);
+
+ i.Resync(this, m_buffer + startRange);
+
+ }
+ else if (delta > 0)
+ {
+ // Buffer is growing
+
+ ResizePadded(m_size+delta);
+
+ i.Resync(this, m_buffer + startRange);
+
+ DebugDestructBuffer(i.m_ptr, deleteSize);
+
+ DebugMoveBuffer(m_buffer + endRange + delta,
+ m_buffer + endRange,
+ end - endRange);
+
+ }
+ else
+ {
+ // Buffer stays the same size. We need to DebugDestruct it first to keep
+ // the invariant that the new space is clean.
+
+ DebugDestructBuffer(i.m_ptr, insertSize);
+ }
+
+ DebugConstructBuffer(i.m_ptr, insertSize);
+
+ RETURN;
+}
+
+