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 // Disables the warning: CLS compliance checking will not be performed on
51 // `XXXX' because it is not visible from outside this assembly
52 #pragma warning disable 3019
54 static DataConverter SwapConv = new SwapConverter ();
55 static DataConverter CopyConv = new CopyConverter ();
57 public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian;
59 public abstract double GetDouble (byte [] data, int index);
60 public abstract float GetFloat (byte [] data, int index);
61 public abstract long GetInt64 (byte [] data, int index);
62 public abstract int GetInt32 (byte [] data, int index);
64 public abstract short GetInt16 (byte [] data, int index);
66 [CLSCompliant (false)]
67 public abstract uint GetUInt32 (byte [] data, int index);
68 [CLSCompliant (false)]
69 public abstract ushort GetUInt16 (byte [] data, int index);
70 [CLSCompliant (false)]
71 public abstract ulong GetUInt64 (byte [] data, int index);
73 public abstract void PutBytes (byte [] dest, int destIdx, double value);
74 public abstract void PutBytes (byte [] dest, int destIdx, float value);
75 public abstract void PutBytes (byte [] dest, int destIdx, int value);
76 public abstract void PutBytes (byte [] dest, int destIdx, long value);
77 public abstract void PutBytes (byte [] dest, int destIdx, short value);
79 [CLSCompliant (false)]
80 public abstract void PutBytes (byte [] dest, int destIdx, ushort value);
81 [CLSCompliant (false)]
82 public abstract void PutBytes (byte [] dest, int destIdx, uint value);
83 [CLSCompliant (false)]
84 public abstract void PutBytes (byte [] dest, int destIdx, ulong value);
86 public byte[] GetBytes (double value)
88 byte [] ret = new byte [8];
89 PutBytes (ret, 0, value);
93 public byte[] GetBytes (float value)
95 byte [] ret = new byte [4];
96 PutBytes (ret, 0, value);
100 public byte[] GetBytes (int value)
102 byte [] ret = new byte [4];
103 PutBytes (ret, 0, value);
107 public byte[] GetBytes (long value)
109 byte [] ret = new byte [8];
110 PutBytes (ret, 0, value);
114 public byte[] GetBytes (short value)
116 byte [] ret = new byte [2];
117 PutBytes (ret, 0, value);
121 [CLSCompliant (false)]
122 public byte[] GetBytes (ushort value)
124 byte [] ret = new byte [2];
125 PutBytes (ret, 0, value);
129 [CLSCompliant (false)]
130 public byte[] GetBytes (uint value)
132 byte [] ret = new byte [4];
133 PutBytes (ret, 0, value);
137 [CLSCompliant (false)]
138 public byte[] GetBytes (ulong value)
140 byte [] ret = new byte [8];
141 PutBytes (ret, 0, value);
145 static public DataConverter LittleEndian {
147 return BitConverter.IsLittleEndian ? CopyConv : SwapConv;
151 static public DataConverter BigEndian {
153 return BitConverter.IsLittleEndian ? SwapConv : CopyConv;
157 static public DataConverter Native {
163 static int Align (int current, int align)
165 return ((current + align - 1) / align) * align;
170 public byte [] buffer;
173 public string description;
174 public int i; // position in the description
175 public DataConverter conv;
179 // if align == -1, auto align to the size of the byte array
180 // if align == 0, do not do alignment
181 // Any other values aligns to that particular size
185 public void Add (byte [] group)
187 //Console.WriteLine ("Adding {0} bytes to {1} (next={2}", group.Length,
188 // buffer == null ? "null" : buffer.Length.ToString (), next);
197 next = Align (next, group.Length);
199 next = Align (next, align);
203 if (next + group.Length > buffer.Length){
204 byte [] nb = new byte [System.Math.Max (next, 16) * 2 + group.Length];
205 Array.Copy (buffer, nb, buffer.Length);
206 Array.Copy (group, 0, nb, next, group.Length);
207 next = next + group.Length;
210 Array.Copy (group, 0, buffer, next, group.Length);
211 next += group.Length;
215 public byte [] Get ()
220 if (buffer.Length != next){
221 byte [] b = new byte [next];
222 Array.Copy (buffer, b, next);
232 // ^ Switch to big endian encoding
233 // _ Switch to little endian encoding
234 // % Switch to host (native) encoding
235 // ! aligns the next data type to its natural boundary (for strings this is 4).
247 // z8 string encoded as UTF8 with 1-byte null terminator
248 // z6 string encoded as UTF16 with 2-byte null terminator
249 // z7 string encoded as UTF7 with 1-byte null terminator
250 // zb string encoded as BigEndianUnicode with 2-byte null terminator
251 // z3 string encoded as UTF32 with 4-byte null terminator
252 // z4 string encoded as UTF32 big endian with 4-byte null terminator
253 // $8 string encoded as UTF8
254 // $6 string encoded as UTF16
255 // $7 string encoded as UTF7
256 // $b string encoded as BigEndianUnicode
257 // $3 string encoded as UTF32
258 // $4 string encoded as UTF-32 big endian encoding
261 // Repeats, these are prefixes:
262 // N a number between 1 and 9, indicates a repeat count (process N items
263 // with the following datatype
264 // [N] For numbers larger than 9, use brackets, for example [20]
265 // * Repeat the next data type until the arguments are exhausted
267 static public byte [] Pack (string description, params object [] args)
270 PackContext b = new PackContext ();
272 b.description = description;
274 for (b.i = 0; b.i < description.Length; ){
277 if (argn < args.Length)
288 if (PackOne (b, oarg)){
303 static public byte [] PackEnumerable (string description, IEnumerable args)
305 PackContext b = new PackContext ();
307 b.description = description;
309 IEnumerator enumerator = args.GetEnumerator ();
310 bool ok = enumerator.MoveNext ();
312 for (b.i = 0; b.i < description.Length; b.i++){
316 oarg = enumerator.Current;
325 if (PackOne (b, oarg)){
326 ok = enumerator.MoveNext ();
341 // Packs one datum `oarg' into the buffer `b', using the string format
342 // in `description' at position `i'
344 // Returns: true if we must pick the next object from the list
346 static bool PackOne (PackContext b, object oarg)
350 switch (b.description [b.i]){
355 b.conv = LittleEndian;
366 b.Add (new byte [] { 0 });
371 b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg)));
375 b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg)));
379 b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg)));
383 b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg)));
387 b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg)));
391 b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg)));
395 b.Add (b.conv.GetBytes (Convert.ToSingle (oarg)));
399 b.Add (b.conv.GetBytes (Convert.ToDouble (oarg)));
403 b.Add (new byte [] { Convert.ToByte (oarg) });
407 b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) });
411 b.Add (new byte [] { Convert.ToByte (oarg) });
415 case '1': case '2': case '3': case '4': case '5':
416 case '6': case '7': case '8': case '9':
417 b.repeat = ((short) b.description [b.i]) - ((short) '0');
421 b.repeat = Int32.MaxValue;
427 for (j = b.i+1; j < b.description.Length; j++){
428 if (b.description [j] == ']')
430 n = ((short) b.description [j]) - ((short) '0');
431 if (n >= 0 && n <= 9){
435 count = count * 10 + n;
439 throw new ArgumentException ("invalid size specification");
445 bool add_null = b.description [b.i] == 'z';
447 if (b.i >= b.description.Length)
448 throw new ArgumentException ("$ description needs a type specified", "description");
449 char d = b.description [b.i];
458 e = Encoding.Unicode;
466 e = Encoding.BigEndianUnicode;
470 e = Encoding.GetEncoding (12000);
474 e = Encoding.GetEncoding (12001);
479 throw new ArgumentException ("Invalid format for $ specifier", "description");
482 b.Add (e.GetBytes (Convert.ToString (oarg)));
484 b.Add (new byte [n]);
487 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
488 b.description [b.i]));
493 static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
496 idx = Align (idx, size);
499 if (idx + size >= buffer.Length){
506 static public IList Unpack (string description, byte [] buffer, int startIndex)
508 DataConverter conv = CopyConv;
509 ArrayList result = new ArrayList ();
510 int idx = startIndex;
514 for (int i = 0; i < description.Length && idx < buffer.Length; ){
517 switch (description [i]){
537 if (Prepare (buffer, ref idx, 4, ref align)){
538 result.Add (conv.GetInt32 (buffer, idx));
544 if (Prepare (buffer, ref idx, 4, ref align)){
545 result.Add (conv.GetUInt32 (buffer, idx));
551 if (Prepare (buffer, ref idx, 2, ref align)){
552 result.Add (conv.GetInt16 (buffer, idx));
558 if (Prepare (buffer, ref idx, 2, ref align)){
559 result.Add (conv.GetUInt16 (buffer, idx));
565 if (Prepare (buffer, ref idx, 8, ref align)){
566 result.Add (conv.GetInt64 (buffer, idx));
572 if (Prepare (buffer, ref idx, 8, ref align)){
573 result.Add (conv.GetUInt64 (buffer, idx));
579 if (Prepare (buffer, ref idx, 4, ref align)){
580 result.Add (conv.GetDouble (buffer, idx));
586 if (Prepare (buffer, ref idx, 8, ref align)){
587 result.Add (conv.GetDouble (buffer, idx));
593 if (Prepare (buffer, ref idx, 1, ref align)){
594 result.Add (buffer [idx]);
600 if (Prepare (buffer, ref idx, 1, ref align)){
603 if (description [i] == 'c')
604 c = ((char) ((sbyte)buffer [idx]));
606 c = ((char) ((byte)buffer [idx]));
614 case '1': case '2': case '3': case '4': case '5':
615 case '6': case '7': case '8': case '9':
616 repeat = ((short) description [i]) - ((short) '0');
620 repeat = Int32.MaxValue;
626 for (j = i+1; j < description.Length; j++){
627 if (description [j] == ']')
629 n = ((short) description [j]) - ((short) '0');
630 if (n >= 0 && n <= 9){
634 count = count * 10 + n;
638 throw new ArgumentException ("invalid size specification");
644 // bool with_null = description [i] == 'z';
646 if (i >= description.Length)
647 throw new ArgumentException ("$ description needs a type specified", "description");
648 char d = description [i];
651 idx = Align (idx, 4);
654 if (idx >= buffer.Length)
663 e = Encoding.Unicode;
671 e = Encoding.BigEndianUnicode;
675 e = Encoding.GetEncoding (12000);
679 e = Encoding.GetEncoding (12001);
684 throw new ArgumentException ("Invalid format for $ specifier", "description");
689 for (; k < buffer.Length && buffer [k] != 0; k++)
691 result.Add (e.GetChars (buffer, idx, k-idx));
692 if (k == buffer.Length)
699 for (; k < buffer.Length; k++){
700 if (k+1 == buffer.Length){
704 if (buffer [k] == 0 && buffer [k+1] == 0)
707 result.Add (e.GetChars (buffer, idx, k-idx));
708 if (k == buffer.Length)
715 for (; k < buffer.Length; k++){
716 if (k+3 >= buffer.Length){
720 if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
723 result.Add (e.GetChars (buffer, idx, k-idx));
724 if (k == buffer.Length)
732 throw new ArgumentException (String.Format ("invalid format specified `{0}'",
745 internal void Check (byte [] dest, int destIdx, int size)
748 throw new ArgumentNullException ("dest");
749 if (destIdx < 0 || destIdx > dest.Length - size)
750 throw new ArgumentException ("destIdx");
753 class CopyConverter : DataConverter {
754 public override double GetDouble (byte [] data, int index)
757 throw new ArgumentNullException ("data");
758 if (data.Length - index < 8)
759 throw new ArgumentException ("index");
761 throw new ArgumentException ("index");
763 byte *b = (byte *)&ret;
765 for (int i = 0; i < 8; i++)
766 b [i] = data [index+i];
771 public override ulong GetUInt64 (byte [] data, int index)
774 throw new ArgumentNullException ("data");
775 if (data.Length - index < 8)
776 throw new ArgumentException ("index");
778 throw new ArgumentException ("index");
781 byte *b = (byte *)&ret;
783 for (int i = 0; i < 8; i++)
784 b [i] = data [index+i];
789 public override long GetInt64 (byte [] data, int index)
792 throw new ArgumentNullException ("data");
793 if (data.Length - index < 8)
794 throw new ArgumentException ("index");
796 throw new ArgumentException ("index");
799 byte *b = (byte *)&ret;
801 for (int i = 0; i < 8; i++)
802 b [i] = data [index+i];
807 public override float GetFloat (byte [] data, int index)
810 throw new ArgumentNullException ("data");
811 if (data.Length - index < 4)
812 throw new ArgumentException ("index");
814 throw new ArgumentException ("index");
817 byte *b = (byte *)&ret;
819 for (int i = 0; i < 4; i++)
820 b [i] = data [index+i];
825 public override int GetInt32 (byte [] data, int index)
828 throw new ArgumentNullException ("data");
829 if (data.Length - index < 4)
830 throw new ArgumentException ("index");
832 throw new ArgumentException ("index");
835 byte *b = (byte *)&ret;
837 for (int i = 0; i < 4; i++)
838 b [i] = data [index+i];
843 public override uint GetUInt32 (byte [] data, int index)
846 throw new ArgumentNullException ("data");
847 if (data.Length - index < 4)
848 throw new ArgumentException ("index");
850 throw new ArgumentException ("index");
853 byte *b = (byte *)&ret;
855 for (int i = 0; i < 4; i++)
856 b [i] = data [index+i];
861 public override short GetInt16 (byte [] data, int index)
864 throw new ArgumentNullException ("data");
865 if (data.Length - index < 2)
866 throw new ArgumentException ("index");
868 throw new ArgumentException ("index");
871 byte *b = (byte *)&ret;
873 for (int i = 0; i < 2; i++)
874 b [i] = data [index+i];
879 public override ushort GetUInt16 (byte [] data, int index)
882 throw new ArgumentNullException ("data");
883 if (data.Length - index < 2)
884 throw new ArgumentException ("index");
886 throw new ArgumentException ("index");
889 byte *b = (byte *)&ret;
891 for (int i = 0; i < 2; i++)
892 b [i] = data [index+i];
897 public override void PutBytes (byte [] dest, int destIdx, double value)
899 Check (dest, destIdx, 8);
900 fixed (byte *target = &dest [destIdx]){
901 long *source = (long *) &value;
903 *((long *)target) = *source;
907 public override void PutBytes (byte [] dest, int destIdx, float value)
909 Check (dest, destIdx, 4);
910 fixed (byte *target = &dest [destIdx]){
911 uint *source = (uint *) &value;
913 *((uint *)target) = *source;
917 public override void PutBytes (byte [] dest, int destIdx, int value)
919 Check (dest, destIdx, 4);
920 fixed (byte *target = &dest [destIdx]){
921 uint *source = (uint *) &value;
923 *((uint *)target) = *source;
927 public override void PutBytes (byte [] dest, int destIdx, uint value)
929 Check (dest, destIdx, 4);
930 fixed (byte *target = &dest [destIdx]){
931 uint *source = (uint *) &value;
933 *((uint *)target) = *source;
937 public override void PutBytes (byte [] dest, int destIdx, long value)
939 Check (dest, destIdx, 8);
940 fixed (byte *target = &dest [destIdx]){
941 long *source = (long *) &value;
943 *((long*)target) = *source;
947 public override void PutBytes (byte [] dest, int destIdx, ulong value)
949 Check (dest, destIdx, 8);
950 fixed (byte *target = &dest [destIdx]){
951 ulong *source = (ulong *) &value;
953 *((ulong *) target) = *source;
957 public override void PutBytes (byte [] dest, int destIdx, short value)
959 Check (dest, destIdx, 2);
960 fixed (byte *target = &dest [destIdx]){
961 ushort *source = (ushort *) &value;
963 *((ushort *)target) = *source;
967 public override void PutBytes (byte [] dest, int destIdx, ushort value)
969 Check (dest, destIdx, 2);
970 fixed (byte *target = &dest [destIdx]){
971 ushort *source = (ushort *) &value;
973 *((ushort *)target) = *source;
978 class SwapConverter : DataConverter {
979 public override double GetDouble (byte [] data, int index)
982 throw new ArgumentNullException ("data");
983 if (data.Length - index < 8)
984 throw new ArgumentException ("index");
986 throw new ArgumentException ("index");
989 byte *b = (byte *)&ret;
991 for (int i = 0; i < 8; i++)
992 b [7-i] = data [index+i];
997 public override ulong GetUInt64 (byte [] data, int index)
1000 throw new ArgumentNullException ("data");
1001 if (data.Length - index < 8)
1002 throw new ArgumentException ("index");
1004 throw new ArgumentException ("index");
1007 byte *b = (byte *)&ret;
1009 for (int i = 0; i < 8; i++)
1010 b [7-i] = data [index+i];
1015 public override long GetInt64 (byte [] data, int index)
1018 throw new ArgumentNullException ("data");
1019 if (data.Length - index < 8)
1020 throw new ArgumentException ("index");
1022 throw new ArgumentException ("index");
1025 byte *b = (byte *)&ret;
1027 for (int i = 0; i < 8; i++)
1028 b [7-i] = data [index+i];
1033 public override float GetFloat (byte [] data, int index)
1036 throw new ArgumentNullException ("data");
1037 if (data.Length - index < 4)
1038 throw new ArgumentException ("index");
1040 throw new ArgumentException ("index");
1043 byte *b = (byte *)&ret;
1045 for (int i = 0; i < 4; i++)
1046 b [3-i] = data [index+i];
1051 public override int GetInt32 (byte [] data, int index)
1054 throw new ArgumentNullException ("data");
1055 if (data.Length - index < 4)
1056 throw new ArgumentException ("index");
1058 throw new ArgumentException ("index");
1061 byte *b = (byte *)&ret;
1063 for (int i = 0; i < 4; i++)
1064 b [3-i] = data [index+i];
1069 public override uint GetUInt32 (byte [] data, int index)
1072 throw new ArgumentNullException ("data");
1073 if (data.Length - index < 4)
1074 throw new ArgumentException ("index");
1076 throw new ArgumentException ("index");
1079 byte *b = (byte *)&ret;
1081 for (int i = 0; i < 4; i++)
1082 b [3-i] = data [index+i];
1087 public override short GetInt16 (byte [] data, int index)
1090 throw new ArgumentNullException ("data");
1091 if (data.Length - index < 2)
1092 throw new ArgumentException ("index");
1094 throw new ArgumentException ("index");
1097 byte *b = (byte *)&ret;
1099 for (int i = 0; i < 2; i++)
1100 b [1-i] = data [index+i];
1105 public override ushort GetUInt16 (byte [] data, int index)
1108 throw new ArgumentNullException ("data");
1109 if (data.Length - index < 2)
1110 throw new ArgumentException ("index");
1112 throw new ArgumentException ("index");
1115 byte *b = (byte *)&ret;
1117 for (int i = 0; i < 2; i++)
1118 b [1-i] = data [index+i];
1123 public override void PutBytes (byte [] dest, int destIdx, double value)
1125 Check (dest, destIdx, 8);
1127 fixed (byte *target = &dest [destIdx]){
1128 byte *source = (byte *) &value;
1130 for (int i = 0; i < 8; i++)
1131 target [i] = source [7-i];
1135 public override void PutBytes (byte [] dest, int destIdx, float value)
1137 Check (dest, destIdx, 4);
1139 fixed (byte *target = &dest [destIdx]){
1140 byte *source = (byte *) &value;
1142 for (int i = 0; i < 4; i++)
1143 target [i] = source [3-i];
1147 public override void PutBytes (byte [] dest, int destIdx, int value)
1149 Check (dest, destIdx, 4);
1151 fixed (byte *target = &dest [destIdx]){
1152 byte *source = (byte *) &value;
1154 for (int i = 0; i < 4; i++)
1155 target [i] = source [3-i];
1159 public override void PutBytes (byte [] dest, int destIdx, uint value)
1161 Check (dest, destIdx, 4);
1163 fixed (byte *target = &dest [destIdx]){
1164 byte *source = (byte *) &value;
1166 for (int i = 0; i < 4; i++)
1167 target [i] = source [3-i];
1171 public override void PutBytes (byte [] dest, int destIdx, long value)
1173 Check (dest, destIdx, 8);
1175 fixed (byte *target = &dest [destIdx]){
1176 byte *source = (byte *) &value;
1178 for (int i = 0; i < 8; i++)
1179 target [i] = source [7-i];
1183 public override void PutBytes (byte [] dest, int destIdx, ulong value)
1185 Check (dest, destIdx, 8);
1187 fixed (byte *target = &dest [destIdx]){
1188 byte *source = (byte *) &value;
1190 for (int i = 0; i < 4; i++)
1191 target [i] = source [7-i];
1195 public override void PutBytes (byte [] dest, int destIdx, short value)
1197 Check (dest, destIdx, 2);
1199 fixed (byte *target = &dest [destIdx]){
1200 byte *source = (byte *) &value;
1202 for (int i = 0; i < 2; i++)
1203 target [i] = source [1-i];
1207 public override void PutBytes (byte [] dest, int destIdx, ushort value)
1209 Check (dest, destIdx, 2);
1211 fixed (byte *target = &dest [destIdx]){
1212 byte *source = (byte *) &value;
1214 for (int i = 0; i < 2; i++)
1215 target [i] = source [1-i];
1220 #if MONO_DATACONVERTER_STATIC_METHODS
1221 static unsafe void PutBytesLE (byte *dest, byte *src, int count)
1225 if (BitConverter.IsLittleEndian){
1226 for (; i < count; i++)
1230 for (; i < count; i++)
1235 static unsafe void PutBytesBE (byte *dest, byte *src, int count)
1239 if (BitConverter.IsLittleEndian){
1241 for (; i < count; i++)
1244 for (; i < count; i++)
1249 static unsafe void PutBytesNative (byte *dest, byte *src, int count)
1253 for (; i < count; i++)
1254 dest [i-count] = *src++;
1257 static public unsafe double DoubleFromLE (byte[] data, int index)
1260 throw new ArgumentNullException ("data");
1261 if (data.Length - index < 8)
1262 throw new ArgumentException ("index");
1264 throw new ArgumentException ("index");
1267 fixed (byte *src = &data[index]){
1268 PutBytesLE ((byte *) &ret, src, 8);
1273 static public unsafe float FloatFromLE (byte [] data, int index)
1276 throw new ArgumentNullException ("data");
1277 if (data.Length - index < 4)
1278 throw new ArgumentException ("index");
1280 throw new ArgumentException ("index");
1283 fixed (byte *src = &data[index]){
1284 PutBytesLE ((byte *) &ret, src, 4);
1289 static public unsafe long Int64FromLE (byte [] data, int index)
1292 throw new ArgumentNullException ("data");
1293 if (data.Length - index < 8)
1294 throw new ArgumentException ("index");
1296 throw new ArgumentException ("index");
1299 fixed (byte *src = &data[index]){
1300 PutBytesLE ((byte *) &ret, src, 8);
1305 static public unsafe ulong UInt64FromLE (byte [] data, int index)
1308 throw new ArgumentNullException ("data");
1309 if (data.Length - index < 8)
1310 throw new ArgumentException ("index");
1312 throw new ArgumentException ("index");
1315 fixed (byte *src = &data[index]){
1316 PutBytesLE ((byte *) &ret, src, 8);
1321 static public unsafe int Int32FromLE (byte [] data, int index)
1324 throw new ArgumentNullException ("data");
1325 if (data.Length - index < 4)
1326 throw new ArgumentException ("index");
1328 throw new ArgumentException ("index");
1331 fixed (byte *src = &data[index]){
1332 PutBytesLE ((byte *) &ret, src, 4);
1337 static public unsafe uint UInt32FromLE (byte [] data, int index)
1340 throw new ArgumentNullException ("data");
1341 if (data.Length - index < 4)
1342 throw new ArgumentException ("index");
1344 throw new ArgumentException ("index");
1347 fixed (byte *src = &data[index]){
1348 PutBytesLE ((byte *) &ret, src, 4);
1353 static public unsafe short Int16FromLE (byte [] data, int index)
1356 throw new ArgumentNullException ("data");
1357 if (data.Length - index < 2)
1358 throw new ArgumentException ("index");
1360 throw new ArgumentException ("index");
1363 fixed (byte *src = &data[index]){
1364 PutBytesLE ((byte *) &ret, src, 2);
1369 static public unsafe ushort UInt16FromLE (byte [] data, int index)
1372 throw new ArgumentNullException ("data");
1373 if (data.Length - index < 2)
1374 throw new ArgumentException ("index");
1376 throw new ArgumentException ("index");
1379 fixed (byte *src = &data[index]){
1380 PutBytesLE ((byte *) &ret, src, 2);
1385 static public unsafe double DoubleFromBE (byte[] data, int index)
1388 throw new ArgumentNullException ("data");
1389 if (data.Length - index < 8)
1390 throw new ArgumentException ("index");
1392 throw new ArgumentException ("index");
1395 fixed (byte *src = &data[index]){
1396 PutBytesBE ((byte *) &ret, src, 8);
1401 static public unsafe float FloatFromBE (byte [] data, int index)
1404 throw new ArgumentNullException ("data");
1405 if (data.Length - index < 4)
1406 throw new ArgumentException ("index");
1408 throw new ArgumentException ("index");
1411 fixed (byte *src = &data[index]){
1412 PutBytesBE ((byte *) &ret, src, 4);
1417 static public unsafe long Int64FromBE (byte [] data, int index)
1420 throw new ArgumentNullException ("data");
1421 if (data.Length - index < 8)
1422 throw new ArgumentException ("index");
1424 throw new ArgumentException ("index");
1427 fixed (byte *src = &data[index]){
1428 PutBytesBE ((byte *) &ret, src, 8);
1433 static public unsafe ulong UInt64FromBE (byte [] data, int index)
1436 throw new ArgumentNullException ("data");
1437 if (data.Length - index < 8)
1438 throw new ArgumentException ("index");
1440 throw new ArgumentException ("index");
1443 fixed (byte *src = &data[index]){
1444 PutBytesBE ((byte *) &ret, src, 8);
1449 static public unsafe int Int32FromBE (byte [] data, int index)
1452 throw new ArgumentNullException ("data");
1453 if (data.Length - index < 4)
1454 throw new ArgumentException ("index");
1456 throw new ArgumentException ("index");
1459 fixed (byte *src = &data[index]){
1460 PutBytesBE ((byte *) &ret, src, 4);
1465 static public unsafe uint UInt32FromBE (byte [] data, int index)
1468 throw new ArgumentNullException ("data");
1469 if (data.Length - index < 4)
1470 throw new ArgumentException ("index");
1472 throw new ArgumentException ("index");
1475 fixed (byte *src = &data[index]){
1476 PutBytesBE ((byte *) &ret, src, 4);
1481 static public unsafe short Int16FromBE (byte [] data, int index)
1484 throw new ArgumentNullException ("data");
1485 if (data.Length - index < 2)
1486 throw new ArgumentException ("index");
1488 throw new ArgumentException ("index");
1491 fixed (byte *src = &data[index]){
1492 PutBytesBE ((byte *) &ret, src, 2);
1497 static public unsafe ushort UInt16FromBE (byte [] data, int index)
1500 throw new ArgumentNullException ("data");
1501 if (data.Length - index < 2)
1502 throw new ArgumentException ("index");
1504 throw new ArgumentException ("index");
1507 fixed (byte *src = &data[index]){
1508 PutBytesBE ((byte *) &ret, src, 2);
1513 static public unsafe double DoubleFromNative (byte[] data, int index)
1516 throw new ArgumentNullException ("data");
1517 if (data.Length - index < 8)
1518 throw new ArgumentException ("index");
1520 throw new ArgumentException ("index");
1523 fixed (byte *src = &data[index]){
1524 PutBytesNative ((byte *) &ret, src, 8);
1529 static public unsafe float FloatFromNative (byte [] data, int index)
1532 throw new ArgumentNullException ("data");
1533 if (data.Length - index < 4)
1534 throw new ArgumentException ("index");
1536 throw new ArgumentException ("index");
1539 fixed (byte *src = &data[index]){
1540 PutBytesNative ((byte *) &ret, src, 4);
1545 static public unsafe long Int64FromNative (byte [] data, int index)
1548 throw new ArgumentNullException ("data");
1549 if (data.Length - index < 8)
1550 throw new ArgumentException ("index");
1552 throw new ArgumentException ("index");
1555 fixed (byte *src = &data[index]){
1556 PutBytesNative ((byte *) &ret, src, 8);
1561 static public unsafe ulong UInt64FromNative (byte [] data, int index)
1564 throw new ArgumentNullException ("data");
1565 if (data.Length - index < 8)
1566 throw new ArgumentException ("index");
1568 throw new ArgumentException ("index");
1571 fixed (byte *src = &data[index]){
1572 PutBytesNative ((byte *) &ret, src, 8);
1577 static public unsafe int Int32FromNative (byte [] data, int index)
1580 throw new ArgumentNullException ("data");
1581 if (data.Length - index < 4)
1582 throw new ArgumentException ("index");
1584 throw new ArgumentException ("index");
1587 fixed (byte *src = &data[index]){
1588 PutBytesNative ((byte *) &ret, src, 4);
1593 static public unsafe uint UInt32FromNative (byte [] data, int index)
1596 throw new ArgumentNullException ("data");
1597 if (data.Length - index < 4)
1598 throw new ArgumentException ("index");
1600 throw new ArgumentException ("index");
1603 fixed (byte *src = &data[index]){
1604 PutBytesNative ((byte *) &ret, src, 4);
1609 static public unsafe short Int16FromNative (byte [] data, int index)
1612 throw new ArgumentNullException ("data");
1613 if (data.Length - index < 2)
1614 throw new ArgumentException ("index");
1616 throw new ArgumentException ("index");
1619 fixed (byte *src = &data[index]){
1620 PutBytesNative ((byte *) &ret, src, 2);
1625 static public unsafe ushort UInt16FromNative (byte [] data, int index)
1628 throw new ArgumentNullException ("data");
1629 if (data.Length - index < 2)
1630 throw new ArgumentException ("index");
1632 throw new ArgumentException ("index");
1635 fixed (byte *src = &data[index]){
1636 PutBytesNative ((byte *) &ret, src, 2);
1641 unsafe static byte[] GetBytesPtr (byte *ptr, int count)
1643 byte [] ret = new byte [count];
1645 for (int i = 0; i < count; i++) {
1652 unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count)
1654 byte [] ret = new byte [count];
1658 for (int i = 0; i < count; i++) {
1659 ret [t-i] = ptr [i];
1662 for (int i = 0; i < count; i++) {
1669 unsafe public static byte[] GetBytesNative (bool value)
1671 return GetBytesPtr ((byte *) &value, 1);
1674 unsafe public static byte[] GetBytesNative (char value)
1676 return GetBytesPtr ((byte *) &value, 2);
1679 unsafe public static byte[] GetBytesNative (short value)
1681 return GetBytesPtr ((byte *) &value, 2);
1684 unsafe public static byte[] GetBytesNative (int value)
1686 return GetBytesPtr ((byte *) &value, 4);
1689 unsafe public static byte[] GetBytesNative (long value)
1691 return GetBytesPtr ((byte *) &value, 8);
1694 [CLSCompliant (false)]
1695 unsafe public static byte[] GetBytesNative (ushort value)
1697 return GetBytesPtr ((byte *) &value, 2);
1700 [CLSCompliant (false)]
1701 unsafe public static byte[] GetBytesNative (uint value)
1703 return GetBytesPtr ((byte *) &value, 4);
1706 [CLSCompliant (false)]
1707 unsafe public static byte[] GetBytesNative (ulong value)
1709 return GetBytesPtr ((byte *) &value, 8);
1712 unsafe public static byte[] GetBytesNative (float value)
1714 return GetBytesPtr ((byte *) &value, 4);
1717 unsafe public static byte[] GetBytesNative (double value)
1719 return GetBytesPtr ((byte *) &value, 8);
1722 unsafe public static byte[] GetBytesLE (bool value)
1724 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1);
1727 unsafe public static byte[] GetBytesLE (char value)
1729 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1732 unsafe public static byte[] GetBytesLE (short value)
1734 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1737 unsafe public static byte[] GetBytesLE (int value)
1739 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1742 unsafe public static byte[] GetBytesLE (long value)
1744 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1747 [CLSCompliant (false)]
1748 unsafe public static byte[] GetBytesLE (ushort value)
1750 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
1753 [CLSCompliant (false)]
1754 unsafe public static byte[] GetBytesLE (uint value)
1756 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1759 [CLSCompliant (false)]
1760 unsafe public static byte[] GetBytesLE (ulong value)
1762 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1765 unsafe public static byte[] GetBytesLE (float value)
1767 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
1770 unsafe public static byte[] GetBytesLE (double value)
1772 return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
1775 unsafe public static byte[] GetBytesBE (bool value)
1777 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1);
1780 unsafe public static byte[] GetBytesBE (char value)
1782 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1785 unsafe public static byte[] GetBytesBE (short value)
1787 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1790 unsafe public static byte[] GetBytesBE (int value)
1792 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1795 unsafe public static byte[] GetBytesBE (long value)
1797 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1800 [CLSCompliant (false)]
1801 unsafe public static byte[] GetBytesBE (ushort value)
1803 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
1806 [CLSCompliant (false)]
1807 unsafe public static byte[] GetBytesBE (uint value)
1809 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1812 [CLSCompliant (false)]
1813 unsafe public static byte[] GetBytesBE (ulong value)
1815 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
1818 unsafe public static byte[] GetBytesBE (float value)
1820 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
1823 unsafe public static byte[] GetBytesBE (double value)
1825 return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);