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;
43 #pragma warning disable 3021
47 #if MONO_DATACONVERTER_PUBLIC
48 unsafe public abstract class DataConverter {
50 unsafe internal abstract class DataConverter {
52 // Disables the warning: CLS compliance checking will not be performed on
53 // `XXXX' because it is not visible from outside this assembly
54 #pragma warning disable 3019
56 static DataConverter SwapConv = new SwapConverter ();
57 static 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;
470 e = Encoding.BigEndianUnicode;
474 e = Encoding.GetEncoding (12000);
478 e = Encoding.GetEncoding (12001);
483 throw new ArgumentException ("Invalid format for $ specifier", "description");
487 b.Add (e.GetBytes (Convert.ToString (oarg)));
489 b.Add (new byte [n]);
492 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
493 b.description [b.i]));
498 static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
501 idx = Align (idx, size);
504 if (idx + size > buffer.Length){
511 static public IList Unpack (string description, byte [] buffer, int startIndex)
513 DataConverter conv = CopyConv;
514 ArrayList result = new ArrayList ();
515 int idx = startIndex;
519 for (int i = 0; i < description.Length && idx < buffer.Length; ){
522 switch (description [i]){
542 if (Prepare (buffer, ref idx, 4, ref align)){
543 result.Add (conv.GetInt32 (buffer, idx));
549 if (Prepare (buffer, ref idx, 4, ref align)){
550 result.Add (conv.GetUInt32 (buffer, idx));
556 if (Prepare (buffer, ref idx, 2, ref align)){
557 result.Add (conv.GetInt16 (buffer, idx));
563 if (Prepare (buffer, ref idx, 2, ref align)){
564 result.Add (conv.GetUInt16 (buffer, idx));
570 if (Prepare (buffer, ref idx, 8, ref align)){
571 result.Add (conv.GetInt64 (buffer, idx));
577 if (Prepare (buffer, ref idx, 8, ref align)){
578 result.Add (conv.GetUInt64 (buffer, idx));
584 if (Prepare (buffer, ref idx, 4, ref align)){
585 result.Add (conv.GetDouble (buffer, idx));
591 if (Prepare (buffer, ref idx, 8, ref align)){
592 result.Add (conv.GetDouble (buffer, idx));
598 if (Prepare (buffer, ref idx, 1, ref align)){
599 result.Add (buffer [idx]);
605 if (Prepare (buffer, ref idx, 1, ref align)){
608 if (description [i] == 'c')
609 c = ((char) ((sbyte)buffer [idx]));
611 c = ((char) ((byte)buffer [idx]));
619 case '1': case '2': case '3': case '4': case '5':
620 case '6': case '7': case '8': case '9':
621 repeat = ((short) description [i]) - ((short) '0');
626 repeat = Int32.MaxValue;
632 for (j = i+1; j < description.Length; j++){
633 if (description [j] == ']')
635 n = ((short) description [j]) - ((short) '0');
636 if (n >= 0 && n <= 9){
640 count = count * 10 + n;
644 throw new ArgumentException ("invalid size specification");
650 // bool with_null = description [i] == 'z';
652 if (i >= description.Length)
653 throw new ArgumentException ("$ description needs a type specified", "description");
654 char d = description [i];
657 idx = Align (idx, 4);
660 if (idx >= buffer.Length)
669 e = Encoding.Unicode;
677 e = Encoding.BigEndianUnicode;
681 e = Encoding.GetEncoding (12000);
685 e = Encoding.GetEncoding (12001);
690 throw new ArgumentException ("Invalid format for $ specifier", "description");
695 for (; k < buffer.Length && buffer [k] != 0; k++)
697 result.Add (e.GetChars (buffer, idx, k-idx));
698 if (k == buffer.Length)
705 for (; k < buffer.Length; k++){
706 if (k+1 == buffer.Length){
710 if (buffer [k] == 0 && buffer [k+1] == 0)
713 result.Add (e.GetChars (buffer, idx, k-idx));
714 if (k == buffer.Length)
721 for (; k < buffer.Length; k++){
722 if (k+3 >= buffer.Length){
726 if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
729 result.Add (e.GetChars (buffer, idx, k-idx));
730 if (k == buffer.Length)
738 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
751 internal void Check (byte [] dest, int destIdx, int size)
754 throw new ArgumentNullException ("dest");
755 if (destIdx < 0 || destIdx > dest.Length - size)
756 throw new ArgumentException ("destIdx");
759 class CopyConverter : DataConverter {
760 public override double GetDouble (byte [] data, int index)
763 throw new ArgumentNullException ("data");
764 if (data.Length - index < 8)
765 throw new ArgumentException ("index");
767 throw new ArgumentException ("index");
769 byte *b = (byte *)&ret;
771 for (int i = 0; i < 8; i++)
772 b [i] = data [index+i];
777 public override ulong GetUInt64 (byte [] data, int index)
780 throw new ArgumentNullException ("data");
781 if (data.Length - index < 8)
782 throw new ArgumentException ("index");
784 throw new ArgumentException ("index");
787 byte *b = (byte *)&ret;
789 for (int i = 0; i < 8; i++)
790 b [i] = data [index+i];
795 public override long GetInt64 (byte [] data, int index)
798 throw new ArgumentNullException ("data");
799 if (data.Length - index < 8)
800 throw new ArgumentException ("index");
802 throw new ArgumentException ("index");
805 byte *b = (byte *)&ret;
807 for (int i = 0; i < 8; i++)
808 b [i] = data [index+i];
813 public override float GetFloat (byte [] data, int index)
816 throw new ArgumentNullException ("data");
817 if (data.Length - index < 4)
818 throw new ArgumentException ("index");
820 throw new ArgumentException ("index");
823 byte *b = (byte *)&ret;
825 for (int i = 0; i < 4; i++)
826 b [i] = data [index+i];
831 public override int GetInt32 (byte [] data, int index)
834 throw new ArgumentNullException ("data");
835 if (data.Length - index < 4)
836 throw new ArgumentException ("index");
838 throw new ArgumentException ("index");
841 byte *b = (byte *)&ret;
843 for (int i = 0; i < 4; i++)
844 b [i] = data [index+i];
849 public override uint GetUInt32 (byte [] data, int index)
852 throw new ArgumentNullException ("data");
853 if (data.Length - index < 4)
854 throw new ArgumentException ("index");
856 throw new ArgumentException ("index");
859 byte *b = (byte *)&ret;
861 for (int i = 0; i < 4; i++)
862 b [i] = data [index+i];
867 public override short GetInt16 (byte [] data, int index)
870 throw new ArgumentNullException ("data");
871 if (data.Length - index < 2)
872 throw new ArgumentException ("index");
874 throw new ArgumentException ("index");
877 byte *b = (byte *)&ret;
879 for (int i = 0; i < 2; i++)
880 b [i] = data [index+i];
885 public override ushort GetUInt16 (byte [] data, int index)
888 throw new ArgumentNullException ("data");
889 if (data.Length - index < 2)
890 throw new ArgumentException ("index");
892 throw new ArgumentException ("index");
895 byte *b = (byte *)&ret;
897 for (int i = 0; i < 2; i++)
898 b [i] = data [index+i];
903 public override void PutBytes (byte [] dest, int destIdx, double value)
905 Check (dest, destIdx, 8);
906 fixed (byte *target = &dest [destIdx]){
907 long *source = (long *) &value;
909 *((long *)target) = *source;
913 public override void PutBytes (byte [] dest, int destIdx, float value)
915 Check (dest, destIdx, 4);
916 fixed (byte *target = &dest [destIdx]){
917 uint *source = (uint *) &value;
919 *((uint *)target) = *source;
923 public override void PutBytes (byte [] dest, int destIdx, int value)
925 Check (dest, destIdx, 4);
926 fixed (byte *target = &dest [destIdx]){
927 uint *source = (uint *) &value;
929 *((uint *)target) = *source;
933 public override void PutBytes (byte [] dest, int destIdx, uint value)
935 Check (dest, destIdx, 4);
936 fixed (byte *target = &dest [destIdx]){
937 uint *source = (uint *) &value;
939 *((uint *)target) = *source;
943 public override void PutBytes (byte [] dest, int destIdx, long value)
945 Check (dest, destIdx, 8);
946 fixed (byte *target = &dest [destIdx]){
947 long *source = (long *) &value;
949 *((long*)target) = *source;
953 public override void PutBytes (byte [] dest, int destIdx, ulong value)
955 Check (dest, destIdx, 8);
956 fixed (byte *target = &dest [destIdx]){
957 ulong *source = (ulong *) &value;
959 *((ulong *) target) = *source;
963 public override void PutBytes (byte [] dest, int destIdx, short value)
965 Check (dest, destIdx, 2);
966 fixed (byte *target = &dest [destIdx]){
967 ushort *source = (ushort *) &value;
969 *((ushort *)target) = *source;
973 public override void PutBytes (byte [] dest, int destIdx, ushort value)
975 Check (dest, destIdx, 2);
976 fixed (byte *target = &dest [destIdx]){
977 ushort *source = (ushort *) &value;
979 *((ushort *)target) = *source;
984 class SwapConverter : DataConverter {
985 public override double GetDouble (byte [] data, int index)
988 throw new ArgumentNullException ("data");
989 if (data.Length - index < 8)
990 throw new ArgumentException ("index");
992 throw new ArgumentException ("index");
995 byte *b = (byte *)&ret;
997 for (int i = 0; i < 8; i++)
998 b [7-i] = data [index+i];
1003 public override ulong GetUInt64 (byte [] data, int index)
1006 throw new ArgumentNullException ("data");
1007 if (data.Length - index < 8)
1008 throw new ArgumentException ("index");
1010 throw new ArgumentException ("index");
1013 byte *b = (byte *)&ret;
1015 for (int i = 0; i < 8; i++)
1016 b [7-i] = data [index+i];
1021 public override long GetInt64 (byte [] data, int index)
1024 throw new ArgumentNullException ("data");
1025 if (data.Length - index < 8)
1026 throw new ArgumentException ("index");
1028 throw new ArgumentException ("index");
1031 byte *b = (byte *)&ret;
1033 for (int i = 0; i < 8; i++)
1034 b [7-i] = data [index+i];
1039 public override float GetFloat (byte [] data, int index)
1042 throw new ArgumentNullException ("data");
1043 if (data.Length - index < 4)
1044 throw new ArgumentException ("index");
1046 throw new ArgumentException ("index");
1049 byte *b = (byte *)&ret;
1051 for (int i = 0; i < 4; i++)
1052 b [3-i] = data [index+i];
1057 public override int GetInt32 (byte [] data, int index)
1060 throw new ArgumentNullException ("data");
1061 if (data.Length - index < 4)
1062 throw new ArgumentException ("index");
1064 throw new ArgumentException ("index");
1067 byte *b = (byte *)&ret;
1069 for (int i = 0; i < 4; i++)
1070 b [3-i] = data [index+i];
1075 public override uint GetUInt32 (byte [] data, int index)
1078 throw new ArgumentNullException ("data");
1079 if (data.Length - index < 4)
1080 throw new ArgumentException ("index");
1082 throw new ArgumentException ("index");
1085 byte *b = (byte *)&ret;
1087 for (int i = 0; i < 4; i++)
1088 b [3-i] = data [index+i];
1093 public override short GetInt16 (byte [] data, int index)
1096 throw new ArgumentNullException ("data");
1097 if (data.Length - index < 2)
1098 throw new ArgumentException ("index");
1100 throw new ArgumentException ("index");
1103 byte *b = (byte *)&ret;
1105 for (int i = 0; i < 2; i++)
1106 b [1-i] = data [index+i];
1111 public override ushort GetUInt16 (byte [] data, int index)
1114 throw new ArgumentNullException ("data");
1115 if (data.Length - index < 2)
1116 throw new ArgumentException ("index");
1118 throw new ArgumentException ("index");
1121 byte *b = (byte *)&ret;
1123 for (int i = 0; i < 2; i++)
1124 b [1-i] = data [index+i];
1129 public override void PutBytes (byte [] dest, int destIdx, double value)
1131 Check (dest, destIdx, 8);
1133 fixed (byte *target = &dest [destIdx]){
1134 byte *source = (byte *) &value;
1136 for (int i = 0; i < 8; i++)
1137 target [i] = source [7-i];
1141 public override void PutBytes (byte [] dest, int destIdx, float value)
1143 Check (dest, destIdx, 4);
1145 fixed (byte *target = &dest [destIdx]){
1146 byte *source = (byte *) &value;
1148 for (int i = 0; i < 4; i++)
1149 target [i] = source [3-i];
1153 public override void PutBytes (byte [] dest, int destIdx, int value)
1155 Check (dest, destIdx, 4);
1157 fixed (byte *target = &dest [destIdx]){
1158 byte *source = (byte *) &value;
1160 for (int i = 0; i < 4; i++)
1161 target [i] = source [3-i];
1165 public override void PutBytes (byte [] dest, int destIdx, uint value)
1167 Check (dest, destIdx, 4);
1169 fixed (byte *target = &dest [destIdx]){
1170 byte *source = (byte *) &value;
1172 for (int i = 0; i < 4; i++)
1173 target [i] = source [3-i];
1177 public override void PutBytes (byte [] dest, int destIdx, long value)
1179 Check (dest, destIdx, 8);
1181 fixed (byte *target = &dest [destIdx]){
1182 byte *source = (byte *) &value;
1184 for (int i = 0; i < 8; i++)
1185 target [i] = source [7-i];
1189 public override void PutBytes (byte [] dest, int destIdx, ulong value)
1191 Check (dest, destIdx, 8);
1193 fixed (byte *target = &dest [destIdx]){
1194 byte *source = (byte *) &value;
1196 for (int i = 0; i < 4; i++)
1197 target [i] = source [7-i];
1201 public override void PutBytes (byte [] dest, int destIdx, short value)
1203 Check (dest, destIdx, 2);
1205 fixed (byte *target = &dest [destIdx]){
1206 byte *source = (byte *) &value;
1208 for (int i = 0; i < 2; i++)
1209 target [i] = source [1-i];
1213 public override void PutBytes (byte [] dest, int destIdx, ushort value)
1215 Check (dest, destIdx, 2);
1217 fixed (byte *target = &dest [destIdx]){
1218 byte *source = (byte *) &value;
1220 for (int i = 0; i < 2; i++)
1221 target [i] = source [1-i];
1226 #if MONO_DATACONVERTER_STATIC_METHODS
1227 static unsafe void PutBytesLE (byte *dest, byte *src, int count)
1231 if (BitConverter.IsLittleEndian){
1232 for (; i < count; i++)
1236 for (; i < count; i++)
1241 static unsafe void PutBytesBE (byte *dest, byte *src, int count)
1245 if (BitConverter.IsLittleEndian){
1247 for (; i < count; i++)
1250 for (; i < count; i++)
1255 static unsafe void PutBytesNative (byte *dest, byte *src, int count)
1259 for (; i < count; i++)
1260 dest [i-count] = *src++;
1263 static public unsafe double DoubleFromLE (byte[] data, int index)
1266 throw new ArgumentNullException ("data");
1267 if (data.Length - index < 8)
1268 throw new ArgumentException ("index");
1270 throw new ArgumentException ("index");
1273 fixed (byte *src = &data[index]){
1274 PutBytesLE ((byte *) &ret, src, 8);
1279 static public unsafe float FloatFromLE (byte [] data, int index)
1282 throw new ArgumentNullException ("data");
1283 if (data.Length - index < 4)
1284 throw new ArgumentException ("index");
1286 throw new ArgumentException ("index");
1289 fixed (byte *src = &data[index]){
1290 PutBytesLE ((byte *) &ret, src, 4);
1295 static public unsafe long Int64FromLE (byte [] data, int index)
1298 throw new ArgumentNullException ("data");
1299 if (data.Length - index < 8)
1300 throw new ArgumentException ("index");
1302 throw new ArgumentException ("index");
1305 fixed (byte *src = &data[index]){
1306 PutBytesLE ((byte *) &ret, src, 8);
1311 static public unsafe ulong UInt64FromLE (byte [] data, int index)
1314 throw new ArgumentNullException ("data");
1315 if (data.Length - index < 8)
1316 throw new ArgumentException ("index");
1318 throw new ArgumentException ("index");
1321 fixed (byte *src = &data[index]){
1322 PutBytesLE ((byte *) &ret, src, 8);
1327 static public unsafe int Int32FromLE (byte [] data, int index)
1330 throw new ArgumentNullException ("data");
1331 if (data.Length - index < 4)
1332 throw new ArgumentException ("index");
1334 throw new ArgumentException ("index");
1337 fixed (byte *src = &data[index]){
1338 PutBytesLE ((byte *) &ret, src, 4);
1343 static public unsafe uint UInt32FromLE (byte [] data, int index)
1346 throw new ArgumentNullException ("data");
1347 if (data.Length - index < 4)
1348 throw new ArgumentException ("index");
1350 throw new ArgumentException ("index");
1353 fixed (byte *src = &data[index]){
1354 PutBytesLE ((byte *) &ret, src, 4);
1359 static public unsafe short Int16FromLE (byte [] data, int index)
1362 throw new ArgumentNullException ("data");
1363 if (data.Length - index < 2)
1364 throw new ArgumentException ("index");
1366 throw new ArgumentException ("index");
1369 fixed (byte *src = &data[index]){
1370 PutBytesLE ((byte *) &ret, src, 2);
1375 static public unsafe ushort UInt16FromLE (byte [] data, int index)
1378 throw new ArgumentNullException ("data");
1379 if (data.Length - index < 2)
1380 throw new ArgumentException ("index");
1382 throw new ArgumentException ("index");
1385 fixed (byte *src = &data[index]){
1386 PutBytesLE ((byte *) &ret, src, 2);
1391 static public unsafe double DoubleFromBE (byte[] data, int index)
1394 throw new ArgumentNullException ("data");
1395 if (data.Length - index < 8)
1396 throw new ArgumentException ("index");
1398 throw new ArgumentException ("index");
1401 fixed (byte *src = &data[index]){
1402 PutBytesBE ((byte *) &ret, src, 8);
1407 static public unsafe float FloatFromBE (byte [] data, int index)
1410 throw new ArgumentNullException ("data");
1411 if (data.Length - index < 4)
1412 throw new ArgumentException ("index");
1414 throw new ArgumentException ("index");
1417 fixed (byte *src = &data[index]){
1418 PutBytesBE ((byte *) &ret, src, 4);
1423 static public unsafe long Int64FromBE (byte [] data, int index)
1426 throw new ArgumentNullException ("data");
1427 if (data.Length - index < 8)
1428 throw new ArgumentException ("index");
1430 throw new ArgumentException ("index");
1433 fixed (byte *src = &data[index]){
1434 PutBytesBE ((byte *) &ret, src, 8);
1439 static public unsafe ulong UInt64FromBE (byte [] data, int index)
1442 throw new ArgumentNullException ("data");
1443 if (data.Length - index < 8)
1444 throw new ArgumentException ("index");
1446 throw new ArgumentException ("index");
1449 fixed (byte *src = &data[index]){
1450 PutBytesBE ((byte *) &ret, src, 8);
1455 static public unsafe int Int32FromBE (byte [] data, int index)
1458 throw new ArgumentNullException ("data");
1459 if (data.Length - index < 4)
1460 throw new ArgumentException ("index");
1462 throw new ArgumentException ("index");
1465 fixed (byte *src = &data[index]){
1466 PutBytesBE ((byte *) &ret, src, 4);
1471 static public unsafe uint UInt32FromBE (byte [] data, int index)
1474 throw new ArgumentNullException ("data");
1475 if (data.Length - index < 4)
1476 throw new ArgumentException ("index");
1478 throw new ArgumentException ("index");
1481 fixed (byte *src = &data[index]){
1482 PutBytesBE ((byte *) &ret, src, 4);
1487 static public unsafe short Int16FromBE (byte [] data, int index)
1490 throw new ArgumentNullException ("data");
1491 if (data.Length - index < 2)
1492 throw new ArgumentException ("index");
1494 throw new ArgumentException ("index");
1497 fixed (byte *src = &data[index]){
1498 PutBytesBE ((byte *) &ret, src, 2);
1503 static public unsafe ushort UInt16FromBE (byte [] data, int index)
1506 throw new ArgumentNullException ("data");
1507 if (data.Length - index < 2)
1508 throw new ArgumentException ("index");
1510 throw new ArgumentException ("index");
1513 fixed (byte *src = &data[index]){
1514 PutBytesBE ((byte *) &ret, src, 2);
1519 static public unsafe double DoubleFromNative (byte[] data, int index)
1522 throw new ArgumentNullException ("data");
1523 if (data.Length - index < 8)
1524 throw new ArgumentException ("index");
1526 throw new ArgumentException ("index");
1529 fixed (byte *src = &data[index]){
1530 PutBytesNative ((byte *) &ret, src, 8);
1535 static public unsafe float FloatFromNative (byte [] data, int index)
1538 throw new ArgumentNullException ("data");
1539 if (data.Length - index < 4)
1540 throw new ArgumentException ("index");
1542 throw new ArgumentException ("index");
1545 fixed (byte *src = &data[index]){
1546 PutBytesNative ((byte *) &ret, src, 4);
1551 static public unsafe long Int64FromNative (byte [] data, int index)
1554 throw new ArgumentNullException ("data");
1555 if (data.Length - index < 8)
1556 throw new ArgumentException ("index");
1558 throw new ArgumentException ("index");
1561 fixed (byte *src = &data[index]){
1562 PutBytesNative ((byte *) &ret, src, 8);
1567 static public unsafe ulong UInt64FromNative (byte [] data, int index)
1570 throw new ArgumentNullException ("data");
1571 if (data.Length - index < 8)
1572 throw new ArgumentException ("index");
1574 throw new ArgumentException ("index");
1577 fixed (byte *src = &data[index]){
1578 PutBytesNative ((byte *) &ret, src, 8);
1583 static public unsafe int Int32FromNative (byte [] data, int index)
1586 throw new ArgumentNullException ("data");
1587 if (data.Length - index < 4)
1588 throw new ArgumentException ("index");
1590 throw new ArgumentException ("index");
1593 fixed (byte *src = &data[index]){
1594 PutBytesNative ((byte *) &ret, src, 4);
1599 static public unsafe uint UInt32FromNative (byte [] data, int index)
1602 throw new ArgumentNullException ("data");
1603 if (data.Length - index < 4)
1604 throw new ArgumentException ("index");
1606 throw new ArgumentException ("index");
1609 fixed (byte *src = &data[index]){
1610 PutBytesNative ((byte *) &ret, src, 4);
1615 static public unsafe short Int16FromNative (byte [] data, int index)
1618 throw new ArgumentNullException ("data");
1619 if (data.Length - index < 2)
1620 throw new ArgumentException ("index");
1622 throw new ArgumentException ("index");
1625 fixed (byte *src = &data[index]){
1626 PutBytesNative ((byte *) &ret, src, 2);
1631 static public unsafe ushort UInt16FromNative (byte [] data, int index)
1634 throw new ArgumentNullException ("data");
1635 if (data.Length - index < 2)
1636 throw new ArgumentException ("index");
1638 throw new ArgumentException ("index");
1641 fixed (byte *src = &data[index]){
1642 PutBytesNative ((byte *) &ret, src, 2);
1647 unsafe static byte[] GetBytesPtr (byte *ptr, int count)
1649 byte [] ret = new byte [count];
1651 for (int i = 0; i < count; i++) {
1658 unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count)
1660 byte [] ret = new byte [count];
1664 for (int i = 0; i < count; i++) {
1665 ret [t-i] = ptr [i];
1668 for (int i = 0; i < count; i++) {
1675 unsafe public static byte[] GetBytesNative (bool value)
1677 return GetBytesPtr ((byte *) &value, 1);
1680 unsafe public static byte[] GetBytesNative (char value)
1682 return GetBytesPtr ((byte *) &value, 2);
1685 unsafe public static byte[] GetBytesNative (short value)
1687 return GetBytesPtr ((byte *) &value, 2);
1690 unsafe public static byte[] GetBytesNative (int value)
1692 return GetBytesPtr ((byte *) &value, 4);
1695 unsafe public static byte[] GetBytesNative (long value)
1697 return GetBytesPtr ((byte *) &value, 8);
1700 [CLSCompliant (false)]
1701 unsafe public static byte[] GetBytesNative (ushort value)
1703 return GetBytesPtr ((byte *) &value, 2);
1706 [CLSCompliant (false)]
1707 unsafe public static byte[] GetBytesNative (uint value)
1709 return GetBytesPtr ((byte *) &value, 4);
1712 [CLSCompliant (false)]
1713 unsafe public static byte[] GetBytesNative (ulong value)
1715 return GetBytesPtr ((byte *) &value, 8);
1718 unsafe public static byte[] GetBytesNative (float value)
1720 return GetBytesPtr ((byte *) &value, 4);
1723 unsafe public static byte[] GetBytesNative (double value)
1725 return GetBytesPtr ((byte *) &value, 8);
1728 unsafe public static byte[] GetBytesLE (bool value)
1730 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1);
1733 unsafe public static byte[] GetBytesLE (char value)
1735 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1738 unsafe public static byte[] GetBytesLE (short value)
1740 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1743 unsafe public static byte[] GetBytesLE (int value)
1745 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1748 unsafe public static byte[] GetBytesLE (long value)
1750 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1753 [CLSCompliant (false)]
1754 unsafe public static byte[] GetBytesLE (ushort value)
1756 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1759 [CLSCompliant (false)]
1760 unsafe public static byte[] GetBytesLE (uint value)
1762 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1765 [CLSCompliant (false)]
1766 unsafe public static byte[] GetBytesLE (ulong value)
1768 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1771 unsafe public static byte[] GetBytesLE (float value)
1773 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1776 unsafe public static byte[] GetBytesLE (double value)
1778 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1781 unsafe public static byte[] GetBytesBE (bool value)
1783 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1);
1786 unsafe public static byte[] GetBytesBE (char value)
1788 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1791 unsafe public static byte[] GetBytesBE (short value)
1793 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1796 unsafe public static byte[] GetBytesBE (int value)
1798 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1801 unsafe public static byte[] GetBytesBE (long value)
1803 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1806 [CLSCompliant (false)]
1807 unsafe public static byte[] GetBytesBE (ushort value)
1809 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1812 [CLSCompliant (false)]
1813 unsafe public static byte[] GetBytesBE (uint value)
1815 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1818 [CLSCompliant (false)]
1819 unsafe public static byte[] GetBytesBE (ulong value)
1821 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1824 unsafe public static byte[] GetBytesBE (float value)
1826 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1829 unsafe public static byte[] GetBytesBE (double value)
1831 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);