diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/utilcode/sbuffer.cpp | |
download | coreclr-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.cpp | 147 |
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; +} + + |