3 // Miguel de Icaza (miguel@novell.com)
5 // See the following url for documentation:
6 // http://www.mono-project.com/Mono_DataConvert
8 // Compilation Options:
9 // MONO_DATACONVERTER_PUBLIC:
10 // Makes the class public instead of the default internal.
12 // MONO_DATACONVERTER_STATIC_METHODS:
13 // Exposes the public static methods.
16 // Support for "DoubleWordsAreSwapped" for ARM devices
18 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
20 // Permission is hereby granted, free of charge, to any person obtaining
21 // a copy of this software and associated documentation files (the
22 // "Software"), to deal in the Software without restriction, including
23 // without limitation the rights to use, copy, modify, merge, publish,
24 // distribute, sublicense, and/or sell copies of the Software, and to
25 // permit persons to whom the Software is furnished to do so, subject to
26 // the following conditions:
28 // The above copyright notice and this permission notice shall be
29 // included in all copies or substantial portions of the Software.
31 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 using System.Collections;
42 using System.Collections.Generic;
44 #pragma warning disable 3021
48 #if MONO_DATACONVERTER_PUBLIC
51 unsafe abstract class DataConverter {
53 // Disables the warning: CLS compliance checking will not be performed on
54 // `XXXX' because it is not visible from outside this assembly
55 #pragma warning disable 3019
56 static readonly DataConverter SwapConv = new SwapConverter ();
57 static readonly DataConverter CopyConv = new CopyConverter ();
59 public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian;
61 public abstract double GetDouble (byte [] data, int index);
62 public abstract float GetFloat (byte [] data, int index);
63 public abstract long GetInt64 (byte [] data, int index);
64 public abstract int GetInt32 (byte [] data, int index);
66 public abstract short GetInt16 (byte [] data, int index);
68 [CLSCompliant (false)]
69 public abstract uint GetUInt32 (byte [] data, int index);
70 [CLSCompliant (false)]
71 public abstract ushort GetUInt16 (byte [] data, int index);
72 [CLSCompliant (false)]
73 public abstract ulong GetUInt64 (byte [] data, int index);
75 public abstract void PutBytes (byte [] dest, int destIdx, double value);
76 public abstract void PutBytes (byte [] dest, int destIdx, float value);
77 public abstract void PutBytes (byte [] dest, int destIdx, int value);
78 public abstract void PutBytes (byte [] dest, int destIdx, long value);
79 public abstract void PutBytes (byte [] dest, int destIdx, short value);
81 [CLSCompliant (false)]
82 public abstract void PutBytes (byte [] dest, int destIdx, ushort value);
83 [CLSCompliant (false)]
84 public abstract void PutBytes (byte [] dest, int destIdx, uint value);
85 [CLSCompliant (false)]
86 public abstract void PutBytes (byte [] dest, int destIdx, ulong value);
88 public byte[] GetBytes (double value)
90 byte [] ret = new byte [8];
91 PutBytes (ret, 0, value);
95 public byte[] GetBytes (float value)
97 byte [] ret = new byte [4];
98 PutBytes (ret, 0, value);
102 public byte[] GetBytes (int value)
104 byte [] ret = new byte [4];
105 PutBytes (ret, 0, value);
109 public byte[] GetBytes (long value)
111 byte [] ret = new byte [8];
112 PutBytes (ret, 0, value);
116 public byte[] GetBytes (short value)
118 byte [] ret = new byte [2];
119 PutBytes (ret, 0, value);
123 [CLSCompliant (false)]
124 public byte[] GetBytes (ushort value)
126 byte [] ret = new byte [2];
127 PutBytes (ret, 0, value);
131 [CLSCompliant (false)]
132 public byte[] GetBytes (uint value)
134 byte [] ret = new byte [4];
135 PutBytes (ret, 0, value);
139 [CLSCompliant (false)]
140 public byte[] GetBytes (ulong value)
142 byte [] ret = new byte [8];
143 PutBytes (ret, 0, value);
147 static public DataConverter LittleEndian {
149 return BitConverter.IsLittleEndian ? CopyConv : SwapConv;
153 static public DataConverter BigEndian {
155 return BitConverter.IsLittleEndian ? SwapConv : CopyConv;
159 static public DataConverter Native {
165 static int Align (int current, int align)
167 return ((current + align - 1) / align) * align;
172 public byte [] buffer;
175 public string description;
176 public int i; // position in the description
177 public DataConverter conv;
181 // if align == -1, auto align to the size of the byte array
182 // if align == 0, do not do alignment
183 // Any other values aligns to that particular size
187 public void Add (byte [] group)
189 //Console.WriteLine ("Adding {0} bytes to {1} (next={2}", group.Length,
190 // buffer == null ? "null" : buffer.Length.ToString (), next);
199 next = Align (next, group.Length);
201 next = Align (next, align);
205 if (next + group.Length > buffer.Length){
206 byte [] nb = new byte [System.Math.Max (next, 16) * 2 + group.Length];
207 Array.Copy (buffer, nb, buffer.Length);
208 Array.Copy (group, 0, nb, next, group.Length);
209 next = next + group.Length;
212 Array.Copy (group, 0, buffer, next, group.Length);
213 next += group.Length;
217 public byte [] Get ()
222 if (buffer.Length != next){
223 byte [] b = new byte [next];
224 Array.Copy (buffer, b, next);
234 // ^ Switch to big endian encoding
235 // _ Switch to little endian encoding
236 // % Switch to host (native) encoding
237 // ! aligns the next data type to its natural boundary (for strings this is 4).
249 // c 1-byte signed character
250 // C 1-byte unsigned character
251 // z8 string encoded as UTF8 with 1-byte null terminator
252 // z6 string encoded as UTF16 with 2-byte null terminator
253 // z7 string encoded as UTF7 with 1-byte null terminator
254 // zb string encoded as BigEndianUnicode with 2-byte null terminator
255 // z3 string encoded as UTF32 with 4-byte null terminator
256 // z4 string encoded as UTF32 big endian with 4-byte null terminator
257 // $8 string encoded as UTF8
258 // $6 string encoded as UTF16
259 // $7 string encoded as UTF7
260 // $b string encoded as BigEndianUnicode
261 // $3 string encoded as UTF32
262 // $4 string encoded as UTF-32 big endian encoding
265 // Repeats, these are prefixes:
266 // N a number between 1 and 9, indicates a repeat count (process N items
267 // with the following datatype
268 // [N] For numbers larger than 9, use brackets, for example [20]
269 // * Repeat the next data type until the arguments are exhausted
271 static public byte [] Pack (string description, params object [] args)
274 PackContext b = new PackContext ();
276 b.description = description;
278 for (b.i = 0; b.i < description.Length; ){
281 if (argn < args.Length)
292 if (PackOne (b, oarg)){
307 static public byte [] PackEnumerable (string description, IEnumerable args)
309 PackContext b = new PackContext ();
311 b.description = description;
313 IEnumerator enumerator = args.GetEnumerator ();
314 bool ok = enumerator.MoveNext ();
316 for (b.i = 0; b.i < description.Length; ){
320 oarg = enumerator.Current;
329 if (PackOne (b, oarg)){
330 ok = enumerator.MoveNext ();
345 // Packs one datum `oarg' into the buffer `b', using the string format
346 // in `description' at position `i'
348 // Returns: true if we must pick the next object from the list
350 static bool PackOne (PackContext b, object oarg)
354 switch (b.description [b.i]){
359 b.conv = LittleEndian;
370 b.Add (new byte [] { 0 });
375 b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg)));
379 b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg)));
383 b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg)));
387 b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg)));
391 b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg)));
395 b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg)));
399 b.Add (b.conv.GetBytes (Convert.ToSingle (oarg)));
403 b.Add (b.conv.GetBytes (Convert.ToDouble (oarg)));
407 b.Add (new byte [] { Convert.ToByte (oarg) });
411 b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) });
415 b.Add (new byte [] { Convert.ToByte (oarg) });
419 case '1': case '2': case '3': case '4': case '5':
420 case '6': case '7': case '8': case '9':
421 b.repeat = ((short) b.description [b.i]) - ((short) '0');
425 b.repeat = Int32.MaxValue;
431 for (j = b.i+1; j < b.description.Length; j++){
432 if (b.description [j] == ']')
434 n = ((short) b.description [j]) - ((short) '0');
435 if (n >= 0 && n <= 9){
439 count = count * 10 + n;
443 throw new ArgumentException ("invalid size specification");
449 bool add_null = b.description [b.i] == 'z';
451 if (b.i >= b.description.Length)
452 throw new ArgumentException ("$ description needs a type specified", "description");
453 char d = b.description [b.i];
462 e = Encoding.Unicode;
467 e = Encoding.GetEncoding ("utf-7");
474 e = Encoding.BigEndianUnicode;
479 e = Encoding.GetEncoding ("utf-32");
481 e = Encoding.GetEncoding (12000);
487 e = Encoding.GetEncoding ("utf-32BE");
489 e = Encoding.GetEncoding (12001);
495 throw new ArgumentException ("Invalid format for $ specifier", "description");
499 b.Add (e.GetBytes (Convert.ToString (oarg)));
501 b.Add (new byte [n]);
504 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
505 b.description [b.i]));
510 static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
513 idx = Align (idx, size);
516 if (idx + size > buffer.Length){
523 static public IList Unpack (string description, byte [] buffer, int startIndex)
525 DataConverter conv = CopyConv;
526 var result = new List<object> ();
527 int idx = startIndex;
531 for (int i = 0; i < description.Length && idx < buffer.Length; ){
534 switch (description [i]){
554 if (Prepare (buffer, ref idx, 4, ref align)){
555 result.Add (conv.GetInt32 (buffer, idx));
561 if (Prepare (buffer, ref idx, 4, ref align)){
562 result.Add (conv.GetUInt32 (buffer, idx));
568 if (Prepare (buffer, ref idx, 2, ref align)){
569 result.Add (conv.GetInt16 (buffer, idx));
575 if (Prepare (buffer, ref idx, 2, ref align)){
576 result.Add (conv.GetUInt16 (buffer, idx));
582 if (Prepare (buffer, ref idx, 8, ref align)){
583 result.Add (conv.GetInt64 (buffer, idx));
589 if (Prepare (buffer, ref idx, 8, ref align)){
590 result.Add (conv.GetUInt64 (buffer, idx));
596 if (Prepare (buffer, ref idx, 4, ref align)){
597 result.Add (conv.GetFloat (buffer, idx));
603 if (Prepare (buffer, ref idx, 8, ref align)){
604 result.Add (conv.GetDouble (buffer, idx));
610 if (Prepare (buffer, ref idx, 1, ref align)){
611 result.Add (buffer [idx]);
617 if (Prepare (buffer, ref idx, 1, ref align)){
620 if (description [i] == 'c')
621 c = ((char) ((sbyte)buffer [idx]));
623 c = ((char) ((byte)buffer [idx]));
631 case '1': case '2': case '3': case '4': case '5':
632 case '6': case '7': case '8': case '9':
633 repeat = ((short) description [i]) - ((short) '0');
638 repeat = Int32.MaxValue;
644 for (j = i+1; j < description.Length; j++){
645 if (description [j] == ']')
647 n = ((short) description [j]) - ((short) '0');
648 if (n >= 0 && n <= 9){
652 count = count * 10 + n;
656 throw new ArgumentException ("invalid size specification");
663 // bool with_null = description [i] == 'z';
665 if (i >= description.Length)
666 throw new ArgumentException ("$ description needs a type specified", "description");
667 char d = description [i];
670 idx = Align (idx, 4);
673 if (idx >= buffer.Length)
682 e = Encoding.Unicode;
690 e = Encoding.BigEndianUnicode;
694 e = Encoding.GetEncoding (12000);
698 e = Encoding.GetEncoding (12001);
703 throw new ArgumentException ("Invalid format for $ specifier", "description");
708 for (; k < buffer.Length && buffer [k] != 0; k++)
710 result.Add (e.GetChars (buffer, idx, k-idx));
711 if (k == buffer.Length)
718 for (; k < buffer.Length; k++){
719 if (k+1 == buffer.Length){
723 if (buffer [k] == 0 && buffer [k+1] == 0)
726 result.Add (e.GetChars (buffer, idx, k-idx));
727 if (k == buffer.Length)
734 for (; k < buffer.Length; k++){
735 if (k+3 >= buffer.Length){
739 if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
742 result.Add (e.GetChars (buffer, idx, k-idx));
743 if (k == buffer.Length)
751 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
764 internal void Check (byte [] dest, int destIdx, int size)
767 throw new ArgumentNullException ("dest");
768 if (destIdx < 0 || destIdx > dest.Length - size)
769 throw new ArgumentException ("destIdx");
772 class CopyConverter : DataConverter {
773 public override double GetDouble (byte [] data, int index)
776 throw new ArgumentNullException ("data");
777 if (data.Length - index < 8)
778 throw new ArgumentException ("index");
780 throw new ArgumentException ("index");
782 byte *b = (byte *)&ret;
784 for (int i = 0; i < 8; i++)
785 b [i] = data [index+i];
790 public override ulong GetUInt64 (byte [] data, int index)
793 throw new ArgumentNullException ("data");
794 if (data.Length - index < 8)
795 throw new ArgumentException ("index");
797 throw new ArgumentException ("index");
800 byte *b = (byte *)&ret;
802 for (int i = 0; i < 8; i++)
803 b [i] = data [index+i];
808 public override long GetInt64 (byte [] data, int index)
811 throw new ArgumentNullException ("data");
812 if (data.Length - index < 8)
813 throw new ArgumentException ("index");
815 throw new ArgumentException ("index");
818 byte *b = (byte *)&ret;
820 for (int i = 0; i < 8; i++)
821 b [i] = data [index+i];
826 public override float GetFloat (byte [] data, int index)
829 throw new ArgumentNullException ("data");
830 if (data.Length - index < 4)
831 throw new ArgumentException ("index");
833 throw new ArgumentException ("index");
836 byte *b = (byte *)&ret;
838 for (int i = 0; i < 4; i++)
839 b [i] = data [index+i];
844 public override int GetInt32 (byte [] data, int index)
847 throw new ArgumentNullException ("data");
848 if (data.Length - index < 4)
849 throw new ArgumentException ("index");
851 throw new ArgumentException ("index");
854 byte *b = (byte *)&ret;
856 for (int i = 0; i < 4; i++)
857 b [i] = data [index+i];
862 public override uint GetUInt32 (byte [] data, int index)
865 throw new ArgumentNullException ("data");
866 if (data.Length - index < 4)
867 throw new ArgumentException ("index");
869 throw new ArgumentException ("index");
872 byte *b = (byte *)&ret;
874 for (int i = 0; i < 4; i++)
875 b [i] = data [index+i];
880 public override short GetInt16 (byte [] data, int index)
883 throw new ArgumentNullException ("data");
884 if (data.Length - index < 2)
885 throw new ArgumentException ("index");
887 throw new ArgumentException ("index");
890 byte *b = (byte *)&ret;
892 for (int i = 0; i < 2; i++)
893 b [i] = data [index+i];
898 public override ushort GetUInt16 (byte [] data, int index)
901 throw new ArgumentNullException ("data");
902 if (data.Length - index < 2)
903 throw new ArgumentException ("index");
905 throw new ArgumentException ("index");
908 byte *b = (byte *)&ret;
910 for (int i = 0; i < 2; i++)
911 b [i] = data [index+i];
916 public override void PutBytes (byte [] dest, int destIdx, double value)
918 Check (dest, destIdx, 8);
919 fixed (byte *target = &dest [destIdx]){
920 long *source = (long *) &value;
922 *((long *)target) = *source;
926 public override void PutBytes (byte [] dest, int destIdx, float value)
928 Check (dest, destIdx, 4);
929 fixed (byte *target = &dest [destIdx]){
930 uint *source = (uint *) &value;
932 *((uint *)target) = *source;
936 public override void PutBytes (byte [] dest, int destIdx, int value)
938 Check (dest, destIdx, 4);
939 fixed (byte *target = &dest [destIdx]){
940 uint *source = (uint *) &value;
942 *((uint *)target) = *source;
946 public override void PutBytes (byte [] dest, int destIdx, uint value)
948 Check (dest, destIdx, 4);
949 fixed (byte *target = &dest [destIdx]){
950 uint *source = (uint *) &value;
952 *((uint *)target) = *source;
956 public override void PutBytes (byte [] dest, int destIdx, long value)
958 Check (dest, destIdx, 8);
959 fixed (byte *target = &dest [destIdx]){
960 long *source = (long *) &value;
962 *((long*)target) = *source;
966 public override void PutBytes (byte [] dest, int destIdx, ulong value)
968 Check (dest, destIdx, 8);
969 fixed (byte *target = &dest [destIdx]){
970 ulong *source = (ulong *) &value;
972 *((ulong *) target) = *source;
976 public override void PutBytes (byte [] dest, int destIdx, short value)
978 Check (dest, destIdx, 2);
979 fixed (byte *target = &dest [destIdx]){
980 ushort *source = (ushort *) &value;
982 *((ushort *)target) = *source;
986 public override void PutBytes (byte [] dest, int destIdx, ushort value)
988 Check (dest, destIdx, 2);
989 fixed (byte *target = &dest [destIdx]){
990 ushort *source = (ushort *) &value;
992 *((ushort *)target) = *source;
997 class SwapConverter : DataConverter {
998 public override double GetDouble (byte [] data, int index)
1001 throw new ArgumentNullException ("data");
1002 if (data.Length - index < 8)
1003 throw new ArgumentException ("index");
1005 throw new ArgumentException ("index");
1008 byte *b = (byte *)&ret;
1010 for (int i = 0; i < 8; i++)
1011 b [7-i] = data [index+i];
1016 public override ulong GetUInt64 (byte [] data, int index)
1019 throw new ArgumentNullException ("data");
1020 if (data.Length - index < 8)
1021 throw new ArgumentException ("index");
1023 throw new ArgumentException ("index");
1026 byte *b = (byte *)&ret;
1028 for (int i = 0; i < 8; i++)
1029 b [7-i] = data [index+i];
1034 public override long GetInt64 (byte [] data, int index)
1037 throw new ArgumentNullException ("data");
1038 if (data.Length - index < 8)
1039 throw new ArgumentException ("index");
1041 throw new ArgumentException ("index");
1044 byte *b = (byte *)&ret;
1046 for (int i = 0; i < 8; i++)
1047 b [7-i] = data [index+i];
1052 public override float GetFloat (byte [] data, int index)
1055 throw new ArgumentNullException ("data");
1056 if (data.Length - index < 4)
1057 throw new ArgumentException ("index");
1059 throw new ArgumentException ("index");
1062 byte *b = (byte *)&ret;
1064 for (int i = 0; i < 4; i++)
1065 b [3-i] = data [index+i];
1070 public override int GetInt32 (byte [] data, int index)
1073 throw new ArgumentNullException ("data");
1074 if (data.Length - index < 4)
1075 throw new ArgumentException ("index");
1077 throw new ArgumentException ("index");
1080 byte *b = (byte *)&ret;
1082 for (int i = 0; i < 4; i++)
1083 b [3-i] = data [index+i];
1088 public override uint GetUInt32 (byte [] data, int index)
1091 throw new ArgumentNullException ("data");
1092 if (data.Length - index < 4)
1093 throw new ArgumentException ("index");
1095 throw new ArgumentException ("index");
1098 byte *b = (byte *)&ret;
1100 for (int i = 0; i < 4; i++)
1101 b [3-i] = data [index+i];
1106 public override short GetInt16 (byte [] data, int index)
1109 throw new ArgumentNullException ("data");
1110 if (data.Length - index < 2)
1111 throw new ArgumentException ("index");
1113 throw new ArgumentException ("index");
1116 byte *b = (byte *)&ret;
1118 for (int i = 0; i < 2; i++)
1119 b [1-i] = data [index+i];
1124 public override ushort GetUInt16 (byte [] data, int index)
1127 throw new ArgumentNullException ("data");
1128 if (data.Length - index < 2)
1129 throw new ArgumentException ("index");
1131 throw new ArgumentException ("index");
1134 byte *b = (byte *)&ret;
1136 for (int i = 0; i < 2; i++)
1137 b [1-i] = data [index+i];
1142 public override void PutBytes (byte [] dest, int destIdx, double value)
1144 Check (dest, destIdx, 8);
1146 fixed (byte *target = &dest [destIdx]){
1147 byte *source = (byte *) &value;
1149 for (int i = 0; i < 8; i++)
1150 target [i] = source [7-i];
1154 public override void PutBytes (byte [] dest, int destIdx, float value)
1156 Check (dest, destIdx, 4);
1158 fixed (byte *target = &dest [destIdx]){
1159 byte *source = (byte *) &value;
1161 for (int i = 0; i < 4; i++)
1162 target [i] = source [3-i];
1166 public override void PutBytes (byte [] dest, int destIdx, int value)
1168 Check (dest, destIdx, 4);
1170 fixed (byte *target = &dest [destIdx]){
1171 byte *source = (byte *) &value;
1173 for (int i = 0; i < 4; i++)
1174 target [i] = source [3-i];
1178 public override void PutBytes (byte [] dest, int destIdx, uint value)
1180 Check (dest, destIdx, 4);
1182 fixed (byte *target = &dest [destIdx]){
1183 byte *source = (byte *) &value;
1185 for (int i = 0; i < 4; i++)
1186 target [i] = source [3-i];
1190 public override void PutBytes (byte [] dest, int destIdx, long value)
1192 Check (dest, destIdx, 8);
1194 fixed (byte *target = &dest [destIdx]){
1195 byte *source = (byte *) &value;
1197 for (int i = 0; i < 8; i++)
1198 target [i] = source [7-i];
1202 public override void PutBytes (byte [] dest, int destIdx, ulong value)
1204 Check (dest, destIdx, 8);
1206 fixed (byte *target = &dest [destIdx]){
1207 byte *source = (byte *) &value;
1209 for (int i = 0; i < 8; i++)
1210 target [i] = source [7-i];
1214 public override void PutBytes (byte [] dest, int destIdx, short value)
1216 Check (dest, destIdx, 2);
1218 fixed (byte *target = &dest [destIdx]){
1219 byte *source = (byte *) &value;
1221 for (int i = 0; i < 2; i++)
1222 target [i] = source [1-i];
1226 public override void PutBytes (byte [] dest, int destIdx, ushort value)
1228 Check (dest, destIdx, 2);
1230 fixed (byte *target = &dest [destIdx]){
1231 byte *source = (byte *) &value;
1233 for (int i = 0; i < 2; i++)
1234 target [i] = source [1-i];
1239 #if MONO_DATACONVERTER_STATIC_METHODS
1240 static unsafe void PutBytesLE (byte *dest, byte *src, int count)
1244 if (BitConverter.IsLittleEndian){
1245 for (; i < count; i++)
1249 for (; i < count; i++)
1254 static unsafe void PutBytesBE (byte *dest, byte *src, int count)
1258 if (BitConverter.IsLittleEndian){
1260 for (; i < count; i++)
1263 for (; i < count; i++)
1268 static unsafe void PutBytesNative (byte *dest, byte *src, int count)
1272 for (; i < count; i++)
1273 dest [i-count] = *src++;
1276 static public unsafe double DoubleFromLE (byte[] data, int index)
1279 throw new ArgumentNullException ("data");
1280 if (data.Length - index < 8)
1281 throw new ArgumentException ("index");
1283 throw new ArgumentException ("index");
1286 fixed (byte *src = &data[index]){
1287 PutBytesLE ((byte *) &ret, src, 8);
1292 static public unsafe float FloatFromLE (byte [] data, int index)
1295 throw new ArgumentNullException ("data");
1296 if (data.Length - index < 4)
1297 throw new ArgumentException ("index");
1299 throw new ArgumentException ("index");
1302 fixed (byte *src = &data[index]){
1303 PutBytesLE ((byte *) &ret, src, 4);
1308 static public unsafe long Int64FromLE (byte [] data, int index)
1311 throw new ArgumentNullException ("data");
1312 if (data.Length - index < 8)
1313 throw new ArgumentException ("index");
1315 throw new ArgumentException ("index");
1318 fixed (byte *src = &data[index]){
1319 PutBytesLE ((byte *) &ret, src, 8);
1324 static public unsafe ulong UInt64FromLE (byte [] data, int index)
1327 throw new ArgumentNullException ("data");
1328 if (data.Length - index < 8)
1329 throw new ArgumentException ("index");
1331 throw new ArgumentException ("index");
1334 fixed (byte *src = &data[index]){
1335 PutBytesLE ((byte *) &ret, src, 8);
1340 static public unsafe int Int32FromLE (byte [] data, int index)
1343 throw new ArgumentNullException ("data");
1344 if (data.Length - index < 4)
1345 throw new ArgumentException ("index");
1347 throw new ArgumentException ("index");
1350 fixed (byte *src = &data[index]){
1351 PutBytesLE ((byte *) &ret, src, 4);
1356 static public unsafe uint UInt32FromLE (byte [] data, int index)
1359 throw new ArgumentNullException ("data");
1360 if (data.Length - index < 4)
1361 throw new ArgumentException ("index");
1363 throw new ArgumentException ("index");
1366 fixed (byte *src = &data[index]){
1367 PutBytesLE ((byte *) &ret, src, 4);
1372 static public unsafe short Int16FromLE (byte [] data, int index)
1375 throw new ArgumentNullException ("data");
1376 if (data.Length - index < 2)
1377 throw new ArgumentException ("index");
1379 throw new ArgumentException ("index");
1382 fixed (byte *src = &data[index]){
1383 PutBytesLE ((byte *) &ret, src, 2);
1388 static public unsafe ushort UInt16FromLE (byte [] data, int index)
1391 throw new ArgumentNullException ("data");
1392 if (data.Length - index < 2)
1393 throw new ArgumentException ("index");
1395 throw new ArgumentException ("index");
1398 fixed (byte *src = &data[index]){
1399 PutBytesLE ((byte *) &ret, src, 2);
1404 static public unsafe double DoubleFromBE (byte[] data, int index)
1407 throw new ArgumentNullException ("data");
1408 if (data.Length - index < 8)
1409 throw new ArgumentException ("index");
1411 throw new ArgumentException ("index");
1414 fixed (byte *src = &data[index]){
1415 PutBytesBE ((byte *) &ret, src, 8);
1420 static public unsafe float FloatFromBE (byte [] data, int index)
1423 throw new ArgumentNullException ("data");
1424 if (data.Length - index < 4)
1425 throw new ArgumentException ("index");
1427 throw new ArgumentException ("index");
1430 fixed (byte *src = &data[index]){
1431 PutBytesBE ((byte *) &ret, src, 4);
1436 static public unsafe long Int64FromBE (byte [] data, int index)
1439 throw new ArgumentNullException ("data");
1440 if (data.Length - index < 8)
1441 throw new ArgumentException ("index");
1443 throw new ArgumentException ("index");
1446 fixed (byte *src = &data[index]){
1447 PutBytesBE ((byte *) &ret, src, 8);
1452 static public unsafe ulong UInt64FromBE (byte [] data, int index)
1455 throw new ArgumentNullException ("data");
1456 if (data.Length - index < 8)
1457 throw new ArgumentException ("index");
1459 throw new ArgumentException ("index");
1462 fixed (byte *src = &data[index]){
1463 PutBytesBE ((byte *) &ret, src, 8);
1468 static public unsafe int Int32FromBE (byte [] data, int index)
1471 throw new ArgumentNullException ("data");
1472 if (data.Length - index < 4)
1473 throw new ArgumentException ("index");
1475 throw new ArgumentException ("index");
1478 fixed (byte *src = &data[index]){
1479 PutBytesBE ((byte *) &ret, src, 4);
1484 static public unsafe uint UInt32FromBE (byte [] data, int index)
1487 throw new ArgumentNullException ("data");
1488 if (data.Length - index < 4)
1489 throw new ArgumentException ("index");
1491 throw new ArgumentException ("index");
1494 fixed (byte *src = &data[index]){
1495 PutBytesBE ((byte *) &ret, src, 4);
1500 static public unsafe short Int16FromBE (byte [] data, int index)
1503 throw new ArgumentNullException ("data");
1504 if (data.Length - index < 2)
1505 throw new ArgumentException ("index");
1507 throw new ArgumentException ("index");
1510 fixed (byte *src = &data[index]){
1511 PutBytesBE ((byte *) &ret, src, 2);
1516 static public unsafe ushort UInt16FromBE (byte [] data, int index)
1519 throw new ArgumentNullException ("data");
1520 if (data.Length - index < 2)
1521 throw new ArgumentException ("index");
1523 throw new ArgumentException ("index");
1526 fixed (byte *src = &data[index]){
1527 PutBytesBE ((byte *) &ret, src, 2);
1532 static public unsafe double DoubleFromNative (byte[] data, int index)
1535 throw new ArgumentNullException ("data");
1536 if (data.Length - index < 8)
1537 throw new ArgumentException ("index");
1539 throw new ArgumentException ("index");
1542 fixed (byte *src = &data[index]){
1543 PutBytesNative ((byte *) &ret, src, 8);
1548 static public unsafe float FloatFromNative (byte [] data, int index)
1551 throw new ArgumentNullException ("data");
1552 if (data.Length - index < 4)
1553 throw new ArgumentException ("index");
1555 throw new ArgumentException ("index");
1558 fixed (byte *src = &data[index]){
1559 PutBytesNative ((byte *) &ret, src, 4);
1564 static public unsafe long Int64FromNative (byte [] data, int index)
1567 throw new ArgumentNullException ("data");
1568 if (data.Length - index < 8)
1569 throw new ArgumentException ("index");
1571 throw new ArgumentException ("index");
1574 fixed (byte *src = &data[index]){
1575 PutBytesNative ((byte *) &ret, src, 8);
1580 static public unsafe ulong UInt64FromNative (byte [] data, int index)
1583 throw new ArgumentNullException ("data");
1584 if (data.Length - index < 8)
1585 throw new ArgumentException ("index");
1587 throw new ArgumentException ("index");
1590 fixed (byte *src = &data[index]){
1591 PutBytesNative ((byte *) &ret, src, 8);
1596 static public unsafe int Int32FromNative (byte [] data, int index)
1599 throw new ArgumentNullException ("data");
1600 if (data.Length - index < 4)
1601 throw new ArgumentException ("index");
1603 throw new ArgumentException ("index");
1606 fixed (byte *src = &data[index]){
1607 PutBytesNative ((byte *) &ret, src, 4);
1612 static public unsafe uint UInt32FromNative (byte [] data, int index)
1615 throw new ArgumentNullException ("data");
1616 if (data.Length - index < 4)
1617 throw new ArgumentException ("index");
1619 throw new ArgumentException ("index");
1622 fixed (byte *src = &data[index]){
1623 PutBytesNative ((byte *) &ret, src, 4);
1628 static public unsafe short Int16FromNative (byte [] data, int index)
1631 throw new ArgumentNullException ("data");
1632 if (data.Length - index < 2)
1633 throw new ArgumentException ("index");
1635 throw new ArgumentException ("index");
1638 fixed (byte *src = &data[index]){
1639 PutBytesNative ((byte *) &ret, src, 2);
1644 static public unsafe ushort UInt16FromNative (byte [] data, int index)
1647 throw new ArgumentNullException ("data");
1648 if (data.Length - index < 2)
1649 throw new ArgumentException ("index");
1651 throw new ArgumentException ("index");
1654 fixed (byte *src = &data[index]){
1655 PutBytesNative ((byte *) &ret, src, 2);
1660 unsafe static byte[] GetBytesPtr (byte *ptr, int count)
1662 byte [] ret = new byte [count];
1664 for (int i = 0; i < count; i++) {
1671 unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count)
1673 byte [] ret = new byte [count];
1677 for (int i = 0; i < count; i++) {
1678 ret [t-i] = ptr [i];
1681 for (int i = 0; i < count; i++) {
1688 unsafe public static byte[] GetBytesNative (bool value)
1690 return GetBytesPtr ((byte *) &value, 1);
1693 unsafe public static byte[] GetBytesNative (char value)
1695 return GetBytesPtr ((byte *) &value, 2);
1698 unsafe public static byte[] GetBytesNative (short value)
1700 return GetBytesPtr ((byte *) &value, 2);
1703 unsafe public static byte[] GetBytesNative (int value)
1705 return GetBytesPtr ((byte *) &value, 4);
1708 unsafe public static byte[] GetBytesNative (long value)
1710 return GetBytesPtr ((byte *) &value, 8);
1713 [CLSCompliant (false)]
1714 unsafe public static byte[] GetBytesNative (ushort value)
1716 return GetBytesPtr ((byte *) &value, 2);
1719 [CLSCompliant (false)]
1720 unsafe public static byte[] GetBytesNative (uint value)
1722 return GetBytesPtr ((byte *) &value, 4);
1725 [CLSCompliant (false)]
1726 unsafe public static byte[] GetBytesNative (ulong value)
1728 return GetBytesPtr ((byte *) &value, 8);
1731 unsafe public static byte[] GetBytesNative (float value)
1733 return GetBytesPtr ((byte *) &value, 4);
1736 unsafe public static byte[] GetBytesNative (double value)
1738 return GetBytesPtr ((byte *) &value, 8);
1741 unsafe public static byte[] GetBytesLE (bool value)
1743 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1);
1746 unsafe public static byte[] GetBytesLE (char value)
1748 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1751 unsafe public static byte[] GetBytesLE (short value)
1753 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1756 unsafe public static byte[] GetBytesLE (int value)
1758 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1761 unsafe public static byte[] GetBytesLE (long value)
1763 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1766 [CLSCompliant (false)]
1767 unsafe public static byte[] GetBytesLE (ushort value)
1769 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1772 [CLSCompliant (false)]
1773 unsafe public static byte[] GetBytesLE (uint value)
1775 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1778 [CLSCompliant (false)]
1779 unsafe public static byte[] GetBytesLE (ulong value)
1781 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1784 unsafe public static byte[] GetBytesLE (float value)
1786 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1789 unsafe public static byte[] GetBytesLE (double value)
1791 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1794 unsafe public static byte[] GetBytesBE (bool value)
1796 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1);
1799 unsafe public static byte[] GetBytesBE (char value)
1801 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1804 unsafe public static byte[] GetBytesBE (short value)
1806 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1809 unsafe public static byte[] GetBytesBE (int value)
1811 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1814 unsafe public static byte[] GetBytesBE (long value)
1816 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1819 [CLSCompliant (false)]
1820 unsafe public static byte[] GetBytesBE (ushort value)
1822 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1825 [CLSCompliant (false)]
1826 unsafe public static byte[] GetBytesBE (uint value)
1828 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1831 [CLSCompliant (false)]
1832 unsafe public static byte[] GetBytesBE (ulong value)
1834 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1837 unsafe public static byte[] GetBytesBE (float value)
1839 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1842 unsafe public static byte[] GetBytesBE (double value)
1844 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);