/mcs/class/corlib/System/Buffer.cs

https://github.com/t-ashula/mono · C# · 160 lines · 94 code · 26 blank · 40 comment · 23 complexity · d28d90e38824840a854908dd0bc7997e MD5 · raw file

  1. //
  2. // System.Buffer.cs
  3. //
  4. // Authors:
  5. // Paolo Molaro (lupus@ximian.com)
  6. // Dan Lewis (dihlewis@yahoo.co.uk)
  7. //
  8. // (C) 2001 Ximian, Inc. http://www.ximian.com
  9. //
  10. //
  11. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System.Runtime.CompilerServices;
  33. using System.Runtime.InteropServices;
  34. using System.Diagnostics.Contracts;
  35. namespace System {
  36. [ComVisible (true)]
  37. public static class Buffer {
  38. public static int ByteLength (Array array)
  39. {
  40. // note: the other methods in this class also use ByteLength to test for
  41. // null and non-primitive arguments as a side-effect.
  42. if (array == null)
  43. throw new ArgumentNullException ("array");
  44. int length = ByteLengthInternal (array);
  45. if (length < 0)
  46. throw new ArgumentException (Locale.GetText ("Object must be an array of primitives."));
  47. return length;
  48. }
  49. public static byte GetByte (Array array, int index)
  50. {
  51. if (index < 0 || index >= ByteLength (array))
  52. throw new ArgumentOutOfRangeException ("index", Locale.GetText(
  53. "Value must be non-negative and less than the size of the collection."));
  54. return GetByteInternal (array, index);
  55. }
  56. public static void SetByte (Array array, int index, byte value)
  57. {
  58. if (index < 0 || index >= ByteLength (array))
  59. throw new ArgumentOutOfRangeException ("index", Locale.GetText(
  60. "Value must be non-negative and less than the size of the collection."));
  61. SetByteInternal (array, index, value);
  62. }
  63. public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count)
  64. {
  65. if (src == null)
  66. throw new ArgumentNullException ("src");
  67. if (dst == null)
  68. throw new ArgumentNullException ("dst");
  69. if (srcOffset < 0)
  70. throw new ArgumentOutOfRangeException ("srcOffset", Locale.GetText(
  71. "Non-negative number required."));
  72. if (dstOffset < 0)
  73. throw new ArgumentOutOfRangeException ("dstOffset", Locale.GetText (
  74. "Non-negative number required."));
  75. if (count < 0)
  76. throw new ArgumentOutOfRangeException ("count", Locale.GetText (
  77. "Non-negative number required."));
  78. // We do the checks in unmanaged code for performance reasons
  79. bool res = BlockCopyInternal (src, srcOffset, dst, dstOffset, count);
  80. if (!res) {
  81. // watch for integer overflow
  82. if ((srcOffset > ByteLength (src) - count) || (dstOffset > ByteLength (dst) - count))
  83. throw new ArgumentException (Locale.GetText (
  84. "Offset and length were out of bounds for the array or count is greater than " +
  85. "the number of elements from index to the end of the source collection."));
  86. }
  87. }
  88. // private
  89. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  90. private extern static int ByteLengthInternal (Array array);
  91. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  92. private extern static byte GetByteInternal (Array array, int index);
  93. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  94. private extern static void SetByteInternal (Array array, int index, int value);
  95. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  96. internal extern static bool BlockCopyInternal (Array src, int src_offset, Array dest, int dest_offset, int count);
  97. internal static bool InternalBlockCopy (Array src, int src_offset, Array dest, int dest_offset, int count)
  98. {
  99. return BlockCopyInternal (src, src_offset, dest, dest_offset, count);
  100. }
  101. internal unsafe static void ZeroMemory (byte* src, long len)
  102. {
  103. while(len-- > 0)
  104. *(src + len) = 0;
  105. }
  106. internal unsafe static void Memcpy (byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
  107. {
  108. Contract.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
  109. Contract.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
  110. // If dest has 0 elements, the fixed statement will throw an
  111. // IndexOutOfRangeException. Special-case 0-byte copies.
  112. if (len==0)
  113. return;
  114. fixed(byte* pSrc = src) {
  115. Memcpy(pDest + destIndex, pSrc + srcIndex, len);
  116. }
  117. }
  118. internal unsafe static void Memcpy(byte[] dest, int destIndex, byte* src, int srcIndex, int len) {
  119. Contract.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
  120. Contract.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
  121. // If dest has 0 elements, the fixed statement will throw an
  122. // IndexOutOfRangeException. Special-case 0-byte copies.
  123. if (len==0)
  124. return;
  125. fixed(byte* pDest = dest) {
  126. Memcpy(pDest + destIndex, src + srcIndex, len);
  127. }
  128. }
  129. internal unsafe static void Memcpy (byte* dest, byte* src, int len)
  130. {
  131. string.memcpy (dest, src, len);
  132. }
  133. }
  134. }