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");
651 // bool with_null = description [i] == 'z';
653 if (i
>= description
.Length
)
654 throw new ArgumentException ("$ description needs a type specified", "description");
655 char d
= description
[i
];
658 idx
= Align (idx
, 4);
661 if (idx
>= buffer
.Length
)
670 e
= Encoding
.Unicode
;
678 e
= Encoding
.BigEndianUnicode
;
682 e
= Encoding
.GetEncoding (12000);
686 e
= Encoding
.GetEncoding (12001);
691 throw new ArgumentException ("Invalid format for $ specifier", "description");
696 for (; k
< buffer
.Length
&& buffer
[k
] != 0; k
++)
698 result
.Add (e
.GetChars (buffer
, idx
, k
-idx
));
699 if (k
== buffer
.Length
)
706 for (; k
< buffer
.Length
; k
++){
707 if (k
+1 == buffer
.Length
){
711 if (buffer
[k
] == 0 && buffer
[k
+1] == 0)
714 result
.Add (e
.GetChars (buffer
, idx
, k
-idx
));
715 if (k
== buffer
.Length
)
722 for (; k
< buffer
.Length
; k
++){
723 if (k
+3 >= buffer
.Length
){
727 if (buffer
[k
]==0 && buffer
[k
+1] == 0 && buffer
[k
+2] == 0 && buffer
[k
+3]== 0)
730 result
.Add (e
.GetChars (buffer
, idx
, k
-idx
));
731 if (k
== buffer
.Length
)
739 throw new ArgumentException (String
.Format ("invalid format specified `{0}'",
752 internal void Check (byte [] dest
, int destIdx
, int size
)
755 throw new ArgumentNullException ("dest");
756 if (destIdx
< 0 || destIdx
> dest
.Length
- size
)
757 throw new ArgumentException ("destIdx");
760 class CopyConverter
: DataConverter
{
761 public override double GetDouble (byte [] data
, int index
)
764 throw new ArgumentNullException ("data");
765 if (data
.Length
- index
< 8)
766 throw new ArgumentException ("index");
768 throw new ArgumentException ("index");
770 byte *b
= (byte *)&ret
;
772 for (int i
= 0; i
< 8; i
++)
773 b
[i
] = data
[index
+i
];
778 public override ulong GetUInt64 (byte [] data
, int index
)
781 throw new ArgumentNullException ("data");
782 if (data
.Length
- index
< 8)
783 throw new ArgumentException ("index");
785 throw new ArgumentException ("index");
788 byte *b
= (byte *)&ret
;
790 for (int i
= 0; i
< 8; i
++)
791 b
[i
] = data
[index
+i
];
796 public override long GetInt64 (byte [] data
, int index
)
799 throw new ArgumentNullException ("data");
800 if (data
.Length
- index
< 8)
801 throw new ArgumentException ("index");
803 throw new ArgumentException ("index");
806 byte *b
= (byte *)&ret
;
808 for (int i
= 0; i
< 8; i
++)
809 b
[i
] = data
[index
+i
];
814 public override float GetFloat (byte [] data
, int index
)
817 throw new ArgumentNullException ("data");
818 if (data
.Length
- index
< 4)
819 throw new ArgumentException ("index");
821 throw new ArgumentException ("index");
824 byte *b
= (byte *)&ret
;
826 for (int i
= 0; i
< 4; i
++)
827 b
[i
] = data
[index
+i
];
832 public override int GetInt32 (byte [] data
, int index
)
835 throw new ArgumentNullException ("data");
836 if (data
.Length
- index
< 4)
837 throw new ArgumentException ("index");
839 throw new ArgumentException ("index");
842 byte *b
= (byte *)&ret
;
844 for (int i
= 0; i
< 4; i
++)
845 b
[i
] = data
[index
+i
];
850 public override uint GetUInt32 (byte [] data
, int index
)
853 throw new ArgumentNullException ("data");
854 if (data
.Length
- index
< 4)
855 throw new ArgumentException ("index");
857 throw new ArgumentException ("index");
860 byte *b
= (byte *)&ret
;
862 for (int i
= 0; i
< 4; i
++)
863 b
[i
] = data
[index
+i
];
868 public override short GetInt16 (byte [] data
, int index
)
871 throw new ArgumentNullException ("data");
872 if (data
.Length
- index
< 2)
873 throw new ArgumentException ("index");
875 throw new ArgumentException ("index");
878 byte *b
= (byte *)&ret
;
880 for (int i
= 0; i
< 2; i
++)
881 b
[i
] = data
[index
+i
];
886 public override ushort GetUInt16 (byte [] data
, int index
)
889 throw new ArgumentNullException ("data");
890 if (data
.Length
- index
< 2)
891 throw new ArgumentException ("index");
893 throw new ArgumentException ("index");
896 byte *b
= (byte *)&ret
;
898 for (int i
= 0; i
< 2; i
++)
899 b
[i
] = data
[index
+i
];
904 public override void PutBytes (byte [] dest
, int destIdx
, double value)
906 Check (dest
, destIdx
, 8);
907 fixed (byte *target
= &dest
[destIdx
]){
908 long *source
= (long *) &value;
910 *((long *)target
) = *source
;
914 public override void PutBytes (byte [] dest
, int destIdx
, float value)
916 Check (dest
, destIdx
, 4);
917 fixed (byte *target
= &dest
[destIdx
]){
918 uint *source
= (uint *) &value;
920 *((uint *)target
) = *source
;
924 public override void PutBytes (byte [] dest
, int destIdx
, int value)
926 Check (dest
, destIdx
, 4);
927 fixed (byte *target
= &dest
[destIdx
]){
928 uint *source
= (uint *) &value;
930 *((uint *)target
) = *source
;
934 public override void PutBytes (byte [] dest
, int destIdx
, uint value)
936 Check (dest
, destIdx
, 4);
937 fixed (byte *target
= &dest
[destIdx
]){
938 uint *source
= (uint *) &value;
940 *((uint *)target
) = *source
;
944 public override void PutBytes (byte [] dest
, int destIdx
, long value)
946 Check (dest
, destIdx
, 8);
947 fixed (byte *target
= &dest
[destIdx
]){
948 long *source
= (long *) &value;
950 *((long*)target
) = *source
;
954 public override void PutBytes (byte [] dest
, int destIdx
, ulong value)
956 Check (dest
, destIdx
, 8);
957 fixed (byte *target
= &dest
[destIdx
]){
958 ulong *source
= (ulong *) &value;
960 *((ulong *) target
) = *source
;
964 public override void PutBytes (byte [] dest
, int destIdx
, short value)
966 Check (dest
, destIdx
, 2);
967 fixed (byte *target
= &dest
[destIdx
]){
968 ushort *source
= (ushort *) &value;
970 *((ushort *)target
) = *source
;
974 public override void PutBytes (byte [] dest
, int destIdx
, ushort value)
976 Check (dest
, destIdx
, 2);
977 fixed (byte *target
= &dest
[destIdx
]){
978 ushort *source
= (ushort *) &value;
980 *((ushort *)target
) = *source
;
985 class SwapConverter
: DataConverter
{
986 public override double GetDouble (byte [] data
, int index
)
989 throw new ArgumentNullException ("data");
990 if (data
.Length
- index
< 8)
991 throw new ArgumentException ("index");
993 throw new ArgumentException ("index");
996 byte *b
= (byte *)&ret
;
998 for (int i
= 0; i
< 8; i
++)
999 b
[7-i
] = data
[index
+i
];
1004 public override ulong GetUInt64 (byte [] data
, int index
)
1007 throw new ArgumentNullException ("data");
1008 if (data
.Length
- index
< 8)
1009 throw new ArgumentException ("index");
1011 throw new ArgumentException ("index");
1014 byte *b
= (byte *)&ret
;
1016 for (int i
= 0; i
< 8; i
++)
1017 b
[7-i
] = data
[index
+i
];
1022 public override long GetInt64 (byte [] data
, int index
)
1025 throw new ArgumentNullException ("data");
1026 if (data
.Length
- index
< 8)
1027 throw new ArgumentException ("index");
1029 throw new ArgumentException ("index");
1032 byte *b
= (byte *)&ret
;
1034 for (int i
= 0; i
< 8; i
++)
1035 b
[7-i
] = data
[index
+i
];
1040 public override float GetFloat (byte [] data
, int index
)
1043 throw new ArgumentNullException ("data");
1044 if (data
.Length
- index
< 4)
1045 throw new ArgumentException ("index");
1047 throw new ArgumentException ("index");
1050 byte *b
= (byte *)&ret
;
1052 for (int i
= 0; i
< 4; i
++)
1053 b
[3-i
] = data
[index
+i
];
1058 public override int GetInt32 (byte [] data
, int index
)
1061 throw new ArgumentNullException ("data");
1062 if (data
.Length
- index
< 4)
1063 throw new ArgumentException ("index");
1065 throw new ArgumentException ("index");
1068 byte *b
= (byte *)&ret
;
1070 for (int i
= 0; i
< 4; i
++)
1071 b
[3-i
] = data
[index
+i
];
1076 public override uint GetUInt32 (byte [] data
, int index
)
1079 throw new ArgumentNullException ("data");
1080 if (data
.Length
- index
< 4)
1081 throw new ArgumentException ("index");
1083 throw new ArgumentException ("index");
1086 byte *b
= (byte *)&ret
;
1088 for (int i
= 0; i
< 4; i
++)
1089 b
[3-i
] = data
[index
+i
];
1094 public override short GetInt16 (byte [] data
, int index
)
1097 throw new ArgumentNullException ("data");
1098 if (data
.Length
- index
< 2)
1099 throw new ArgumentException ("index");
1101 throw new ArgumentException ("index");
1104 byte *b
= (byte *)&ret
;
1106 for (int i
= 0; i
< 2; i
++)
1107 b
[1-i
] = data
[index
+i
];
1112 public override ushort GetUInt16 (byte [] data
, int index
)
1115 throw new ArgumentNullException ("data");
1116 if (data
.Length
- index
< 2)
1117 throw new ArgumentException ("index");
1119 throw new ArgumentException ("index");
1122 byte *b
= (byte *)&ret
;
1124 for (int i
= 0; i
< 2; i
++)
1125 b
[1-i
] = data
[index
+i
];
1130 public override void PutBytes (byte [] dest
, int destIdx
, double value)
1132 Check (dest
, destIdx
, 8);
1134 fixed (byte *target
= &dest
[destIdx
]){
1135 byte *source
= (byte *) &value;
1137 for (int i
= 0; i
< 8; i
++)
1138 target
[i
] = source
[7-i
];
1142 public override void PutBytes (byte [] dest
, int destIdx
, float value)
1144 Check (dest
, destIdx
, 4);
1146 fixed (byte *target
= &dest
[destIdx
]){
1147 byte *source
= (byte *) &value;
1149 for (int i
= 0; i
< 4; i
++)
1150 target
[i
] = source
[3-i
];
1154 public override void PutBytes (byte [] dest
, int destIdx
, int value)
1156 Check (dest
, destIdx
, 4);
1158 fixed (byte *target
= &dest
[destIdx
]){
1159 byte *source
= (byte *) &value;
1161 for (int i
= 0; i
< 4; i
++)
1162 target
[i
] = source
[3-i
];
1166 public override void PutBytes (byte [] dest
, int destIdx
, uint value)
1168 Check (dest
, destIdx
, 4);
1170 fixed (byte *target
= &dest
[destIdx
]){
1171 byte *source
= (byte *) &value;
1173 for (int i
= 0; i
< 4; i
++)
1174 target
[i
] = source
[3-i
];
1178 public override void PutBytes (byte [] dest
, int destIdx
, long value)
1180 Check (dest
, destIdx
, 8);
1182 fixed (byte *target
= &dest
[destIdx
]){
1183 byte *source
= (byte *) &value;
1185 for (int i
= 0; i
< 8; i
++)
1186 target
[i
] = source
[7-i
];
1190 public override void PutBytes (byte [] dest
, int destIdx
, ulong value)
1192 Check (dest
, destIdx
, 8);
1194 fixed (byte *target
= &dest
[destIdx
]){
1195 byte *source
= (byte *) &value;
1197 for (int i
= 0; i
< 4; i
++)
1198 target
[i
] = source
[7-i
];
1202 public override void PutBytes (byte [] dest
, int destIdx
, short value)
1204 Check (dest
, destIdx
, 2);
1206 fixed (byte *target
= &dest
[destIdx
]){
1207 byte *source
= (byte *) &value;
1209 for (int i
= 0; i
< 2; i
++)
1210 target
[i
] = source
[1-i
];
1214 public override void PutBytes (byte [] dest
, int destIdx
, ushort value)
1216 Check (dest
, destIdx
, 2);
1218 fixed (byte *target
= &dest
[destIdx
]){
1219 byte *source
= (byte *) &value;
1221 for (int i
= 0; i
< 2; i
++)
1222 target
[i
] = source
[1-i
];
1227 #if MONO_DATACONVERTER_STATIC_METHODS
1228 static unsafe void PutBytesLE (byte *dest
, byte *src
, int count
)
1232 if (BitConverter
.IsLittleEndian
){
1233 for (; i
< count
; i
++)
1237 for (; i
< count
; i
++)
1242 static unsafe void PutBytesBE (byte *dest
, byte *src
, int count
)
1246 if (BitConverter
.IsLittleEndian
){
1248 for (; i
< count
; i
++)
1251 for (; i
< count
; i
++)
1256 static unsafe void PutBytesNative (byte *dest
, byte *src
, int count
)
1260 for (; i
< count
; i
++)
1261 dest
[i
-count
] = *src
++;
1264 static public unsafe double DoubleFromLE (byte[] data
, int index
)
1267 throw new ArgumentNullException ("data");
1268 if (data
.Length
- index
< 8)
1269 throw new ArgumentException ("index");
1271 throw new ArgumentException ("index");
1274 fixed (byte *src
= &data
[index
]){
1275 PutBytesLE ((byte *) &ret
, src
, 8);
1280 static public unsafe float FloatFromLE (byte [] data
, int index
)
1283 throw new ArgumentNullException ("data");
1284 if (data
.Length
- index
< 4)
1285 throw new ArgumentException ("index");
1287 throw new ArgumentException ("index");
1290 fixed (byte *src
= &data
[index
]){
1291 PutBytesLE ((byte *) &ret
, src
, 4);
1296 static public unsafe long Int64FromLE (byte [] data
, int index
)
1299 throw new ArgumentNullException ("data");
1300 if (data
.Length
- index
< 8)
1301 throw new ArgumentException ("index");
1303 throw new ArgumentException ("index");
1306 fixed (byte *src
= &data
[index
]){
1307 PutBytesLE ((byte *) &ret
, src
, 8);
1312 static public unsafe ulong UInt64FromLE (byte [] data
, int index
)
1315 throw new ArgumentNullException ("data");
1316 if (data
.Length
- index
< 8)
1317 throw new ArgumentException ("index");
1319 throw new ArgumentException ("index");
1322 fixed (byte *src
= &data
[index
]){
1323 PutBytesLE ((byte *) &ret
, src
, 8);
1328 static public unsafe int Int32FromLE (byte [] data
, int index
)
1331 throw new ArgumentNullException ("data");
1332 if (data
.Length
- index
< 4)
1333 throw new ArgumentException ("index");
1335 throw new ArgumentException ("index");
1338 fixed (byte *src
= &data
[index
]){
1339 PutBytesLE ((byte *) &ret
, src
, 4);
1344 static public unsafe uint UInt32FromLE (byte [] data
, int index
)
1347 throw new ArgumentNullException ("data");
1348 if (data
.Length
- index
< 4)
1349 throw new ArgumentException ("index");
1351 throw new ArgumentException ("index");
1354 fixed (byte *src
= &data
[index
]){
1355 PutBytesLE ((byte *) &ret
, src
, 4);
1360 static public unsafe short Int16FromLE (byte [] data
, int index
)
1363 throw new ArgumentNullException ("data");
1364 if (data
.Length
- index
< 2)
1365 throw new ArgumentException ("index");
1367 throw new ArgumentException ("index");
1370 fixed (byte *src
= &data
[index
]){
1371 PutBytesLE ((byte *) &ret
, src
, 2);
1376 static public unsafe ushort UInt16FromLE (byte [] data
, int index
)
1379 throw new ArgumentNullException ("data");
1380 if (data
.Length
- index
< 2)
1381 throw new ArgumentException ("index");
1383 throw new ArgumentException ("index");
1386 fixed (byte *src
= &data
[index
]){
1387 PutBytesLE ((byte *) &ret
, src
, 2);
1392 static public unsafe double DoubleFromBE (byte[] data
, int index
)
1395 throw new ArgumentNullException ("data");
1396 if (data
.Length
- index
< 8)
1397 throw new ArgumentException ("index");
1399 throw new ArgumentException ("index");
1402 fixed (byte *src
= &data
[index
]){
1403 PutBytesBE ((byte *) &ret
, src
, 8);
1408 static public unsafe float FloatFromBE (byte [] data
, int index
)
1411 throw new ArgumentNullException ("data");
1412 if (data
.Length
- index
< 4)
1413 throw new ArgumentException ("index");
1415 throw new ArgumentException ("index");
1418 fixed (byte *src
= &data
[index
]){
1419 PutBytesBE ((byte *) &ret
, src
, 4);
1424 static public unsafe long Int64FromBE (byte [] data
, int index
)
1427 throw new ArgumentNullException ("data");
1428 if (data
.Length
- index
< 8)
1429 throw new ArgumentException ("index");
1431 throw new ArgumentException ("index");
1434 fixed (byte *src
= &data
[index
]){
1435 PutBytesBE ((byte *) &ret
, src
, 8);
1440 static public unsafe ulong UInt64FromBE (byte [] data
, int index
)
1443 throw new ArgumentNullException ("data");
1444 if (data
.Length
- index
< 8)
1445 throw new ArgumentException ("index");
1447 throw new ArgumentException ("index");
1450 fixed (byte *src
= &data
[index
]){
1451 PutBytesBE ((byte *) &ret
, src
, 8);
1456 static public unsafe int Int32FromBE (byte [] data
, int index
)
1459 throw new ArgumentNullException ("data");
1460 if (data
.Length
- index
< 4)
1461 throw new ArgumentException ("index");
1463 throw new ArgumentException ("index");
1466 fixed (byte *src
= &data
[index
]){
1467 PutBytesBE ((byte *) &ret
, src
, 4);
1472 static public unsafe uint UInt32FromBE (byte [] data
, int index
)
1475 throw new ArgumentNullException ("data");
1476 if (data
.Length
- index
< 4)
1477 throw new ArgumentException ("index");
1479 throw new ArgumentException ("index");
1482 fixed (byte *src
= &data
[index
]){
1483 PutBytesBE ((byte *) &ret
, src
, 4);
1488 static public unsafe short Int16FromBE (byte [] data
, int index
)
1491 throw new ArgumentNullException ("data");
1492 if (data
.Length
- index
< 2)
1493 throw new ArgumentException ("index");
1495 throw new ArgumentException ("index");
1498 fixed (byte *src
= &data
[index
]){
1499 PutBytesBE ((byte *) &ret
, src
, 2);
1504 static public unsafe ushort UInt16FromBE (byte [] data
, int index
)
1507 throw new ArgumentNullException ("data");
1508 if (data
.Length
- index
< 2)
1509 throw new ArgumentException ("index");
1511 throw new ArgumentException ("index");
1514 fixed (byte *src
= &data
[index
]){
1515 PutBytesBE ((byte *) &ret
, src
, 2);
1520 static public unsafe double DoubleFromNative (byte[] data
, int index
)
1523 throw new ArgumentNullException ("data");
1524 if (data
.Length
- index
< 8)
1525 throw new ArgumentException ("index");
1527 throw new ArgumentException ("index");
1530 fixed (byte *src
= &data
[index
]){
1531 PutBytesNative ((byte *) &ret
, src
, 8);
1536 static public unsafe float FloatFromNative (byte [] data
, int index
)
1539 throw new ArgumentNullException ("data");
1540 if (data
.Length
- index
< 4)
1541 throw new ArgumentException ("index");
1543 throw new ArgumentException ("index");
1546 fixed (byte *src
= &data
[index
]){
1547 PutBytesNative ((byte *) &ret
, src
, 4);
1552 static public unsafe long Int64FromNative (byte [] data
, int index
)
1555 throw new ArgumentNullException ("data");
1556 if (data
.Length
- index
< 8)
1557 throw new ArgumentException ("index");
1559 throw new ArgumentException ("index");
1562 fixed (byte *src
= &data
[index
]){
1563 PutBytesNative ((byte *) &ret
, src
, 8);
1568 static public unsafe ulong UInt64FromNative (byte [] data
, int index
)
1571 throw new ArgumentNullException ("data");
1572 if (data
.Length
- index
< 8)
1573 throw new ArgumentException ("index");
1575 throw new ArgumentException ("index");
1578 fixed (byte *src
= &data
[index
]){
1579 PutBytesNative ((byte *) &ret
, src
, 8);
1584 static public unsafe int Int32FromNative (byte [] data
, int index
)
1587 throw new ArgumentNullException ("data");
1588 if (data
.Length
- index
< 4)
1589 throw new ArgumentException ("index");
1591 throw new ArgumentException ("index");
1594 fixed (byte *src
= &data
[index
]){
1595 PutBytesNative ((byte *) &ret
, src
, 4);
1600 static public unsafe uint UInt32FromNative (byte [] data
, int index
)
1603 throw new ArgumentNullException ("data");
1604 if (data
.Length
- index
< 4)
1605 throw new ArgumentException ("index");
1607 throw new ArgumentException ("index");
1610 fixed (byte *src
= &data
[index
]){
1611 PutBytesNative ((byte *) &ret
, src
, 4);
1616 static public unsafe short Int16FromNative (byte [] data
, int index
)
1619 throw new ArgumentNullException ("data");
1620 if (data
.Length
- index
< 2)
1621 throw new ArgumentException ("index");
1623 throw new ArgumentException ("index");
1626 fixed (byte *src
= &data
[index
]){
1627 PutBytesNative ((byte *) &ret
, src
, 2);
1632 static public unsafe ushort UInt16FromNative (byte [] data
, int index
)
1635 throw new ArgumentNullException ("data");
1636 if (data
.Length
- index
< 2)
1637 throw new ArgumentException ("index");
1639 throw new ArgumentException ("index");
1642 fixed (byte *src
= &data
[index
]){
1643 PutBytesNative ((byte *) &ret
, src
, 2);
1648 unsafe static byte[] GetBytesPtr (byte *ptr
, int count
)
1650 byte [] ret
= new byte [count
];
1652 for (int i
= 0; i
< count
; i
++) {
1659 unsafe static byte[] GetBytesSwap (bool swap
, byte *ptr
, int count
)
1661 byte [] ret
= new byte [count
];
1665 for (int i
= 0; i
< count
; i
++) {
1666 ret
[t
-i
] = ptr
[i
];
1669 for (int i
= 0; i
< count
; i
++) {
1676 unsafe public static byte[] GetBytesNative (bool value)
1678 return GetBytesPtr ((byte *) &value, 1);
1681 unsafe public static byte[] GetBytesNative (char value)
1683 return GetBytesPtr ((byte *) &value, 2);
1686 unsafe public static byte[] GetBytesNative (short value)
1688 return GetBytesPtr ((byte *) &value, 2);
1691 unsafe public static byte[] GetBytesNative (int value)
1693 return GetBytesPtr ((byte *) &value, 4);
1696 unsafe public static byte[] GetBytesNative (long value)
1698 return GetBytesPtr ((byte *) &value, 8);
1701 [CLSCompliant (false)]
1702 unsafe public static byte[] GetBytesNative (ushort value)
1704 return GetBytesPtr ((byte *) &value, 2);
1707 [CLSCompliant (false)]
1708 unsafe public static byte[] GetBytesNative (uint value)
1710 return GetBytesPtr ((byte *) &value, 4);
1713 [CLSCompliant (false)]
1714 unsafe public static byte[] GetBytesNative (ulong value)
1716 return GetBytesPtr ((byte *) &value, 8);
1719 unsafe public static byte[] GetBytesNative (float value)
1721 return GetBytesPtr ((byte *) &value, 4);
1724 unsafe public static byte[] GetBytesNative (double value)
1726 return GetBytesPtr ((byte *) &value, 8);
1729 unsafe public static byte[] GetBytesLE (bool value)
1731 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 1);
1734 unsafe public static byte[] GetBytesLE (char value)
1736 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1739 unsafe public static byte[] GetBytesLE (short value)
1741 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1744 unsafe public static byte[] GetBytesLE (int value)
1746 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1749 unsafe public static byte[] GetBytesLE (long value)
1751 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 8);
1754 [CLSCompliant (false)]
1755 unsafe public static byte[] GetBytesLE (ushort value)
1757 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1760 [CLSCompliant (false)]
1761 unsafe public static byte[] GetBytesLE (uint value)
1763 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1766 [CLSCompliant (false)]
1767 unsafe public static byte[] GetBytesLE (ulong value)
1769 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 8);
1772 unsafe public static byte[] GetBytesLE (float value)
1774 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1777 unsafe public static byte[] GetBytesLE (double value)
1779 return GetBytesSwap (!BitConverter
.IsLittleEndian
, (byte *) &value, 8);
1782 unsafe public static byte[] GetBytesBE (bool value)
1784 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 1);
1787 unsafe public static byte[] GetBytesBE (char value)
1789 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1792 unsafe public static byte[] GetBytesBE (short value)
1794 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1797 unsafe public static byte[] GetBytesBE (int value)
1799 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1802 unsafe public static byte[] GetBytesBE (long value)
1804 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 8);
1807 [CLSCompliant (false)]
1808 unsafe public static byte[] GetBytesBE (ushort value)
1810 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 2);
1813 [CLSCompliant (false)]
1814 unsafe public static byte[] GetBytesBE (uint value)
1816 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1819 [CLSCompliant (false)]
1820 unsafe public static byte[] GetBytesBE (ulong value)
1822 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 8);
1825 unsafe public static byte[] GetBytesBE (float value)
1827 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 4);
1830 unsafe public static byte[] GetBytesBE (double value)
1832 return GetBytesSwap (BitConverter
.IsLittleEndian
, (byte *) &value, 8);