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);