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;
45 #if MONO_DATACONVERTER_PUBLIC
46 unsafe public abstract class DataConverter {
48 unsafe internal abstract class DataConverter {
50 static DataConverter SwapConv = new SwapConverter ();
51 static DataConverter CopyConv = new CopyConverter ();
53 public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian;
55 public abstract double GetDouble (byte [] data, int index);
56 public abstract float GetFloat (byte [] data, int index);
57 public abstract long GetInt64 (byte [] data, int index);
58 public abstract int GetInt32 (byte [] data, int index);
60 public abstract short GetInt16 (byte [] data, int index);
62 [CLSCompliant (false)]
63 public abstract uint GetUInt32 (byte [] data, int index);
64 [CLSCompliant (false)]
65 public abstract ushort GetUInt16 (byte [] data, int index);
66 [CLSCompliant (false)]
67 public abstract ulong GetUInt64 (byte [] data, int index);
69 public abstract void PutBytes (byte [] dest, int destIdx, double value);
70 public abstract void PutBytes (byte [] dest, int destIdx, float value);
71 public abstract void PutBytes (byte [] dest, int destIdx, int value);
72 public abstract void PutBytes (byte [] dest, int destIdx, long value);
73 public abstract void PutBytes (byte [] dest, int destIdx, short value);
75 [CLSCompliant (false)]
76 public abstract void PutBytes (byte [] dest, int destIdx, ushort value);
77 [CLSCompliant (false)]
78 public abstract void PutBytes (byte [] dest, int destIdx, uint value);
79 [CLSCompliant (false)]
80 public abstract void PutBytes (byte [] dest, int destIdx, ulong value);
82 public byte[] GetBytes (double value)
84 byte [] ret = new byte [8];
85 PutBytes (ret, 0, value);
89 public byte[] GetBytes (float value)
91 byte [] ret = new byte [4];
92 PutBytes (ret, 0, value);
96 public byte[] GetBytes (int value)
98 byte [] ret = new byte [4];
99 PutBytes (ret, 0, value);
103 public byte[] GetBytes (long value)
105 byte [] ret = new byte [8];
106 PutBytes (ret, 0, value);
110 public byte[] GetBytes (short value)
112 byte [] ret = new byte [2];
113 PutBytes (ret, 0, value);
117 [CLSCompliant (false)]
118 public byte[] GetBytes (ushort value)
120 byte [] ret = new byte [2];
121 PutBytes (ret, 0, value);
125 [CLSCompliant (false)]
126 public byte[] GetBytes (uint value)
128 byte [] ret = new byte [4];
129 PutBytes (ret, 0, value);
133 [CLSCompliant (false)]
134 public byte[] GetBytes (ulong value)
136 byte [] ret = new byte [8];
137 PutBytes (ret, 0, value);
141 static public DataConverter LittleEndian {
143 return BitConverter.IsLittleEndian ? CopyConv : SwapConv;
147 static public DataConverter BigEndian {
149 return BitConverter.IsLittleEndian ? SwapConv : CopyConv;
153 static public DataConverter Native {
159 static int Align (int current, int align)
161 return ((current + align - 1) / align) * align;
166 public byte [] buffer;
169 public string description;
170 public int i; // position in the description
171 public DataConverter conv;
175 // if align == -1, auto align to the size of the byte array
176 // if align == 0, do not do alignment
177 // Any other values aligns to that particular size
181 public void Add (byte [] group)
183 //Console.WriteLine ("Adding {0} bytes to {1} (next={2}", group.Length,
184 // buffer == null ? "null" : buffer.Length.ToString (), next);
193 next = Align (next, group.Length);
195 next = Align (next, align);
199 if (next + group.Length > buffer.Length){
200 byte [] nb = new byte [System.Math.Max (next, 16) * 2 + group.Length];
201 Array.Copy (buffer, nb, buffer.Length);
202 Array.Copy (group, 0, nb, next, group.Length);
203 next = next + group.Length;
206 Array.Copy (group, 0, buffer, next, group.Length);
207 next += group.Length;
211 public byte [] Get ()
216 if (buffer.Length != next){
217 byte [] b = new byte [next];
218 Array.Copy (buffer, b, next);
228 // ^ Switch to big endian encoding
229 // _ Switch to little endian encoding
230 // % Switch to host (native) encoding
231 // ! aligns the next data type to its natural boundary (for strings this is 4).
243 // z8 string encoded as UTF8 with 1-byte null terminator
244 // z6 string encoded as UTF16 with 2-byte null terminator
245 // z7 string encoded as UTF7 with 1-byte null terminator
246 // zb string encoded as BigEndianUnicode with 2-byte null terminator
247 // z3 string encoded as UTF32 with 4-byte null terminator
248 // z4 string encoded as UTF32 big endian with 4-byte null terminator
249 // $8 string encoded as UTF8
250 // $6 string encoded as UTF16
251 // $7 string encoded as UTF7
252 // $b string encoded as BigEndianUnicode
253 // $3 string encoded as UTF32
254 // $4 string encoded as UTF-32 big endian encoding
257 // Repeats, these are prefixes:
258 // N a number between 1 and 9, indicates a repeat count (process N items
259 // with the following datatype
260 // [N] For numbers larger than 9, use brackets, for example [20]
261 // * Repeat the next data type until the arguments are exhausted
263 static public byte [] Pack (string description, params object [] args)
266 PackContext b = new PackContext ();
268 b.description = description;
270 for (b.i = 0; b.i < description.Length; ){
273 if (argn < args.Length)
284 if (PackOne (b, oarg)){
299 static public byte [] PackEnumerable (string description, IEnumerable args)
301 PackContext b = new PackContext ();
303 b.description = description;
305 IEnumerator enumerator = args.GetEnumerator ();
306 bool ok = enumerator.MoveNext ();
308 for (b.i = 0; b.i < description.Length; b.i++){
312 oarg = enumerator.Current;
321 if (PackOne (b, oarg)){
322 ok = enumerator.MoveNext ();
337 // Packs one datum `oarg' into the buffer `b', using the string format
338 // in `description' at position `i'
340 // Returns: true if we must pick the next object from the list
342 static bool PackOne (PackContext b, object oarg)
344 switch (b.description [b.i]){
349 b.conv = LittleEndian;
360 b.Add (new byte [] { 0 });
365 b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg)));
369 b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg)));
373 b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg)));
377 b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg)));
381 b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg)));
385 b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg)));
389 b.Add (b.conv.GetBytes (Convert.ToSingle (oarg)));
393 b.Add (b.conv.GetBytes (Convert.ToDouble (oarg)));
397 b.Add (new byte [] { Convert.ToByte (oarg) });
401 b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) });
405 b.Add (new byte [] { Convert.ToByte (oarg) });
409 case '1': case '2': case '3': case '4': case '5':
410 case '6': case '7': case '8': case '9':
411 b.repeat = ((short) b.description [b.i]) - ((short) '0');
415 b.repeat = Int32.MaxValue;
421 for (j = b.i+1; j < b.description.Length; j++){
422 if (b.description [j] == ']')
424 int n = ((short) b.description [j]) - ((short) '0');
425 if (n >= 0 && n <= 9){
429 count = count * 10 + n;
433 throw new ArgumentException ("invalid size specification");
439 bool add_null = b.description [b.i] == 'z';
442 if (b.i >= b.description.Length)
443 throw new ArgumentException ("$ description needs a type specified", "description");
444 char d = b.description [b.i];
453 e = Encoding.Unicode;
461 e = Encoding.BigEndianUnicode;
465 e = Encoding.GetEncoding (12000);
469 e = Encoding.GetEncoding (12001);
474 throw new ArgumentException ("Invalid format for $ specifier", "description");
477 b.Add (e.GetBytes (Convert.ToString (oarg)));
479 b.Add (new byte [n]);
482 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
483 b.description [b.i]));
488 static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
491 idx = Align (idx, size);
494 if (idx + size >= buffer.Length){
501 static public IList Unpack (string description, byte [] buffer, int startIndex)
503 DataConverter conv = CopyConv;
504 ArrayList result = new ArrayList ();
505 int idx = startIndex;
509 for (int i = 0; i < description.Length && idx < buffer.Length; ){
512 switch (description [i]){
532 if (Prepare (buffer, ref idx, 4, ref align)){
533 result.Add (conv.GetInt32 (buffer, idx));
539 if (Prepare (buffer, ref idx, 4, ref align)){
540 result.Add (conv.GetUInt32 (buffer, idx));
546 if (Prepare (buffer, ref idx, 2, ref align)){
547 result.Add (conv.GetInt16 (buffer, idx));
553 if (Prepare (buffer, ref idx, 2, ref align)){
554 result.Add (conv.GetUInt16 (buffer, idx));
560 if (Prepare (buffer, ref idx, 8, ref align)){
561 result.Add (conv.GetInt64 (buffer, idx));
567 if (Prepare (buffer, ref idx, 8, ref align)){
568 result.Add (conv.GetUInt64 (buffer, idx));
574 if (Prepare (buffer, ref idx, 4, ref align)){
575 result.Add (conv.GetDouble (buffer, idx));
581 if (Prepare (buffer, ref idx, 8, ref align)){
582 result.Add (conv.GetDouble (buffer, idx));
588 if (Prepare (buffer, ref idx, 1, ref align)){
589 result.Add (buffer [idx]);
595 if (Prepare (buffer, ref idx, 1, ref align)){
598 if (description [i] == 'c')
599 c = ((char) ((sbyte)buffer [idx]));
601 c = ((char) ((byte)buffer [idx]));
609 case '1': case '2': case '3': case '4': case '5':
610 case '6': case '7': case '8': case '9':
611 repeat = ((short) description [i]) - ((short) '0');
615 repeat = Int32.MaxValue;
621 for (j = i+1; j < description.Length; j++){
622 if (description [j] == ']')
624 int n = ((short) description [j]) - ((short) '0');
625 if (n >= 0 && n <= 9){
629 count = count * 10 + n;
633 throw new ArgumentException ("invalid size specification");
639 // bool with_null = description [i] == 'z';
642 if (i >= description.Length)
643 throw new ArgumentException ("$ description needs a type specified", "description");
644 char d = description [i];
647 idx = Align (idx, 4);
650 if (idx >= buffer.Length)
659 e = Encoding.Unicode;
667 e = Encoding.BigEndianUnicode;
671 e = Encoding.GetEncoding (12000);
675 e = Encoding.GetEncoding (12001);
680 throw new ArgumentException ("Invalid format for $ specifier", "description");
685 for (; k < buffer.Length && buffer [k] != 0; k++)
687 result.Add (e.GetChars (buffer, idx, k-idx));
688 if (k == buffer.Length)
695 for (; k < buffer.Length; k++){
696 if (k+1 == buffer.Length){
700 if (buffer [k] == 0 && buffer [k+1] == 0)
703 result.Add (e.GetChars (buffer, idx, k-idx));
704 if (k == buffer.Length)
711 for (; k < buffer.Length; k++){
712 if (k+3 >= buffer.Length){
716 if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
719 result.Add (e.GetChars (buffer, idx, k-idx));
720 if (k == buffer.Length)
728 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
741 internal void Check (byte [] dest, int destIdx, int size)
744 throw new ArgumentNullException ("dest");
745 if (destIdx < 0 || destIdx > dest.Length - size)
746 throw new ArgumentException ("destIdx");
749 class CopyConverter : DataConverter {
750 public override double GetDouble (byte [] data, int index)
753 throw new ArgumentNullException ("data");
754 if (data.Length - index < 8)
755 throw new ArgumentException ("index");
757 throw new ArgumentException ("index");
759 byte *b = (byte *)&ret;
761 for (int i = 0; i < 8; i++)
762 b [i] = data [index+i];
767 public override ulong GetUInt64 (byte [] data, int index)
770 throw new ArgumentNullException ("data");
771 if (data.Length - index < 8)
772 throw new ArgumentException ("index");
774 throw new ArgumentException ("index");
777 byte *b = (byte *)&ret;
779 for (int i = 0; i < 8; i++)
780 b [i] = data [index+i];
785 public override long GetInt64 (byte [] data, int index)
788 throw new ArgumentNullException ("data");
789 if (data.Length - index < 8)
790 throw new ArgumentException ("index");
792 throw new ArgumentException ("index");
795 byte *b = (byte *)&ret;
797 for (int i = 0; i < 8; i++)
798 b [i] = data [index+i];
803 public override float GetFloat (byte [] data, int index)
806 throw new ArgumentNullException ("data");
807 if (data.Length - index < 4)
808 throw new ArgumentException ("index");
810 throw new ArgumentException ("index");
813 byte *b = (byte *)&ret;
815 for (int i = 0; i < 4; i++)
816 b [i] = data [index+i];
821 public override int GetInt32 (byte [] data, int index)
824 throw new ArgumentNullException ("data");
825 if (data.Length - index < 4)
826 throw new ArgumentException ("index");
828 throw new ArgumentException ("index");
831 byte *b = (byte *)&ret;
833 for (int i = 0; i < 4; i++)
834 b [i] = data [index+i];
839 public override uint GetUInt32 (byte [] data, int index)
842 throw new ArgumentNullException ("data");
843 if (data.Length - index < 4)
844 throw new ArgumentException ("index");
846 throw new ArgumentException ("index");
849 byte *b = (byte *)&ret;
851 for (int i = 0; i < 4; i++)
852 b [i] = data [index+i];
857 public override short GetInt16 (byte [] data, int index)
860 throw new ArgumentNullException ("data");
861 if (data.Length - index < 2)
862 throw new ArgumentException ("index");
864 throw new ArgumentException ("index");
867 byte *b = (byte *)&ret;
869 for (int i = 0; i < 2; i++)
870 b [i] = data [index+i];
875 public override ushort GetUInt16 (byte [] data, int index)
878 throw new ArgumentNullException ("data");
879 if (data.Length - index < 2)
880 throw new ArgumentException ("index");
882 throw new ArgumentException ("index");
885 byte *b = (byte *)&ret;
887 for (int i = 0; i < 2; i++)
888 b [i] = data [index+i];
893 public override void PutBytes (byte [] dest, int destIdx, double value)
895 Check (dest, destIdx, 8);
896 fixed (byte *target = (&dest [destIdx])){
897 long *source = (long *) &value;
899 *((long *)target) = *source;
903 public override void PutBytes (byte [] dest, int destIdx, float value)
905 Check (dest, destIdx, 4);
906 fixed (byte *target = &dest [destIdx]){
907 uint *source = (uint *) &value;
909 *((uint *)target) = *source;
913 public override void PutBytes (byte [] dest, int destIdx, int 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, uint 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, long value)
935 Check (dest, destIdx, 8);
936 fixed (byte *target = &dest [destIdx]){
937 long *source = (long *) &value;
939 *((long*)target) = *source;
943 public override void PutBytes (byte [] dest, int destIdx, ulong value)
945 Check (dest, destIdx, 8);
946 fixed (byte *target = &dest [destIdx]){
947 ulong *source = (ulong *) &value;
949 *((ulong *) target) = *source;
953 public override void PutBytes (byte [] dest, int destIdx, short value)
955 Check (dest, destIdx, 2);
956 fixed (byte *target = &dest [destIdx]){
957 ushort *source = (ushort *) &value;
959 *((ushort *)target) = *source;
963 public override void PutBytes (byte [] dest, int destIdx, ushort value)
965 Check (dest, destIdx, 2);
966 fixed (byte *target = &dest [destIdx]){
967 ushort *source = (ushort *) &value;
969 *((ushort *)target) = *source;
974 class SwapConverter : DataConverter {
975 public override double GetDouble (byte [] data, int index)
978 throw new ArgumentNullException ("data");
979 if (data.Length - index < 8)
980 throw new ArgumentException ("index");
982 throw new ArgumentException ("index");
985 byte *b = (byte *)&ret;
987 for (int i = 0; i < 8; i++)
988 b [7-i] = data [index+i];
993 public override ulong GetUInt64 (byte [] data, int index)
996 throw new ArgumentNullException ("data");
997 if (data.Length - index < 8)
998 throw new ArgumentException ("index");
1000 throw new ArgumentException ("index");
1003 byte *b = (byte *)&ret;
1005 for (int i = 0; i < 8; i++)
1006 b [7-i] = data [index+i];
1011 public override long GetInt64 (byte [] data, int index)
1014 throw new ArgumentNullException ("data");
1015 if (data.Length - index < 8)
1016 throw new ArgumentException ("index");
1018 throw new ArgumentException ("index");
1021 byte *b = (byte *)&ret;
1023 for (int i = 0; i < 8; i++)
1024 b [7-i] = data [index+i];
1029 public override float GetFloat (byte [] data, int index)
1032 throw new ArgumentNullException ("data");
1033 if (data.Length - index < 4)
1034 throw new ArgumentException ("index");
1036 throw new ArgumentException ("index");
1039 byte *b = (byte *)&ret;
1041 for (int i = 0; i < 4; i++)
1042 b [3-i] = data [index+i];
1047 public override int GetInt32 (byte [] data, int index)
1050 throw new ArgumentNullException ("data");
1051 if (data.Length - index < 4)
1052 throw new ArgumentException ("index");
1054 throw new ArgumentException ("index");
1057 byte *b = (byte *)&ret;
1059 for (int i = 0; i < 4; i++)
1060 b [3-i] = data [index+i];
1065 public override uint GetUInt32 (byte [] data, int index)
1068 throw new ArgumentNullException ("data");
1069 if (data.Length - index < 4)
1070 throw new ArgumentException ("index");
1072 throw new ArgumentException ("index");
1075 byte *b = (byte *)&ret;
1077 for (int i = 0; i < 4; i++)
1078 b [3-i] = data [index+i];
1083 public override short GetInt16 (byte [] data, int index)
1086 throw new ArgumentNullException ("data");
1087 if (data.Length - index < 2)
1088 throw new ArgumentException ("index");
1090 throw new ArgumentException ("index");
1093 byte *b = (byte *)&ret;
1095 for (int i = 0; i < 2; i++)
1096 b [1-i] = data [index+i];
1101 public override ushort GetUInt16 (byte [] data, int index)
1104 throw new ArgumentNullException ("data");
1105 if (data.Length - index < 2)
1106 throw new ArgumentException ("index");
1108 throw new ArgumentException ("index");
1111 byte *b = (byte *)&ret;
1113 for (int i = 0; i < 2; i++)
1114 b [1-i] = data [index+i];
1119 public override void PutBytes (byte [] dest, int destIdx, double value)
1121 Check (dest, destIdx, 8);
1123 fixed (byte *target = &dest [destIdx]){
1124 byte *source = (byte *) &value;
1126 for (int i = 0; i < 8; i++)
1127 target [i] = source [7-i];
1131 public override void PutBytes (byte [] dest, int destIdx, float value)
1133 Check (dest, destIdx, 4);
1135 fixed (byte *target = &dest [destIdx]){
1136 byte *source = (byte *) &value;
1138 for (int i = 0; i < 4; i++)
1139 target [i] = source [3-i];
1143 public override void PutBytes (byte [] dest, int destIdx, int value)
1145 Check (dest, destIdx, 4);
1147 fixed (byte *target = &dest [destIdx]){
1148 byte *source = (byte *) &value;
1150 for (int i = 0; i < 4; i++)
1151 target [i] = source [3-i];
1155 public override void PutBytes (byte [] dest, int destIdx, uint value)
1157 Check (dest, destIdx, 4);
1159 fixed (byte *target = &dest [destIdx]){
1160 byte *source = (byte *) &value;
1162 for (int i = 0; i < 4; i++)
1163 target [i] = source [3-i];
1167 public override void PutBytes (byte [] dest, int destIdx, long value)
1169 Check (dest, destIdx, 8);
1171 fixed (byte *target = &dest [destIdx]){
1172 byte *source = (byte *) &value;
1174 for (int i = 0; i < 8; i++)
1175 target [i] = source [7-i];
1179 public override void PutBytes (byte [] dest, int destIdx, ulong value)
1181 Check (dest, destIdx, 8);
1183 fixed (byte *target = &dest [destIdx]){
1184 byte *source = (byte *) &value;
1186 for (int i = 0; i < 4; i++)
1187 target [i] = source [7-i];
1191 public override void PutBytes (byte [] dest, int destIdx, short value)
1193 Check (dest, destIdx, 2);
1195 fixed (byte *target = &dest [destIdx]){
1196 byte *source = (byte *) &value;
1198 for (int i = 0; i < 2; i++)
1199 target [i] = source [1-i];
1203 public override void PutBytes (byte [] dest, int destIdx, ushort value)
1205 Check (dest, destIdx, 2);
1207 fixed (byte *target = &dest [destIdx]){
1208 byte *source = (byte *) &value;
1210 for (int i = 0; i < 2; i++)
1211 target [i] = source [1-i];
1216 #if MONO_DATACONVERTER_STATIC_METHODS
1217 static unsafe void PutBytesLE (byte *dest, byte *src, int count)
1221 if (BitConverter.IsLittleEndian){
1222 for (; i < count; i++)
1225 for (; i < count; i++)
1226 dest [i-count] = *src++;
1230 static unsafe void PutBytesBE (byte *dest, byte *src, int count)
1234 if (BitConverter.IsLittleEndian){
1235 for (; i < count; i++)
1236 dest [i-count] = *src++;
1238 for (; i < count; i++)
1243 static unsafe void PutBytesNative (byte *dest, byte *src, int count)
1247 for (; i < count; i++)
1248 dest [i-count] = *src++;
1251 static public unsafe double DoubleFromLE (byte[] data, int index)
1254 throw new ArgumentNullException ("data");
1255 if (data.Length - index < 8)
1256 throw new ArgumentException ("index");
1258 throw new ArgumentException ("index");
1261 fixed (byte *src = &data[index]){
1262 PutBytesLE ((byte *) &ret, src, 8);
1267 static public unsafe float FloatFromLE (byte [] data, int index)
1270 throw new ArgumentNullException ("data");
1271 if (data.Length - index < 4)
1272 throw new ArgumentException ("index");
1274 throw new ArgumentException ("index");
1277 fixed (byte *src = &data[index]){
1278 PutBytesLE ((byte *) &ret, src, 4);
1283 static public unsafe long Int64FromLE (byte [] data, int index)
1286 throw new ArgumentNullException ("data");
1287 if (data.Length - index < 8)
1288 throw new ArgumentException ("index");
1290 throw new ArgumentException ("index");
1293 fixed (byte *src = &data[index]){
1294 PutBytesLE ((byte *) &ret, src, 8);
1299 static public unsafe ulong UInt64FromLE (byte [] data, int index)
1302 throw new ArgumentNullException ("data");
1303 if (data.Length - index < 8)
1304 throw new ArgumentException ("index");
1306 throw new ArgumentException ("index");
1309 fixed (byte *src = &data[index]){
1310 PutBytesLE ((byte *) &ret, src, 8);
1315 static public unsafe int Int32FromLE (byte [] data, int index)
1318 throw new ArgumentNullException ("data");
1319 if (data.Length - index < 4)
1320 throw new ArgumentException ("index");
1322 throw new ArgumentException ("index");
1325 fixed (byte *src = &data[index]){
1326 PutBytesLE ((byte *) &ret, src, 4);
1331 static public unsafe uint UInt32FromLE (byte [] data, int index)
1334 throw new ArgumentNullException ("data");
1335 if (data.Length - index < 4)
1336 throw new ArgumentException ("index");
1338 throw new ArgumentException ("index");
1341 fixed (byte *src = &data[index]){
1342 PutBytesLE ((byte *) &ret, src, 4);
1347 static public unsafe short Int16FromLE (byte [] data, int index)
1350 throw new ArgumentNullException ("data");
1351 if (data.Length - index < 2)
1352 throw new ArgumentException ("index");
1354 throw new ArgumentException ("index");
1357 fixed (byte *src = &data[index]){
1358 PutBytesLE ((byte *) &ret, src, 2);
1363 static public unsafe ushort UInt16FromLE (byte [] data, int index)
1366 throw new ArgumentNullException ("data");
1367 if (data.Length - index < 2)
1368 throw new ArgumentException ("index");
1370 throw new ArgumentException ("index");
1373 fixed (byte *src = &data[index]){
1374 PutBytesLE ((byte *) &ret, src, 2);
1379 static public unsafe double DoubleFromBE (byte[] data, int index)
1382 throw new ArgumentNullException ("data");
1383 if (data.Length - index < 8)
1384 throw new ArgumentException ("index");
1386 throw new ArgumentException ("index");
1389 fixed (byte *src = &data[index]){
1390 PutBytesBE ((byte *) &ret, src, 8);
1395 static public unsafe float FloatFromBE (byte [] data, int index)
1398 throw new ArgumentNullException ("data");
1399 if (data.Length - index < 4)
1400 throw new ArgumentException ("index");
1402 throw new ArgumentException ("index");
1405 fixed (byte *src = &data[index]){
1406 PutBytesBE ((byte *) &ret, src, 4);
1411 static public unsafe long Int64FromBE (byte [] data, int index)
1414 throw new ArgumentNullException ("data");
1415 if (data.Length - index < 8)
1416 throw new ArgumentException ("index");
1418 throw new ArgumentException ("index");
1421 fixed (byte *src = &data[index]){
1422 PutBytesBE ((byte *) &ret, src, 8);
1427 static public unsafe ulong UInt64FromBE (byte [] data, int index)
1430 throw new ArgumentNullException ("data");
1431 if (data.Length - index < 8)
1432 throw new ArgumentException ("index");
1434 throw new ArgumentException ("index");
1437 fixed (byte *src = &data[index]){
1438 PutBytesBE ((byte *) &ret, src, 8);
1443 static public unsafe int Int32FromBE (byte [] data, int index)
1446 throw new ArgumentNullException ("data");
1447 if (data.Length - index < 4)
1448 throw new ArgumentException ("index");
1450 throw new ArgumentException ("index");
1453 fixed (byte *src = &data[index]){
1454 PutBytesBE ((byte *) &ret, src, 4);
1459 static public unsafe uint UInt32FromBE (byte [] data, int index)
1462 throw new ArgumentNullException ("data");
1463 if (data.Length - index < 4)
1464 throw new ArgumentException ("index");
1466 throw new ArgumentException ("index");
1469 fixed (byte *src = &data[index]){
1470 PutBytesBE ((byte *) &ret, src, 4);
1475 static public unsafe short Int16FromBE (byte [] data, int index)
1478 throw new ArgumentNullException ("data");
1479 if (data.Length - index < 2)
1480 throw new ArgumentException ("index");
1482 throw new ArgumentException ("index");
1485 fixed (byte *src = &data[index]){
1486 PutBytesBE ((byte *) &ret, src, 2);
1491 static public unsafe ushort UInt16FromBE (byte [] data, int index)
1494 throw new ArgumentNullException ("data");
1495 if (data.Length - index < 2)
1496 throw new ArgumentException ("index");
1498 throw new ArgumentException ("index");
1501 fixed (byte *src = &data[index]){
1502 PutBytesBE ((byte *) &ret, src, 2);
1507 static public unsafe double DoubleFromNative (byte[] data, int index)
1510 throw new ArgumentNullException ("data");
1511 if (data.Length - index < 8)
1512 throw new ArgumentException ("index");
1514 throw new ArgumentException ("index");
1517 fixed (byte *src = &data[index]){
1518 PutBytesNative ((byte *) &ret, src, 8);
1523 static public unsafe float FloatFromNative (byte [] data, int index)
1526 throw new ArgumentNullException ("data");
1527 if (data.Length - index < 4)
1528 throw new ArgumentException ("index");
1530 throw new ArgumentException ("index");
1533 fixed (byte *src = &data[index]){
1534 PutBytesNative ((byte *) &ret, src, 4);
1539 static public unsafe long Int64FromNative (byte [] data, int index)
1542 throw new ArgumentNullException ("data");
1543 if (data.Length - index < 8)
1544 throw new ArgumentException ("index");
1546 throw new ArgumentException ("index");
1549 fixed (byte *src = &data[index]){
1550 PutBytesNative ((byte *) &ret, src, 8);
1555 static public unsafe ulong UInt64FromNative (byte [] data, int index)
1558 throw new ArgumentNullException ("data");
1559 if (data.Length - index < 8)
1560 throw new ArgumentException ("index");
1562 throw new ArgumentException ("index");
1565 fixed (byte *src = &data[index]){
1566 PutBytesNative ((byte *) &ret, src, 8);
1571 static public unsafe int Int32FromNative (byte [] data, int index)
1574 throw new ArgumentNullException ("data");
1575 if (data.Length - index < 4)
1576 throw new ArgumentException ("index");
1578 throw new ArgumentException ("index");
1581 fixed (byte *src = &data[index]){
1582 PutBytesNative ((byte *) &ret, src, 4);
1587 static public unsafe uint UInt32FromNative (byte [] data, int index)
1590 throw new ArgumentNullException ("data");
1591 if (data.Length - index < 4)
1592 throw new ArgumentException ("index");
1594 throw new ArgumentException ("index");
1597 fixed (byte *src = &data[index]){
1598 PutBytesNative ((byte *) &ret, src, 4);
1603 static public unsafe short Int16FromNative (byte [] data, int index)
1606 throw new ArgumentNullException ("data");
1607 if (data.Length - index < 2)
1608 throw new ArgumentException ("index");
1610 throw new ArgumentException ("index");
1613 fixed (byte *src = &data[index]){
1614 PutBytesNative ((byte *) &ret, src, 2);
1619 static public unsafe ushort UInt16FromNative (byte [] data, int index)
1622 throw new ArgumentNullException ("data");
1623 if (data.Length - index < 2)
1624 throw new ArgumentException ("index");
1626 throw new ArgumentException ("index");
1629 fixed (byte *src = &data[index]){
1630 PutBytesNative ((byte *) &ret, src, 2);
1635 unsafe static byte[] GetBytesPtr (byte *ptr, int count)
1637 byte [] ret = new byte [count];
1639 for (int i = 0; i < count; i++) {
1646 unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count)
1648 byte [] ret = new byte [count];
1652 for (int i = 0; i < count; i++) {
1653 ret [t-i] = ptr [i];
1656 for (int i = 0; i < count; i++) {
1663 unsafe public static byte[] GetBytesNative (bool value)
1665 return GetBytesPtr ((byte *) &value, 1);
1668 unsafe public static byte[] GetBytesNative (char value)
1670 return GetBytesPtr ((byte *) &value, 2);
1673 unsafe public static byte[] GetBytesNative (short value)
1675 return GetBytesPtr ((byte *) &value, 2);
1678 unsafe public static byte[] GetBytesNative (int value)
1680 return GetBytesPtr ((byte *) &value, 4);
1683 unsafe public static byte[] GetBytesNative (long value)
1685 return GetBytesPtr ((byte *) &value, 8);
1688 [CLSCompliant (false)]
1689 unsafe public static byte[] GetBytesNative (ushort value)
1691 return GetBytesPtr ((byte *) &value, 2);
1694 [CLSCompliant (false)]
1695 unsafe public static byte[] GetBytesNative (uint value)
1697 return GetBytesPtr ((byte *) &value, 4);
1700 [CLSCompliant (false)]
1701 unsafe public static byte[] GetBytesNative (ulong value)
1703 return GetBytesPtr ((byte *) &value, 8);
1706 unsafe public static byte[] GetBytesNative (float value)
1708 return GetBytesPtr ((byte *) &value, 4);
1711 unsafe public static byte[] GetBytesNative (double value)
1713 return GetBytesPtr ((byte *) &value, 8);
1716 unsafe public static byte[] GetBytesLE (bool value)
1718 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1);
1721 unsafe public static byte[] GetBytesLE (char value)
1723 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1726 unsafe public static byte[] GetBytesLE (short value)
1728 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1731 unsafe public static byte[] GetBytesLE (int value)
1733 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1736 unsafe public static byte[] GetBytesLE (long value)
1738 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1741 [CLSCompliant (false)]
1742 unsafe public static byte[] GetBytesLE (ushort value)
1744 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1747 [CLSCompliant (false)]
1748 unsafe public static byte[] GetBytesLE (uint value)
1750 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1753 [CLSCompliant (false)]
1754 unsafe public static byte[] GetBytesLE (ulong value)
1756 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1759 unsafe public static byte[] GetBytesLE (float value)
1761 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1764 unsafe public static byte[] GetBytesLE (double value)
1766 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1769 unsafe public static byte[] GetBytesBE (bool value)
1771 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1);
1774 unsafe public static byte[] GetBytesBE (char value)
1776 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1779 unsafe public static byte[] GetBytesBE (short value)
1781 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1784 unsafe public static byte[] GetBytesBE (int value)
1786 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1789 unsafe public static byte[] GetBytesBE (long value)
1791 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1794 [CLSCompliant (false)]
1795 unsafe public static byte[] GetBytesBE (ushort value)
1797 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1800 [CLSCompliant (false)]
1801 unsafe public static byte[] GetBytesBE (uint value)
1803 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1806 [CLSCompliant (false)]
1807 unsafe public static byte[] GetBytesBE (ulong value)
1809 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1812 unsafe public static byte[] GetBytesBE (float value)
1814 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1817 unsafe public static byte[] GetBytesBE (double value)
1819 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);