3 // Miguel de Icaza (miguel@novell.com)
5 // See the following url for documentation:
6 // http://www.mono-project.com/Mono_DataConvert
8 // WARNING: This is a modified version!!!! Most features were removed by
9 // Avery Pennarun <apenwarr@gmail.com>.
12 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Collections
;
39 unsafe internal abstract class DataConverter
{
41 // Disables the warning: CLS compliance checking will not be performed on
42 // `XXXX' because it is not visible from outside this assembly
43 #pragma warning disable 3019
44 static DataConverter SwapConv
= new SwapConverter ();
45 static DataConverter CopyConv
= new CopyConverter ();
47 public static readonly bool IsLittleEndian
= BitConverter
.IsLittleEndian
;
49 public abstract double GetDouble (byte [] data
, int index
);
50 public abstract float GetFloat (byte [] data
, int index
);
51 public abstract long GetInt64 (byte [] data
, int index
);
52 public abstract int GetInt32 (byte [] data
, int index
);
54 public abstract short GetInt16 (byte [] data
, int index
);
56 public abstract uint GetUInt32 (byte [] data
, int index
);
57 public abstract ushort GetUInt16 (byte [] data
, int index
);
58 public abstract ulong GetUInt64 (byte [] data
, int index
);
60 public abstract void PutBytes (byte [] dest
, int destIdx
, double value);
61 public abstract void PutBytes (byte [] dest
, int destIdx
, float value);
62 public abstract void PutBytes (byte [] dest
, int destIdx
, int value);
63 public abstract void PutBytes (byte [] dest
, int destIdx
, long value);
64 public abstract void PutBytes (byte [] dest
, int destIdx
, short value);
66 public abstract void PutBytes (byte [] dest
, int destIdx
, ushort value);
67 public abstract void PutBytes (byte [] dest
, int destIdx
, uint value);
68 public abstract void PutBytes (byte [] dest
, int destIdx
, ulong value);
70 public byte[] GetBytes (double value)
72 byte [] ret
= new byte [8];
73 PutBytes (ret
, 0, value);
77 public byte[] GetBytes (float value)
79 byte [] ret
= new byte [4];
80 PutBytes (ret
, 0, value);
84 public byte[] GetBytes (int value)
86 byte [] ret
= new byte [4];
87 PutBytes (ret
, 0, value);
91 public byte[] GetBytes (long value)
93 byte [] ret
= new byte [8];
94 PutBytes (ret
, 0, value);
98 public byte[] GetBytes (short value)
100 byte [] ret
= new byte [2];
101 PutBytes (ret
, 0, value);
105 public byte[] GetBytes (ushort value)
107 byte [] ret
= new byte [2];
108 PutBytes (ret
, 0, value);
112 public byte[] GetBytes (uint value)
114 byte [] ret
= new byte [4];
115 PutBytes (ret
, 0, value);
119 public byte[] GetBytes (ulong value)
121 byte [] ret
= new byte [8];
122 PutBytes (ret
, 0, value);
126 static public DataConverter LittleEndian
{
128 return BitConverter
.IsLittleEndian
? CopyConv
: SwapConv
;
132 static public DataConverter BigEndian
{
134 return BitConverter
.IsLittleEndian
? SwapConv
: CopyConv
;
138 static public DataConverter Native
{
144 internal void Check (byte [] dest
, int destIdx
, int size
)
147 throw new ArgumentNullException ("dest");
148 if (destIdx
< 0 || destIdx
> dest
.Length
- size
)
149 throw new ArgumentException ("destIdx");
152 class CopyConverter
: DataConverter
{
153 public override double GetDouble (byte [] data
, int index
)
156 throw new ArgumentNullException ("data");
157 if (data
.Length
- index
< 8)
158 throw new ArgumentException ("index");
160 throw new ArgumentException ("index");
162 byte *b
= (byte *)&ret
;
164 for (int i
= 0; i
< 8; i
++)
165 b
[i
] = data
[index
+i
];
170 public override ulong GetUInt64 (byte [] data
, int index
)
173 throw new ArgumentNullException ("data");
174 if (data
.Length
- index
< 8)
175 throw new ArgumentException ("index");
177 throw new ArgumentException ("index");
180 byte *b
= (byte *)&ret
;
182 for (int i
= 0; i
< 8; i
++)
183 b
[i
] = data
[index
+i
];
188 public override long GetInt64 (byte [] data
, int index
)
191 throw new ArgumentNullException ("data");
192 if (data
.Length
- index
< 8)
193 throw new ArgumentException ("index");
195 throw new ArgumentException ("index");
198 byte *b
= (byte *)&ret
;
200 for (int i
= 0; i
< 8; i
++)
201 b
[i
] = data
[index
+i
];
206 public override float GetFloat (byte [] data
, int index
)
209 throw new ArgumentNullException ("data");
210 if (data
.Length
- index
< 4)
211 throw new ArgumentException ("index");
213 throw new ArgumentException ("index");
216 byte *b
= (byte *)&ret
;
218 for (int i
= 0; i
< 4; i
++)
219 b
[i
] = data
[index
+i
];
224 public override int GetInt32 (byte [] data
, int index
)
227 throw new ArgumentNullException ("data");
228 if (data
.Length
- index
< 4)
229 throw new ArgumentException ("index");
231 throw new ArgumentException ("index");
234 byte *b
= (byte *)&ret
;
236 for (int i
= 0; i
< 4; i
++)
237 b
[i
] = data
[index
+i
];
242 public override uint GetUInt32 (byte [] data
, int index
)
245 throw new ArgumentNullException ("data");
246 if (data
.Length
- index
< 4)
247 throw new ArgumentException ("index");
249 throw new ArgumentException ("index");
252 byte *b
= (byte *)&ret
;
254 for (int i
= 0; i
< 4; i
++)
255 b
[i
] = data
[index
+i
];
260 public override short GetInt16 (byte [] data
, int index
)
263 throw new ArgumentNullException ("data");
264 if (data
.Length
- index
< 2)
265 throw new ArgumentException ("index");
267 throw new ArgumentException ("index");
270 byte *b
= (byte *)&ret
;
272 for (int i
= 0; i
< 2; i
++)
273 b
[i
] = data
[index
+i
];
278 public override ushort GetUInt16 (byte [] data
, int index
)
281 throw new ArgumentNullException ("data");
282 if (data
.Length
- index
< 2)
283 throw new ArgumentException ("index");
285 throw new ArgumentException ("index");
288 byte *b
= (byte *)&ret
;
290 for (int i
= 0; i
< 2; i
++)
291 b
[i
] = data
[index
+i
];
296 public override void PutBytes (byte [] dest
, int destIdx
, double value)
298 Check (dest
, destIdx
, 8);
299 fixed (byte *target
= &dest
[destIdx
]){
300 long *source
= (long *) &value;
302 *((long *)target
) = *source
;
306 public override void PutBytes (byte [] dest
, int destIdx
, float value)
308 Check (dest
, destIdx
, 4);
309 fixed (byte *target
= &dest
[destIdx
]){
310 uint *source
= (uint *) &value;
312 *((uint *)target
) = *source
;
316 public override void PutBytes (byte [] dest
, int destIdx
, int value)
318 Check (dest
, destIdx
, 4);
319 fixed (byte *target
= &dest
[destIdx
]){
320 uint *source
= (uint *) &value;
322 *((uint *)target
) = *source
;
326 public override void PutBytes (byte [] dest
, int destIdx
, uint value)
328 Check (dest
, destIdx
, 4);
329 fixed (byte *target
= &dest
[destIdx
]){
330 uint *source
= (uint *) &value;
332 *((uint *)target
) = *source
;
336 public override void PutBytes (byte [] dest
, int destIdx
, long value)
338 Check (dest
, destIdx
, 8);
339 fixed (byte *target
= &dest
[destIdx
]){
340 long *source
= (long *) &value;
342 *((long*)target
) = *source
;
346 public override void PutBytes (byte [] dest
, int destIdx
, ulong value)
348 Check (dest
, destIdx
, 8);
349 fixed (byte *target
= &dest
[destIdx
]){
350 ulong *source
= (ulong *) &value;
352 *((ulong *) target
) = *source
;
356 public override void PutBytes (byte [] dest
, int destIdx
, short value)
358 Check (dest
, destIdx
, 2);
359 fixed (byte *target
= &dest
[destIdx
]){
360 ushort *source
= (ushort *) &value;
362 *((ushort *)target
) = *source
;
366 public override void PutBytes (byte [] dest
, int destIdx
, ushort value)
368 Check (dest
, destIdx
, 2);
369 fixed (byte *target
= &dest
[destIdx
]){
370 ushort *source
= (ushort *) &value;
372 *((ushort *)target
) = *source
;
377 class SwapConverter
: DataConverter
{
378 public override double GetDouble (byte [] data
, int index
)
381 throw new ArgumentNullException ("data");
382 if (data
.Length
- index
< 8)
383 throw new ArgumentException ("index");
385 throw new ArgumentException ("index");
388 byte *b
= (byte *)&ret
;
390 for (int i
= 0; i
< 8; i
++)
391 b
[7-i
] = data
[index
+i
];
396 public override ulong GetUInt64 (byte [] data
, int index
)
399 throw new ArgumentNullException ("data");
400 if (data
.Length
- index
< 8)
401 throw new ArgumentException ("index");
403 throw new ArgumentException ("index");
406 byte *b
= (byte *)&ret
;
408 for (int i
= 0; i
< 8; i
++)
409 b
[7-i
] = data
[index
+i
];
414 public override long GetInt64 (byte [] data
, int index
)
417 throw new ArgumentNullException ("data");
418 if (data
.Length
- index
< 8)
419 throw new ArgumentException ("index");
421 throw new ArgumentException ("index");
424 byte *b
= (byte *)&ret
;
426 for (int i
= 0; i
< 8; i
++)
427 b
[7-i
] = data
[index
+i
];
432 public override float GetFloat (byte [] data
, int index
)
435 throw new ArgumentNullException ("data");
436 if (data
.Length
- index
< 4)
437 throw new ArgumentException ("index");
439 throw new ArgumentException ("index");
442 byte *b
= (byte *)&ret
;
444 for (int i
= 0; i
< 4; i
++)
445 b
[3-i
] = data
[index
+i
];
450 public override int GetInt32 (byte [] data
, int index
)
453 throw new ArgumentNullException ("data");
454 if (data
.Length
- index
< 4)
455 throw new ArgumentException ("index");
457 throw new ArgumentException ("index");
460 byte *b
= (byte *)&ret
;
462 for (int i
= 0; i
< 4; i
++)
463 b
[3-i
] = data
[index
+i
];
468 public override uint GetUInt32 (byte [] data
, int index
)
471 throw new ArgumentNullException ("data");
472 if (data
.Length
- index
< 4)
473 throw new ArgumentException ("index");
475 throw new ArgumentException ("index");
478 byte *b
= (byte *)&ret
;
480 for (int i
= 0; i
< 4; i
++)
481 b
[3-i
] = data
[index
+i
];
486 public override short GetInt16 (byte [] data
, int index
)
489 throw new ArgumentNullException ("data");
490 if (data
.Length
- index
< 2)
491 throw new ArgumentException ("index");
493 throw new ArgumentException ("index");
496 byte *b
= (byte *)&ret
;
498 for (int i
= 0; i
< 2; i
++)
499 b
[1-i
] = data
[index
+i
];
504 public override ushort GetUInt16 (byte [] data
, int index
)
507 throw new ArgumentNullException ("data");
508 if (data
.Length
- index
< 2)
509 throw new ArgumentException ("index");
511 throw new ArgumentException ("index");
514 byte *b
= (byte *)&ret
;
516 for (int i
= 0; i
< 2; i
++)
517 b
[1-i
] = data
[index
+i
];
522 public override void PutBytes (byte [] dest
, int destIdx
, double value)
524 Check (dest
, destIdx
, 8);
526 fixed (byte *target
= &dest
[destIdx
]){
527 byte *source
= (byte *) &value;
529 for (int i
= 0; i
< 8; i
++)
530 target
[i
] = source
[7-i
];
534 public override void PutBytes (byte [] dest
, int destIdx
, float value)
536 Check (dest
, destIdx
, 4);
538 fixed (byte *target
= &dest
[destIdx
]){
539 byte *source
= (byte *) &value;
541 for (int i
= 0; i
< 4; i
++)
542 target
[i
] = source
[3-i
];
546 public override void PutBytes (byte [] dest
, int destIdx
, int value)
548 Check (dest
, destIdx
, 4);
550 fixed (byte *target
= &dest
[destIdx
]){
551 byte *source
= (byte *) &value;
553 for (int i
= 0; i
< 4; i
++)
554 target
[i
] = source
[3-i
];
558 public override void PutBytes (byte [] dest
, int destIdx
, uint value)
560 Check (dest
, destIdx
, 4);
562 fixed (byte *target
= &dest
[destIdx
]){
563 byte *source
= (byte *) &value;
565 for (int i
= 0; i
< 4; i
++)
566 target
[i
] = source
[3-i
];
570 public override void PutBytes (byte [] dest
, int destIdx
, long value)
572 Check (dest
, destIdx
, 8);
574 fixed (byte *target
= &dest
[destIdx
]){
575 byte *source
= (byte *) &value;
577 for (int i
= 0; i
< 8; i
++)
578 target
[i
] = source
[7-i
];
582 public override void PutBytes (byte [] dest
, int destIdx
, ulong value)
584 Check (dest
, destIdx
, 8);
586 fixed (byte *target
= &dest
[destIdx
]){
587 byte *source
= (byte *) &value;
589 for (int i
= 0; i
< 4; i
++)
590 target
[i
] = source
[7-i
];
594 public override void PutBytes (byte [] dest
, int destIdx
, short value)
596 Check (dest
, destIdx
, 2);
598 fixed (byte *target
= &dest
[destIdx
]){
599 byte *source
= (byte *) &value;
601 for (int i
= 0; i
< 2; i
++)
602 target
[i
] = source
[1-i
];
606 public override void PutBytes (byte [] dest
, int destIdx
, ushort value)
608 Check (dest
, destIdx
, 2);
610 fixed (byte *target
= &dest
[destIdx
]){
611 byte *source
= (byte *) &value;
613 for (int i
= 0; i
< 2; i
++)
614 target
[i
] = source
[1-i
];