Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Buffer.cs / 3 / 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
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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UndoManager.cs
- ObjRef.cs
- PackageStore.cs
- TreeView.cs
- HttpStreamMessage.cs
- FieldToken.cs
- DesignerHelpers.cs
- OleDbPermission.cs
- ExpanderAutomationPeer.cs
- WinEventWrap.cs
- x509store.cs
- SoapFault.cs
- TextViewBase.cs
- AdCreatedEventArgs.cs
- SqlDataSourceCustomCommandEditor.cs
- DataGridToolTip.cs
- FloaterParaClient.cs
- InputLangChangeEvent.cs
- DataGridViewRowsAddedEventArgs.cs
- AffineTransform3D.cs
- HttpConfigurationContext.cs
- EmissiveMaterial.cs
- AssemblyResourceLoader.cs
- RangeValueProviderWrapper.cs
- ServerIdentity.cs
- SelectionService.cs
- XmlRawWriter.cs
- MapPathBasedVirtualPathProvider.cs
- ContextMenu.cs
- PageParser.cs
- SynchronizedInputPattern.cs
- VirtualPath.cs
- LogManagementAsyncResult.cs
- InstanceNameConverter.cs
- PersianCalendar.cs
- ActiveDocumentEvent.cs
- AbandonedMutexException.cs
- PropertyItemInternal.cs
- HtmlWindow.cs
- BevelBitmapEffect.cs
- ModuleBuilder.cs
- TextSelectionHelper.cs
- ValidatingPropertiesEventArgs.cs
- Matrix3DConverter.cs
- PropertyHelper.cs
- XmlAttributes.cs
- ThemeDictionaryExtension.cs
- ApplicationManager.cs
- TypeInfo.cs
- LambdaReference.cs
- XpsSerializationManager.cs
- EncoderParameter.cs
- GeometryHitTestParameters.cs
- PackagePart.cs
- CollectionEditorDialog.cs
- BaseDataList.cs
- FastEncoderWindow.cs
- GeneratedContractType.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- PrivilegedConfigurationManager.cs
- MessageBox.cs
- SuppressIldasmAttribute.cs
- ChildrenQuery.cs
- FontEmbeddingManager.cs
- PageAsyncTask.cs
- FragmentQueryKB.cs
- SystemIcmpV4Statistics.cs
- Int64.cs
- MarginCollapsingState.cs
- ValueUtilsSmi.cs
- EventLogTraceListener.cs
- FormatStringEditor.cs
- UriTemplateClientFormatter.cs
- LZCodec.cs
- AutoCompleteStringCollection.cs
- ProcessHost.cs
- DispatcherSynchronizationContext.cs
- ForeignKeyConstraint.cs
- LoginViewDesigner.cs
- LabelEditEvent.cs
- WaitHandle.cs
- DesignTimeTemplateParser.cs
- MobileCapabilities.cs
- SQLString.cs
- FileUpload.cs
- RolePrincipal.cs
- _UncName.cs
- ArrayConverter.cs
- ChannelFactoryRefCache.cs
- EditorZoneDesigner.cs
- UInt64Storage.cs
- VisualBrush.cs
- ListControlDesigner.cs
- TextEffectCollection.cs
- SizeAnimationUsingKeyFrames.cs
- WebPartMenuStyle.cs
- CalloutQueueItem.cs
- followingsibling.cs
- DrawingAttributesDefaultValueFactory.cs
- AjaxFrameworkAssemblyAttribute.cs