/Zelig/Zelig/RunTime/Framework/mscorlib/System/Buffer.cs

https://github.com/NETMF/llilum · C# · 326 lines · 104 code · 28 blank · 194 comment · 0 complexity · 8667c39a6b32bcba94a13119f8216f80 MD5 · raw file

  1. // ==++==
  2. //
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. //
  5. // ==--==
  6. namespace System
  7. {
  8. //Only contains static methods. Does not require serialization
  9. using System;
  10. using System.Runtime.CompilerServices;
  11. ////using System.Runtime.Versioning;
  12. public static class Buffer
  13. {
  14. // Copies from one primitive array to another primitive array without
  15. // respecting types. This calls memmove internally.
  16. //// [ResourceExposure( ResourceScope.None )]
  17. [MethodImpl( MethodImplOptions.InternalCall )]
  18. public static extern void BlockCopy( Array src ,
  19. int srcOffset ,
  20. Array dst ,
  21. int dstOffset ,
  22. int count );
  23. //// // A very simple and efficient array copy that assumes all of the
  24. //// // parameter validation has already been done. All counts here are
  25. //// // in bytes.
  26. //// [ResourceExposure( ResourceScope.None )]
  27. [MethodImpl( MethodImplOptions.InternalCall )]
  28. internal static extern void InternalBlockCopy( Array src ,
  29. int srcOffset ,
  30. Array dst ,
  31. int dstOffset ,
  32. int count );
  33. //// // This is ported from the optimized CRT assembly in memchr.asm. The JIT generates
  34. //// // pretty good code here and this ends up being within a couple % of the CRT asm.
  35. //// // It is however cross platform as the CRT hasn't ported their fast version to 64-bit
  36. //// // platforms.
  37. //// //
  38. //// internal unsafe static int IndexOfByte( byte* src, byte value, int index, int count )
  39. //// {
  40. //// BCLDebug.Assert( src != null, "src should not be null" );
  41. ////
  42. //// byte* pByte = src + index;
  43. ////
  44. //// // Align up the pointer to sizeof(int).
  45. //// while(((int)pByte & 3) != 0)
  46. //// {
  47. //// if(count == 0)
  48. //// {
  49. //// return -1;
  50. //// }
  51. //// else if(*pByte == value)
  52. //// {
  53. //// return (int)(pByte - src);
  54. //// }
  55. ////
  56. //// count--;
  57. //// pByte++;
  58. //// }
  59. ////
  60. //// // Fill comparer with value byte for comparisons
  61. //// //
  62. //// // comparer = 0/0/value/value
  63. //// uint comparer = (((uint)value << 8) + (uint)value);
  64. //// // comparer = value/value/value/value
  65. //// comparer = (comparer << 16) + comparer;
  66. ////
  67. //// // Run through buffer until we hit a 4-byte section which contains
  68. //// // the byte we're looking for or until we exhaust the buffer.
  69. //// while(count > 3)
  70. //// {
  71. //// // Test the buffer for presence of value. comparer contains the byte
  72. //// // replicated 4 times.
  73. //// uint t1 = *(uint*)pByte;
  74. //// t1 = t1 ^ comparer;
  75. //// uint t2 = 0x7efefeff + t1;
  76. //// t1 = t1 ^ 0xffffffff;
  77. //// t1 = t1 ^ t2;
  78. //// t1 = t1 & 0x81010100;
  79. ////
  80. //// // if t1 is zero then these 4-bytes don't contain a match
  81. //// if(t1 != 0)
  82. //// {
  83. //// // We've found a match for value, figure out which position it's in.
  84. //// int foundIndex = (int)(pByte - src);
  85. //// if(pByte[0] == value)
  86. //// {
  87. //// return foundIndex;
  88. //// }
  89. //// else if(pByte[1] == value)
  90. //// {
  91. //// return foundIndex + 1;
  92. //// }
  93. //// else if(pByte[2] == value)
  94. //// {
  95. //// return foundIndex + 2;
  96. //// }
  97. //// else if(pByte[3] == value)
  98. //// {
  99. //// return foundIndex + 3;
  100. //// }
  101. //// }
  102. ////
  103. //// count -= 4;
  104. //// pByte += 4;
  105. ////
  106. //// }
  107. ////
  108. //// // Catch any bytes that might be left at the tail of the buffer
  109. //// while(count > 0)
  110. //// {
  111. //// if(*pByte == value)
  112. //// {
  113. //// return (int)(pByte - src);
  114. //// }
  115. ////
  116. //// count--;
  117. //// pByte++;
  118. //// }
  119. ////
  120. //// // If we don't have a match return -1;
  121. //// return -1;
  122. //// }
  123. ////
  124. //// // Gets a particular byte out of the array. The array must be an
  125. //// // array of primitives.
  126. //// //
  127. //// // This essentially does the following:
  128. //// // return ((byte*)array) + index.
  129. //// //
  130. //// [ResourceExposure( ResourceScope.None )]
  131. //// [MethodImpl( MethodImplOptions.InternalCall )]
  132. //// public static extern byte GetByte( Array array, int index );
  133. ////
  134. //// // Sets a particular byte in an the array. The array must be an
  135. //// // array of primitives.
  136. //// //
  137. //// // This essentially does the following:
  138. //// // *(((byte*)array) + index) = value.
  139. //// //
  140. //// [ResourceExposure( ResourceScope.None )]
  141. //// [MethodImpl( MethodImplOptions.InternalCall )]
  142. //// public static extern void SetByte( Array array, int index, byte value );
  143. ////
  144. //// // Gets a particular byte out of the array. The array must be an
  145. //// // array of primitives.
  146. //// //
  147. //// // This essentially does the following:
  148. //// // return array.length * sizeof(array.UnderlyingElementType).
  149. //// //
  150. //// [ResourceExposure( ResourceScope.None )]
  151. //// [MethodImpl( MethodImplOptions.InternalCall )]
  152. //// public static extern int ByteLength( Array array );
  153. ////
  154. //// internal unsafe static void ZeroMemory( byte* src, long len )
  155. //// {
  156. //// while(len-- > 0)
  157. //// {
  158. //// *(src + len) = 0;
  159. //// }
  160. //// }
  161. ////
  162. //// internal unsafe static void memcpy( byte* src, int srcIndex, byte[] dest, int destIndex, int len )
  163. //// {
  164. //// BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!" );
  165. //// BCLDebug.Assert( dest.Length - destIndex >= len, "not enough bytes in dest" );
  166. ////
  167. //// // If dest has 0 elements, the fixed statement will throw an
  168. //// // IndexOutOfRangeException. Special-case 0-byte copies.
  169. //// if(len == 0)
  170. //// {
  171. //// return;
  172. //// }
  173. ////
  174. //// fixed(byte* pDest = dest)
  175. //// {
  176. //// memcpyimpl( src + srcIndex, pDest + destIndex, len );
  177. //// }
  178. //// }
  179. ////
  180. //// internal unsafe static void memcpy( byte[] src, int srcIndex, byte* pDest, int destIndex, int len )
  181. //// {
  182. //// BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!" );
  183. //// BCLDebug.Assert( src.Length - srcIndex >= len, "not enough bytes in src" );
  184. ////
  185. //// // If dest has 0 elements, the fixed statement will throw an
  186. //// // IndexOutOfRangeException. Special-case 0-byte copies.
  187. //// if(len == 0)
  188. //// {
  189. //// return;
  190. //// }
  191. ////
  192. //// fixed(byte* pSrc = src)
  193. //// {
  194. //// memcpyimpl( pSrc + srcIndex, pDest + destIndex, len );
  195. //// }
  196. //// }
  197. ////
  198. //// internal unsafe static void memcpy( char* pSrc, int srcIndex, char* pDest, int destIndex, int len )
  199. //// {
  200. //// BCLDebug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!" );
  201. ////
  202. //// // No boundary check for buffer overruns - dangerous
  203. //// if(len == 0)
  204. //// {
  205. //// return;
  206. //// }
  207. ////
  208. //// memcpyimpl( (byte*)(char*)(pSrc + srcIndex), (byte*)(char*)(pDest + destIndex), len * 2 );
  209. //// }
  210. //--//
  211. [MethodImpl( MethodImplOptions.InternalCall )]
  212. internal unsafe extern static void InternalMemoryCopy( byte* src ,
  213. byte* dst ,
  214. int count );
  215. [MethodImpl( MethodImplOptions.InternalCall )]
  216. internal unsafe extern static void InternalMemoryCopy( sbyte* src ,
  217. sbyte* dst ,
  218. int count );
  219. [MethodImpl( MethodImplOptions.InternalCall )]
  220. internal unsafe extern static void InternalMemoryCopy( ushort* src ,
  221. ushort* dst ,
  222. int count );
  223. [MethodImpl( MethodImplOptions.InternalCall )]
  224. internal unsafe extern static void InternalMemoryCopy( short* src ,
  225. short* dst ,
  226. int count );
  227. [MethodImpl( MethodImplOptions.InternalCall )]
  228. internal unsafe extern static void InternalMemoryCopy( char* src ,
  229. char* dst ,
  230. int count );
  231. [MethodImpl( MethodImplOptions.InternalCall )]
  232. internal unsafe extern static void InternalMemoryCopy( uint* src ,
  233. uint* dst ,
  234. int count );
  235. [MethodImpl( MethodImplOptions.InternalCall )]
  236. internal unsafe extern static void InternalMemoryCopy( int* src ,
  237. int* dst ,
  238. int count );
  239. //--//
  240. [MethodImpl( MethodImplOptions.InternalCall )]
  241. internal unsafe extern static void InternalBackwardMemoryCopy( byte* src ,
  242. byte* dst ,
  243. int count );
  244. [MethodImpl( MethodImplOptions.InternalCall )]
  245. internal unsafe extern static void InternalBackwardMemoryCopy( sbyte* src ,
  246. sbyte* dst ,
  247. int count );
  248. [MethodImpl( MethodImplOptions.InternalCall )]
  249. internal unsafe extern static void InternalBackwardMemoryCopy( ushort* src ,
  250. ushort* dst ,
  251. int count );
  252. [MethodImpl( MethodImplOptions.InternalCall )]
  253. internal unsafe extern static void InternalBackwardMemoryCopy( short* src ,
  254. short* dst ,
  255. int count );
  256. [MethodImpl( MethodImplOptions.InternalCall )]
  257. internal unsafe extern static void InternalBackwardMemoryCopy( char* src ,
  258. char* dst ,
  259. int count );
  260. [MethodImpl( MethodImplOptions.InternalCall )]
  261. internal unsafe extern static void InternalBackwardMemoryCopy( uint* src ,
  262. uint* dst ,
  263. int count );
  264. [MethodImpl( MethodImplOptions.InternalCall )]
  265. internal unsafe extern static void InternalBackwardMemoryCopy( int* src ,
  266. int* dst ,
  267. int count );
  268. //--//
  269. [MethodImpl( MethodImplOptions.InternalCall )]
  270. internal unsafe extern static void InternalMemoryMove( byte* src ,
  271. byte* dst ,
  272. int count );
  273. [MethodImpl( MethodImplOptions.InternalCall )]
  274. internal unsafe extern static void InternalMemoryMove( sbyte* src ,
  275. sbyte* dst ,
  276. int count );
  277. [MethodImpl( MethodImplOptions.InternalCall )]
  278. internal unsafe extern static void InternalMemoryMove( ushort* src ,
  279. ushort* dst ,
  280. int count );
  281. [MethodImpl( MethodImplOptions.InternalCall )]
  282. internal unsafe extern static void InternalMemoryMove( short* src ,
  283. short* dst ,
  284. int count );
  285. [MethodImpl( MethodImplOptions.InternalCall )]
  286. internal unsafe extern static void InternalMemoryMove( char* src ,
  287. char* dst ,
  288. int count );
  289. [MethodImpl( MethodImplOptions.InternalCall )]
  290. internal unsafe extern static void InternalMemoryMove( uint* src ,
  291. uint* dst ,
  292. int count );
  293. [MethodImpl( MethodImplOptions.InternalCall )]
  294. internal unsafe extern static void InternalMemoryMove( int* src ,
  295. int* dst ,
  296. int count );
  297. }
  298. }