Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / BCL / System / Buffer.cs / 1 / Buffer.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System {
//Only contains static methods. Does not require serialization
using System;
using System.Runtime.CompilerServices;
[System.Runtime.InteropServices.ComVisible(true)]
public static class Buffer
{
// Copies from one primitive array to another primitive array without
// respecting types. This calls memmove internally.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void BlockCopy(Array src, int srcOffset,
Array dst, int dstOffset, int count);
// A very simple and efficient array copy that assumes all of the
// parameter validation has already been done. All counts here are
// in bytes.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalBlockCopy(Array src, int srcOffset,
Array dst, int dstOffset, int count);
// This is ported from the optimized CRT assembly in memchr.asm. The JIT generates
// pretty good code here and this ends up being within a couple % of the CRT asm.
// It is however cross platform as the CRT hasn't ported their fast version to 64-bit
// platforms.
//
internal unsafe static int IndexOfByte(byte* src, byte value, int index, int count)
{
BCLDebug.Assert(src != null, "src should not be null");
byte* pByte = src + index;
// Align up the pointer to sizeof(int).
while (((int)pByte & 3) != 0)
{
if (count == 0)
return -1;
else if (*pByte == value)
return (int) (pByte - src);
count--;
pByte++;
}
// Fill comparer with value byte for comparisons
//
// comparer = 0/0/value/value
uint comparer = (((uint)value << 8) + (uint)value);
// comparer = value/value/value/value
comparer = (comparer << 16) + comparer;
// Run through buffer until we hit a 4-byte section which contains
// the byte we're looking for or until we exhaust the buffer.
while (count > 3)
{
// Test the buffer for presence of value. comparer contains the byte
// replicated 4 times.
uint t1 = *(uint*)pByte;
t1 = t1 ^ comparer;
uint t2 = 0x7efefeff + t1;
t1 = t1 ^ 0xffffffff;
t1 = t1 ^ t2;
t1 = t1 & 0x81010100;
// if t1 is zero then these 4-bytes don't contain a match
if (t1 != 0)
{
// We've found a match for value, figure out which position it's in.
int foundIndex = (int) (pByte - src);
if (pByte[0] == value)
return foundIndex;
else if (pByte[1] == value)
return foundIndex + 1;
else if (pByte[2] == value)
return foundIndex + 2;
else if (pByte[3] == value)
return foundIndex + 3;
}
count -= 4;
pByte += 4;
}
// Catch any bytes that might be left at the tail of the buffer
while (count > 0)
{
if (*pByte == value)
return (int) (pByte - src);
count--;
pByte++;
}
// If we don't have a match return -1;
return -1;
}
// Gets a particular byte out of the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// return ((byte*)array) + index.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern byte GetByte(Array array, int index);
// Sets a particular byte in an the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// *(((byte*)array) + index) = value.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void SetByte(Array array, int index, byte value);
// Gets a particular byte out of the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// return array.length * sizeof(array.UnderlyingElementType).
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int ByteLength(Array array);
internal unsafe static void ZeroMemory(byte* src, long len)
{
while(len-- > 0)
*(src + len) = 0;
}
internal unsafe static void memcpy(byte* src, int srcIndex, byte[] dest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
BCLDebug.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
if (len==0)
return;
fixed(byte* pDest = dest) {
memcpyimpl(src+srcIndex, pDest+destIndex, len);
}
}
internal unsafe static void memcpy(byte[] src, int srcIndex, byte* pDest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
BCLDebug.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
if (len==0)
return;
fixed(byte* pSrc = src) {
memcpyimpl(pSrc+srcIndex, pDest+destIndex, len);
}
}
internal unsafe static void memcpy(char* pSrc, int srcIndex, char* pDest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
// No boundary check for buffer overruns - dangerous
if (len==0)
return;
memcpyimpl((byte*)(char*)(pSrc+srcIndex), (byte*)(char*)(pDest+destIndex), len*2);
}
// Note - using a long instead of an int for the length parameter
// slows this method down by ~18%.
internal unsafe static void memcpyimpl(byte* src, byte* dest, int len) {
BCLDebug.Assert(len >= 0, "Negative length in memcopy!");
#if FEATURE_PAL
// Portable naive implementation
while (len-- > 0)
*dest++ = *src++;
#else
// It turns out that on AMD64 it is faster to not be careful of alignment issues.
// On IA64 it is necessary to be careful... Oh well. When we do the IA64 push we
// can work on this implementation.
#if IA64
long dstAlign = 8 - (((long)dest) & 7); // number of bytes to copy before dest is 8-byte aligned
while ((dstAlign > 0) && (len > 0))
{
*dest++ = *src++;
len--;
dstAlign--;
}
long srcAlign = 8 - (((long)src) & 7);
if (len > 0)
{
if (srcAlign != 8)
{
if (4 == srcAlign)
{
while (len >= 4)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
len -= 4;
}
srcAlign = 2; // fall through to 2-byte copies
}
if ((2 == srcAlign) || (6 == srcAlign))
{
while (len >= 2)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
len -= 2;
}
}
while (len-- > 0)
{
*dest++ = *src++;
}
}
else
{
if (len >= 16)
{
do
{
((long*)dest)[0] = ((long*)src)[0];
((long*)dest)[1] = ((long*)src)[1];
dest += 16;
src += 16;
} while ((len -= 16) >= 16);
}
if (len > 0) // protection against negative len and optimization for len==16*N
{
if ((len & 8) != 0)
{
((long*)dest)[0] = ((long*)src)[0];
dest += 8;
src += 8;
}
if ((len & 4) != 0)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
}
if ((len & 2) != 0)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
}
if ((len & 1) != 0)
{
*dest++ = *src++;
}
}
}
}
#else
// AMD64 implementation uses longs instead of ints where possible
//
// This is a faster memcpy implementation, from
// COMString.cpp. For our strings, this beat the processor's
// repeat & move single byte instruction, which memcpy expands into.
// (You read that correctly.)
// This is 3x faster than a simple while loop copying byte by byte,
// for large copies.
if (len >= 16)
{
do
{
#if AMD64
((long*)dest)[0] = ((long*)src)[0];
((long*)dest)[1] = ((long*)src)[1];
#else
((int*)dest)[0] = ((int*)src)[0];
((int*)dest)[1] = ((int*)src)[1];
((int*)dest)[2] = ((int*)src)[2];
((int*)dest)[3] = ((int*)src)[3];
#endif
dest += 16;
src += 16;
} while ((len -= 16) >= 16);
}
if(len > 0) // protection against negative len and optimization for len==16*N
{
if ((len & 8) != 0)
{
#if AMD64
((long*)dest)[0] = ((long*)src)[0];
#else
((int*)dest)[0] = ((int*)src)[0];
((int*)dest)[1] = ((int*)src)[1];
#endif
dest += 8;
src += 8;
}
if ((len & 4) != 0)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
}
if ((len & 2) != 0)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
}
if ((len & 1) != 0)
*dest++ = *src++;
}
#endif // IA64
#endif // FEATURE_PAL
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System {
//Only contains static methods. Does not require serialization
using System;
using System.Runtime.CompilerServices;
[System.Runtime.InteropServices.ComVisible(true)]
public static class Buffer
{
// Copies from one primitive array to another primitive array without
// respecting types. This calls memmove internally.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void BlockCopy(Array src, int srcOffset,
Array dst, int dstOffset, int count);
// A very simple and efficient array copy that assumes all of the
// parameter validation has already been done. All counts here are
// in bytes.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalBlockCopy(Array src, int srcOffset,
Array dst, int dstOffset, int count);
// This is ported from the optimized CRT assembly in memchr.asm. The JIT generates
// pretty good code here and this ends up being within a couple % of the CRT asm.
// It is however cross platform as the CRT hasn't ported their fast version to 64-bit
// platforms.
//
internal unsafe static int IndexOfByte(byte* src, byte value, int index, int count)
{
BCLDebug.Assert(src != null, "src should not be null");
byte* pByte = src + index;
// Align up the pointer to sizeof(int).
while (((int)pByte & 3) != 0)
{
if (count == 0)
return -1;
else if (*pByte == value)
return (int) (pByte - src);
count--;
pByte++;
}
// Fill comparer with value byte for comparisons
//
// comparer = 0/0/value/value
uint comparer = (((uint)value << 8) + (uint)value);
// comparer = value/value/value/value
comparer = (comparer << 16) + comparer;
// Run through buffer until we hit a 4-byte section which contains
// the byte we're looking for or until we exhaust the buffer.
while (count > 3)
{
// Test the buffer for presence of value. comparer contains the byte
// replicated 4 times.
uint t1 = *(uint*)pByte;
t1 = t1 ^ comparer;
uint t2 = 0x7efefeff + t1;
t1 = t1 ^ 0xffffffff;
t1 = t1 ^ t2;
t1 = t1 & 0x81010100;
// if t1 is zero then these 4-bytes don't contain a match
if (t1 != 0)
{
// We've found a match for value, figure out which position it's in.
int foundIndex = (int) (pByte - src);
if (pByte[0] == value)
return foundIndex;
else if (pByte[1] == value)
return foundIndex + 1;
else if (pByte[2] == value)
return foundIndex + 2;
else if (pByte[3] == value)
return foundIndex + 3;
}
count -= 4;
pByte += 4;
}
// Catch any bytes that might be left at the tail of the buffer
while (count > 0)
{
if (*pByte == value)
return (int) (pByte - src);
count--;
pByte++;
}
// If we don't have a match return -1;
return -1;
}
// Gets a particular byte out of the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// return ((byte*)array) + index.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern byte GetByte(Array array, int index);
// Sets a particular byte in an the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// *(((byte*)array) + index) = value.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void SetByte(Array array, int index, byte value);
// Gets a particular byte out of the array. The array must be an
// array of primitives.
//
// This essentially does the following:
// return array.length * sizeof(array.UnderlyingElementType).
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int ByteLength(Array array);
internal unsafe static void ZeroMemory(byte* src, long len)
{
while(len-- > 0)
*(src + len) = 0;
}
internal unsafe static void memcpy(byte* src, int srcIndex, byte[] dest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
BCLDebug.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
if (len==0)
return;
fixed(byte* pDest = dest) {
memcpyimpl(src+srcIndex, pDest+destIndex, len);
}
}
internal unsafe static void memcpy(byte[] src, int srcIndex, byte* pDest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
BCLDebug.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
if (len==0)
return;
fixed(byte* pSrc = src) {
memcpyimpl(pSrc+srcIndex, pDest+destIndex, len);
}
}
internal unsafe static void memcpy(char* pSrc, int srcIndex, char* pDest, int destIndex, int len) {
BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
// No boundary check for buffer overruns - dangerous
if (len==0)
return;
memcpyimpl((byte*)(char*)(pSrc+srcIndex), (byte*)(char*)(pDest+destIndex), len*2);
}
// Note - using a long instead of an int for the length parameter
// slows this method down by ~18%.
internal unsafe static void memcpyimpl(byte* src, byte* dest, int len) {
BCLDebug.Assert(len >= 0, "Negative length in memcopy!");
#if FEATURE_PAL
// Portable naive implementation
while (len-- > 0)
*dest++ = *src++;
#else
// It turns out that on AMD64 it is faster to not be careful of alignment issues.
// On IA64 it is necessary to be careful... Oh well. When we do the IA64 push we
// can work on this implementation.
#if IA64
long dstAlign = 8 - (((long)dest) & 7); // number of bytes to copy before dest is 8-byte aligned
while ((dstAlign > 0) && (len > 0))
{
*dest++ = *src++;
len--;
dstAlign--;
}
long srcAlign = 8 - (((long)src) & 7);
if (len > 0)
{
if (srcAlign != 8)
{
if (4 == srcAlign)
{
while (len >= 4)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
len -= 4;
}
srcAlign = 2; // fall through to 2-byte copies
}
if ((2 == srcAlign) || (6 == srcAlign))
{
while (len >= 2)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
len -= 2;
}
}
while (len-- > 0)
{
*dest++ = *src++;
}
}
else
{
if (len >= 16)
{
do
{
((long*)dest)[0] = ((long*)src)[0];
((long*)dest)[1] = ((long*)src)[1];
dest += 16;
src += 16;
} while ((len -= 16) >= 16);
}
if (len > 0) // protection against negative len and optimization for len==16*N
{
if ((len & 8) != 0)
{
((long*)dest)[0] = ((long*)src)[0];
dest += 8;
src += 8;
}
if ((len & 4) != 0)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
}
if ((len & 2) != 0)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
}
if ((len & 1) != 0)
{
*dest++ = *src++;
}
}
}
}
#else
// AMD64 implementation uses longs instead of ints where possible
//
// This is a faster memcpy implementation, from
// COMString.cpp. For our strings, this beat the processor's
// repeat & move single byte instruction, which memcpy expands into.
// (You read that correctly.)
// This is 3x faster than a simple while loop copying byte by byte,
// for large copies.
if (len >= 16)
{
do
{
#if AMD64
((long*)dest)[0] = ((long*)src)[0];
((long*)dest)[1] = ((long*)src)[1];
#else
((int*)dest)[0] = ((int*)src)[0];
((int*)dest)[1] = ((int*)src)[1];
((int*)dest)[2] = ((int*)src)[2];
((int*)dest)[3] = ((int*)src)[3];
#endif
dest += 16;
src += 16;
} while ((len -= 16) >= 16);
}
if(len > 0) // protection against negative len and optimization for len==16*N
{
if ((len & 8) != 0)
{
#if AMD64
((long*)dest)[0] = ((long*)src)[0];
#else
((int*)dest)[0] = ((int*)src)[0];
((int*)dest)[1] = ((int*)src)[1];
#endif
dest += 8;
src += 8;
}
if ((len & 4) != 0)
{
((int*)dest)[0] = ((int*)src)[0];
dest += 4;
src += 4;
}
if ((len & 2) != 0)
{
((short*)dest)[0] = ((short*)src)[0];
dest += 2;
src += 2;
}
if ((len & 1) != 0)
*dest++ = *src++;
}
#endif // IA64
#endif // FEATURE_PAL
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- File.cs
- BufferModesCollection.cs
- Button.cs
- Predicate.cs
- HandlerBase.cs
- MediaPlayer.cs
- _CommandStream.cs
- Timer.cs
- ToolStripPanel.cs
- FrameworkPropertyMetadata.cs
- DrawingContext.cs
- RowToFieldTransformer.cs
- SelectionPatternIdentifiers.cs
- SQLBytes.cs
- WindowsFormsHostAutomationPeer.cs
- _HeaderInfo.cs
- StackOverflowException.cs
- TemplatedMailWebEventProvider.cs
- GridViewHeaderRowPresenter.cs
- HtmlImage.cs
- TCPClient.cs
- ReliableReplySessionChannel.cs
- EDesignUtil.cs
- TransactionChannelFaultConverter.cs
- ProviderSettingsCollection.cs
- IntMinMaxAggregationOperator.cs
- Rotation3DKeyFrameCollection.cs
- FieldNameLookup.cs
- BooleanSwitch.cs
- JournalNavigationScope.cs
- AsyncContentLoadedEventArgs.cs
- EditCommandColumn.cs
- ADConnectionHelper.cs
- VectorConverter.cs
- ECDiffieHellmanPublicKey.cs
- AdapterUtil.cs
- StackBuilderSink.cs
- CharEntityEncoderFallback.cs
- MouseButton.cs
- Fonts.cs
- CustomErrorsSection.cs
- Visual.cs
- MetadataSection.cs
- EventMappingSettings.cs
- FieldToken.cs
- DataServiceQueryException.cs
- ButtonAutomationPeer.cs
- TypefaceCollection.cs
- ImageFormatConverter.cs
- HierarchicalDataBoundControl.cs
- DetailsViewRow.cs
- SqlUnionizer.cs
- SoapRpcServiceAttribute.cs
- CodeSubDirectoriesCollection.cs
- GacUtil.cs
- InfoCardTraceRecord.cs
- DiagnosticTrace.cs
- ChameleonKey.cs
- CacheRequest.cs
- InstancePersistenceCommandException.cs
- RectangleConverter.cs
- querybuilder.cs
- BoundPropertyEntry.cs
- Timer.cs
- EndOfStreamException.cs
- TimeoutException.cs
- BaseAsyncResult.cs
- UserUseLicenseDictionaryLoader.cs
- HttpModulesSection.cs
- Attributes.cs
- AppDomain.cs
- StateDesigner.TransitionInfo.cs
- DataGridView.cs
- StylusPlugInCollection.cs
- SoapHeaderException.cs
- ellipse.cs
- Calendar.cs
- TypeForwardedToAttribute.cs
- Stylus.cs
- XmlTypeMapping.cs
- Knowncolors.cs
- NotifyCollectionChangedEventArgs.cs
- Symbol.cs
- SqlBuffer.cs
- MethodBuilder.cs
- ScriptControl.cs
- _SSPIWrapper.cs
- UriTemplateTrieLocation.cs
- WpfSharedXamlSchemaContext.cs
- Transform.cs
- BitmapEffectInput.cs
- SqlWebEventProvider.cs
- COM2AboutBoxPropertyDescriptor.cs
- XmlWellformedWriterHelpers.cs
- TempEnvironment.cs
- RelatedImageListAttribute.cs
- KnownBoxes.cs
- ZipIOCentralDirectoryBlock.cs
- MimeFormReflector.cs
- ProcessInfo.cs