-//
-// Authors:
-// Miguel de Icaza (miguel@novell.com)
-//
-// See the following url for documentation:
-// http://www.mono-project.com/Mono_DataConvert
-//
-// Compilation Options:
-// MONO_DATACONVERTER_PUBLIC:
-// Makes the class public instead of the default internal.
-//
-// MONO_DATACONVERTER_STATIC_METHODS:
-// Exposes the public static methods.
-//
-// TODO:
-// Support for "DoubleWordsAreSwapped" for ARM devices
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Collections;
-using System.Text;
-
-#pragma warning disable 3021
-
-namespace Mono {
-
-#if MONO_DATACONVERTER_PUBLIC
- unsafe public abstract class DataConverter {
-#else
- unsafe internal abstract class DataConverter {
-
-// Disables the warning: CLS compliance checking will not be performed on
-// `XXXX' because it is not visible from outside this assembly
-#pragma warning disable 3019
-#endif
- static DataConverter SwapConv = new SwapConverter ();
- static DataConverter CopyConv = new CopyConverter ();
-
- public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian;
-
- public abstract double GetDouble (byte [] data, int index);
- public abstract float GetFloat (byte [] data, int index);
- public abstract long GetInt64 (byte [] data, int index);
- public abstract int GetInt32 (byte [] data, int index);
-
- public abstract short GetInt16 (byte [] data, int index);
-
- [CLSCompliant (false)]
- public abstract uint GetUInt32 (byte [] data, int index);
- [CLSCompliant (false)]
- public abstract ushort GetUInt16 (byte [] data, int index);
- [CLSCompliant (false)]
- public abstract ulong GetUInt64 (byte [] data, int index);
-
- public abstract void PutBytes (byte [] dest, int destIdx, double value);
- public abstract void PutBytes (byte [] dest, int destIdx, float value);
- public abstract void PutBytes (byte [] dest, int destIdx, int value);
- public abstract void PutBytes (byte [] dest, int destIdx, long value);
- public abstract void PutBytes (byte [] dest, int destIdx, short value);
-
- [CLSCompliant (false)]
- public abstract void PutBytes (byte [] dest, int destIdx, ushort value);
- [CLSCompliant (false)]
- public abstract void PutBytes (byte [] dest, int destIdx, uint value);
- [CLSCompliant (false)]
- public abstract void PutBytes (byte [] dest, int destIdx, ulong value);
-
- public byte[] GetBytes (double value)
- {
- byte [] ret = new byte [8];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- public byte[] GetBytes (float value)
- {
- byte [] ret = new byte [4];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- public byte[] GetBytes (int value)
- {
- byte [] ret = new byte [4];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- public byte[] GetBytes (long value)
- {
- byte [] ret = new byte [8];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- public byte[] GetBytes (short value)
- {
- byte [] ret = new byte [2];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- [CLSCompliant (false)]
- public byte[] GetBytes (ushort value)
- {
- byte [] ret = new byte [2];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- [CLSCompliant (false)]
- public byte[] GetBytes (uint value)
- {
- byte [] ret = new byte [4];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- [CLSCompliant (false)]
- public byte[] GetBytes (ulong value)
- {
- byte [] ret = new byte [8];
- PutBytes (ret, 0, value);
- return ret;
- }
-
- static public DataConverter LittleEndian {
- get {
- return BitConverter.IsLittleEndian ? CopyConv : SwapConv;
- }
- }
-
- static public DataConverter BigEndian {
- get {
- return BitConverter.IsLittleEndian ? SwapConv : CopyConv;
- }
- }
-
- static public DataConverter Native {
- get {
- return CopyConv;
- }
- }
-
- static int Align (int current, int align)
- {
- return ((current + align - 1) / align) * align;
- }
-
- class PackContext {
- // Buffer
- public byte [] buffer;
- int next;
-
- public string description;
- public int i; // position in the description
- public DataConverter conv;
- public int repeat;
-
- //
- // if align == -1, auto align to the size of the byte array
- // if align == 0, do not do alignment
- // Any other values aligns to that particular size
- //
- public int align;
-
- public void Add (byte [] group)
- {
- //Console.WriteLine ("Adding {0} bytes to {1} (next={2}", group.Length,
- // buffer == null ? "null" : buffer.Length.ToString (), next);
-
- if (buffer == null){
- buffer = group;
- next = group.Length;
- return;
- }
- if (align != 0){
- if (align == -1)
- next = Align (next, group.Length);
- else
- next = Align (next, align);
- align = 0;
- }
-
- if (next + group.Length > buffer.Length){
- byte [] nb = new byte [System.Math.Max (next, 16) * 2 + group.Length];
- Array.Copy (buffer, nb, buffer.Length);
- Array.Copy (group, 0, nb, next, group.Length);
- next = next + group.Length;
- buffer = nb;
- } else {
- Array.Copy (group, 0, buffer, next, group.Length);
- next += group.Length;
- }
- }
-
- public byte [] Get ()
- {
- if (buffer == null)
- return new byte [0];
-
- if (buffer.Length != next){
- byte [] b = new byte [next];
- Array.Copy (buffer, b, next);
- return b;
- }
- return buffer;
- }
- }
-
- //
- // Format includes:
- // Control:
- // ^ Switch to big endian encoding
- // _ Switch to little endian encoding
- // % Switch to host (native) encoding
- // ! aligns the next data type to its natural boundary (for strings this is 4).
- //
- // Types:
- // s Int16
- // S UInt16
- // i Int32
- // I UInt32
- // l Int64
- // L UInt64
- // f float
- // d double
- // b byte
- // c 1-byte signed character
- // C 1-byte unsigned character
- // z8 string encoded as UTF8 with 1-byte null terminator
- // z6 string encoded as UTF16 with 2-byte null terminator
- // z7 string encoded as UTF7 with 1-byte null terminator
- // zb string encoded as BigEndianUnicode with 2-byte null terminator
- // z3 string encoded as UTF32 with 4-byte null terminator
- // z4 string encoded as UTF32 big endian with 4-byte null terminator
- // $8 string encoded as UTF8
- // $6 string encoded as UTF16
- // $7 string encoded as UTF7
- // $b string encoded as BigEndianUnicode
- // $3 string encoded as UTF32
- // $4 string encoded as UTF-32 big endian encoding
- // x null byte
- //
- // Repeats, these are prefixes:
- // N a number between 1 and 9, indicates a repeat count (process N items
- // with the following datatype
- // [N] For numbers larger than 9, use brackets, for example [20]
- // * Repeat the next data type until the arguments are exhausted
- //
- static public byte [] Pack (string description, params object [] args)
- {
- int argn = 0;
- PackContext b = new PackContext ();
- b.conv = CopyConv;
- b.description = description;
-
- for (b.i = 0; b.i < description.Length; ){
- object oarg;
-
- if (argn < args.Length)
- oarg = args [argn];
- else {
- if (b.repeat != 0)
- break;
-
- oarg = null;
- }
-
- int save = b.i;
-
- if (PackOne (b, oarg)){
- argn++;
- if (b.repeat > 0){
- if (--b.repeat > 0)
- b.i = save;
- else
- b.i++;
- } else
- b.i++;
- } else
- b.i++;
- }
- return b.Get ();
- }
-
- static public byte [] PackEnumerable (string description, IEnumerable args)
- {
- PackContext b = new PackContext ();
- b.conv = CopyConv;
- b.description = description;
-
- IEnumerator enumerator = args.GetEnumerator ();
- bool ok = enumerator.MoveNext ();
-
- for (b.i = 0; b.i < description.Length; ){
- object oarg;
-
- if (ok)
- oarg = enumerator.Current;
- else {
- if (b.repeat != 0)
- break;
- oarg = null;
- }
-
- int save = b.i;
-
- if (PackOne (b, oarg)){
- ok = enumerator.MoveNext ();
- if (b.repeat > 0){
- if (--b.repeat > 0)
- b.i = save;
- else
- b.i++;
- } else
- b.i++;
- } else
- b.i++;
- }
- return b.Get ();
- }
-
- //
- // Packs one datum `oarg' into the buffer `b', using the string format
- // in `description' at position `i'
- //
- // Returns: true if we must pick the next object from the list
- //
- static bool PackOne (PackContext b, object oarg)
- {
- int n;
-
- switch (b.description [b.i]){
- case '^':
- b.conv = BigEndian;
- return false;
- case '_':
- b.conv = LittleEndian;
- return false;
- case '%':
- b.conv = Native;
- return false;
-
- case '!':
- b.align = -1;
- return false;
-
- case 'x':
- b.Add (new byte [] { 0 });
- return false;
-
- // Type Conversions
- case 'i':
- b.Add (b.conv.GetBytes (Convert.ToInt32 (oarg)));
- break;
-
- case 'I':
- b.Add (b.conv.GetBytes (Convert.ToUInt32 (oarg)));
- break;
-
- case 's':
- b.Add (b.conv.GetBytes (Convert.ToInt16 (oarg)));
- break;
-
- case 'S':
- b.Add (b.conv.GetBytes (Convert.ToUInt16 (oarg)));
- break;
-
- case 'l':
- b.Add (b.conv.GetBytes (Convert.ToInt64 (oarg)));
- break;
-
- case 'L':
- b.Add (b.conv.GetBytes (Convert.ToUInt64 (oarg)));
- break;
-
- case 'f':
- b.Add (b.conv.GetBytes (Convert.ToSingle (oarg)));
- break;
-
- case 'd':
- b.Add (b.conv.GetBytes (Convert.ToDouble (oarg)));
- break;
-
- case 'b':
- b.Add (new byte [] { Convert.ToByte (oarg) });
- break;
-
- case 'c':
- b.Add (new byte [] { (byte) (Convert.ToSByte (oarg)) });
- break;
-
- case 'C':
- b.Add (new byte [] { Convert.ToByte (oarg) });
- break;
-
- // Repeat acount;
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- b.repeat = ((short) b.description [b.i]) - ((short) '0');
- return false;
-
- case '*':
- b.repeat = Int32.MaxValue;
- return false;
-
- case '[':
- int count = -1, j;
-
- for (j = b.i+1; j < b.description.Length; j++){
- if (b.description [j] == ']')
- break;
- n = ((short) b.description [j]) - ((short) '0');
- if (n >= 0 && n <= 9){
- if (count == -1)
- count = n;
- else
- count = count * 10 + n;
- }
- }
- if (count == -1)
- throw new ArgumentException ("invalid size specification");
- b.i = j;
- b.repeat = count;
- return false;
-
- case '$': case 'z':
- bool add_null = b.description [b.i] == 'z';
- b.i++;
- if (b.i >= b.description.Length)
- throw new ArgumentException ("$ description needs a type specified", "description");
- char d = b.description [b.i];
- Encoding e;
-
- switch (d){
- case '8':
- e = Encoding.UTF8;
- n = 1;
- break;
- case '6':
- e = Encoding.Unicode;
- n = 2;
- break;
- case '7':
- e = Encoding.UTF7;
- n = 1;
- break;
- case 'b':
- e = Encoding.BigEndianUnicode;
- n = 2;
- break;
- case '3':
- e = Encoding.GetEncoding (12000);
- n = 4;
- break;
- case '4':
- e = Encoding.GetEncoding (12001);
- n = 4;
- break;
-
- default:
- throw new ArgumentException ("Invalid format for $ specifier", "description");
- }
- if (b.align == -1)
- b.align = 4;
- b.Add (e.GetBytes (Convert.ToString (oarg)));
- if (add_null)
- b.Add (new byte [n]);
- break;
- default:
- throw new ArgumentException (String.Format ("invalid format specified `{0}'",
- b.description [b.i]));
- }
- return true;
- }
-
- static bool Prepare (byte [] buffer, ref int idx, int size, ref bool align)
- {
- if (align){
- idx = Align (idx, size);
- align = false;
- }
- if (idx + size > buffer.Length){
- idx = buffer.Length;
- return false;
- }
- return true;
- }
-
- static public IList Unpack (string description, byte [] buffer, int startIndex)
- {
- DataConverter conv = CopyConv;
- ArrayList result = new ArrayList ();
- int idx = startIndex;
- bool align = false;
- int repeat = 0, n;
-
- for (int i = 0; i < description.Length && idx < buffer.Length; ){
- int save = i;
-
- switch (description [i]){
- case '^':
- conv = BigEndian;
- break;
- case '_':
- conv = LittleEndian;
- break;
- case '%':
- conv = Native;
- break;
- case 'x':
- idx++;
- break;
-
- case '!':
- align = true;
- break;
-
- // Type Conversions
- case 'i':
- if (Prepare (buffer, ref idx, 4, ref align)){
- result.Add (conv.GetInt32 (buffer, idx));
- idx += 4;
- }
- break;
-
- case 'I':
- if (Prepare (buffer, ref idx, 4, ref align)){
- result.Add (conv.GetUInt32 (buffer, idx));
- idx += 4;
- }
- break;
-
- case 's':
- if (Prepare (buffer, ref idx, 2, ref align)){
- result.Add (conv.GetInt16 (buffer, idx));
- idx += 2;
- }
- break;
-
- case 'S':
- if (Prepare (buffer, ref idx, 2, ref align)){
- result.Add (conv.GetUInt16 (buffer, idx));
- idx += 2;
- }
- break;
-
- case 'l':
- if (Prepare (buffer, ref idx, 8, ref align)){
- result.Add (conv.GetInt64 (buffer, idx));
- idx += 8;
- }
- break;
-
- case 'L':
- if (Prepare (buffer, ref idx, 8, ref align)){
- result.Add (conv.GetUInt64 (buffer, idx));
- idx += 8;
- }
- break;
-
- case 'f':
- if (Prepare (buffer, ref idx, 4, ref align)){
- result.Add (conv.GetDouble (buffer, idx));
- idx += 4;
- }
- break;
-
- case 'd':
- if (Prepare (buffer, ref idx, 8, ref align)){
- result.Add (conv.GetDouble (buffer, idx));
- idx += 8;
- }
- break;
-
- case 'b':
- if (Prepare (buffer, ref idx, 1, ref align)){
- result.Add (buffer [idx]);
- idx++;
- }
- break;
-
- case 'c': case 'C':
- if (Prepare (buffer, ref idx, 1, ref align)){
- char c;
-
- if (description [i] == 'c')
- c = ((char) ((sbyte)buffer [idx]));
- else
- c = ((char) ((byte)buffer [idx]));
-
- result.Add (c);
- idx++;
- }
- break;
-
- // Repeat acount;
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- repeat = ((short) description [i]) - ((short) '0');
- save = i + 1;
- break;
-
- case '*':
- repeat = Int32.MaxValue;
- break;
-
- case '[':
- int count = -1, j;
-
- for (j = i+1; j < description.Length; j++){
- if (description [j] == ']')
- break;
- n = ((short) description [j]) - ((short) '0');
- if (n >= 0 && n <= 9){
- if (count == -1)
- count = n;
- else
- count = count * 10 + n;
- }
- }
- if (count == -1)
- throw new ArgumentException ("invalid size specification");
- i = j;
- repeat = count;
- break;
-
- case '$': case 'z':
- // bool with_null = description [i] == 'z';
- i++;
- if (i >= description.Length)
- throw new ArgumentException ("$ description needs a type specified", "description");
- char d = description [i];
- Encoding e;
- if (align){
- idx = Align (idx, 4);
- align = false;
- }
- if (idx >= buffer.Length)
- break;
-
- switch (d){
- case '8':
- e = Encoding.UTF8;
- n = 1;
- break;
- case '6':
- e = Encoding.Unicode;
- n = 2;
- break;
- case '7':
- e = Encoding.UTF7;
- n = 1;
- break;
- case 'b':
- e = Encoding.BigEndianUnicode;
- n = 2;
- break;
- case '3':
- e = Encoding.GetEncoding (12000);
- n = 4;
- break;
- case '4':
- e = Encoding.GetEncoding (12001);
- n = 4;
- break;
-
- default:
- throw new ArgumentException ("Invalid format for $ specifier", "description");
- }
- int k = idx;
- switch (n){
- case 1:
- for (; k < buffer.Length && buffer [k] != 0; k++)
- ;
- result.Add (e.GetChars (buffer, idx, k-idx));
- if (k == buffer.Length)
- idx = k;
- else
- idx = k+1;
- break;
-
- case 2:
- for (; k < buffer.Length; k++){
- if (k+1 == buffer.Length){
- k++;
- break;
- }
- if (buffer [k] == 0 && buffer [k+1] == 0)
- break;
- }
- result.Add (e.GetChars (buffer, idx, k-idx));
- if (k == buffer.Length)
- idx = k;
- else
- idx = k+2;
- break;
-
- case 4:
- for (; k < buffer.Length; k++){
- if (k+3 >= buffer.Length){
- k = buffer.Length;
- break;
- }
- if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0)
- break;
- }
- result.Add (e.GetChars (buffer, idx, k-idx));
- if (k == buffer.Length)
- idx = k;
- else
- idx = k+4;
- break;
- }
- break;
- default:
- throw new ArgumentException (String.Format ("invalid format specified `{0}'",
- description [i]));
- }
-
- if (repeat > 0){
- if (--repeat > 0)
- i = save;
- } else
- i++;
- }
- return result;
- }
-
- internal void Check (byte [] dest, int destIdx, int size)
- {
- if (dest == null)
- throw new ArgumentNullException ("dest");
- if (destIdx < 0 || destIdx > dest.Length - size)
- throw new ArgumentException ("destIdx");
- }
-
- class CopyConverter : DataConverter {
- public override double GetDouble (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
- double ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override ulong GetUInt64 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ulong ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override long GetInt64 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- long ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override float GetFloat (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- float ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override int GetInt32 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- int ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override uint GetUInt32 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- uint ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override short GetInt16 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- short ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 2; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override ushort GetUInt16 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ushort ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 2; i++)
- b [i] = data [index+i];
-
- return ret;
- }
-
- public override void PutBytes (byte [] dest, int destIdx, double value)
- {
- Check (dest, destIdx, 8);
- fixed (byte *target = &dest [destIdx]){
- long *source = (long *) &value;
-
- *((long *)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, float value)
- {
- Check (dest, destIdx, 4);
- fixed (byte *target = &dest [destIdx]){
- uint *source = (uint *) &value;
-
- *((uint *)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, int value)
- {
- Check (dest, destIdx, 4);
- fixed (byte *target = &dest [destIdx]){
- uint *source = (uint *) &value;
-
- *((uint *)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, uint value)
- {
- Check (dest, destIdx, 4);
- fixed (byte *target = &dest [destIdx]){
- uint *source = (uint *) &value;
-
- *((uint *)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, long value)
- {
- Check (dest, destIdx, 8);
- fixed (byte *target = &dest [destIdx]){
- long *source = (long *) &value;
-
- *((long*)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, ulong value)
- {
- Check (dest, destIdx, 8);
- fixed (byte *target = &dest [destIdx]){
- ulong *source = (ulong *) &value;
-
- *((ulong *) target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, short value)
- {
- Check (dest, destIdx, 2);
- fixed (byte *target = &dest [destIdx]){
- ushort *source = (ushort *) &value;
-
- *((ushort *)target) = *source;
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, ushort value)
- {
- Check (dest, destIdx, 2);
- fixed (byte *target = &dest [destIdx]){
- ushort *source = (ushort *) &value;
-
- *((ushort *)target) = *source;
- }
- }
- }
-
- class SwapConverter : DataConverter {
- public override double GetDouble (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- double ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [7-i] = data [index+i];
-
- return ret;
- }
-
- public override ulong GetUInt64 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ulong ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [7-i] = data [index+i];
-
- return ret;
- }
-
- public override long GetInt64 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- long ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 8; i++)
- b [7-i] = data [index+i];
-
- return ret;
- }
-
- public override float GetFloat (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- float ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [3-i] = data [index+i];
-
- return ret;
- }
-
- public override int GetInt32 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- int ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [3-i] = data [index+i];
-
- return ret;
- }
-
- public override uint GetUInt32 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- uint ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 4; i++)
- b [3-i] = data [index+i];
-
- return ret;
- }
-
- public override short GetInt16 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- short ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 2; i++)
- b [1-i] = data [index+i];
-
- return ret;
- }
-
- public override ushort GetUInt16 (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ushort ret;
- byte *b = (byte *)&ret;
-
- for (int i = 0; i < 2; i++)
- b [1-i] = data [index+i];
-
- return ret;
- }
-
- public override void PutBytes (byte [] dest, int destIdx, double value)
- {
- Check (dest, destIdx, 8);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 8; i++)
- target [i] = source [7-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, float value)
- {
- Check (dest, destIdx, 4);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 4; i++)
- target [i] = source [3-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, int value)
- {
- Check (dest, destIdx, 4);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 4; i++)
- target [i] = source [3-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, uint value)
- {
- Check (dest, destIdx, 4);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 4; i++)
- target [i] = source [3-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, long value)
- {
- Check (dest, destIdx, 8);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 8; i++)
- target [i] = source [7-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, ulong value)
- {
- Check (dest, destIdx, 8);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 4; i++)
- target [i] = source [7-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, short value)
- {
- Check (dest, destIdx, 2);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 2; i++)
- target [i] = source [1-i];
- }
- }
-
- public override void PutBytes (byte [] dest, int destIdx, ushort value)
- {
- Check (dest, destIdx, 2);
-
- fixed (byte *target = &dest [destIdx]){
- byte *source = (byte *) &value;
-
- for (int i = 0; i < 2; i++)
- target [i] = source [1-i];
- }
- }
- }
-
-#if MONO_DATACONVERTER_STATIC_METHODS
- static unsafe void PutBytesLE (byte *dest, byte *src, int count)
- {
- int i = 0;
-
- if (BitConverter.IsLittleEndian){
- for (; i < count; i++)
- *dest++ = *src++;
- } else {
- dest += count;
- for (; i < count; i++)
- *(--dest) = *src++;
- }
- }
-
- static unsafe void PutBytesBE (byte *dest, byte *src, int count)
- {
- int i = 0;
-
- if (BitConverter.IsLittleEndian){
- dest += count;
- for (; i < count; i++)
- *(--dest) = *src++;
- } else {
- for (; i < count; i++)
- *dest++ = *src++;
- }
- }
-
- static unsafe void PutBytesNative (byte *dest, byte *src, int count)
- {
- int i = 0;
-
- for (; i < count; i++)
- dest [i-count] = *src++;
- }
-
- static public unsafe double DoubleFromLE (byte[] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- double ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe float FloatFromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- float ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe long Int64FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- long ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe ulong UInt64FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ulong ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe int Int32FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- int ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe uint UInt32FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- uint ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe short Int16FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- short ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- static public unsafe ushort UInt16FromLE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ushort ret;
- fixed (byte *src = &data[index]){
- PutBytesLE ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- static public unsafe double DoubleFromBE (byte[] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- double ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe float FloatFromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- float ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe long Int64FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- long ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe ulong UInt64FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ulong ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe int Int32FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- int ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe uint UInt32FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- uint ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe short Int16FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- short ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- static public unsafe ushort UInt16FromBE (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ushort ret;
- fixed (byte *src = &data[index]){
- PutBytesBE ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- static public unsafe double DoubleFromNative (byte[] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- double ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe float FloatFromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- float ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe long Int64FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- long ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe ulong UInt64FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 8)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ulong ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 8);
- }
- return ret;
- }
-
- static public unsafe int Int32FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- int ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe uint UInt32FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 4)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- uint ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 4);
- }
- return ret;
- }
-
- static public unsafe short Int16FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- short ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- static public unsafe ushort UInt16FromNative (byte [] data, int index)
- {
- if (data == null)
- throw new ArgumentNullException ("data");
- if (data.Length - index < 2)
- throw new ArgumentException ("index");
- if (index < 0)
- throw new ArgumentException ("index");
-
- ushort ret;
- fixed (byte *src = &data[index]){
- PutBytesNative ((byte *) &ret, src, 2);
- }
- return ret;
- }
-
- unsafe static byte[] GetBytesPtr (byte *ptr, int count)
- {
- byte [] ret = new byte [count];
-
- for (int i = 0; i < count; i++) {
- ret [i] = ptr [i];
- }
-
- return ret;
- }
-
- unsafe static byte[] GetBytesSwap (bool swap, byte *ptr, int count)
- {
- byte [] ret = new byte [count];
-
- if (swap){
- int t = count-1;
- for (int i = 0; i < count; i++) {
- ret [t-i] = ptr [i];
- }
- } else {
- for (int i = 0; i < count; i++) {
- ret [i] = ptr [i];
- }
- }
- return ret;
- }
-
- unsafe public static byte[] GetBytesNative (bool value)
- {
- return GetBytesPtr ((byte *) &value, 1);
- }
-
- unsafe public static byte[] GetBytesNative (char value)
- {
- return GetBytesPtr ((byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesNative (short value)
- {
- return GetBytesPtr ((byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesNative (int value)
- {
- return GetBytesPtr ((byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesNative (long value)
- {
- return GetBytesPtr ((byte *) &value, 8);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesNative (ushort value)
- {
- return GetBytesPtr ((byte *) &value, 2);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesNative (uint value)
- {
- return GetBytesPtr ((byte *) &value, 4);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesNative (ulong value)
- {
- return GetBytesPtr ((byte *) &value, 8);
- }
-
- unsafe public static byte[] GetBytesNative (float value)
- {
- return GetBytesPtr ((byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesNative (double value)
- {
- return GetBytesPtr ((byte *) &value, 8);
- }
-
- unsafe public static byte[] GetBytesLE (bool value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 1);
- }
-
- unsafe public static byte[] GetBytesLE (char value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesLE (short value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesLE (int value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesLE (long value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesLE (ushort value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesLE (uint value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesLE (ulong value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-
- unsafe public static byte[] GetBytesLE (float value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesLE (double value)
- {
- return GetBytesSwap (!BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-
- unsafe public static byte[] GetBytesBE (bool value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 1);
- }
-
- unsafe public static byte[] GetBytesBE (char value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesBE (short value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- unsafe public static byte[] GetBytesBE (int value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesBE (long value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesBE (ushort value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 2);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesBE (uint value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- [CLSCompliant (false)]
- unsafe public static byte[] GetBytesBE (ulong value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-
- unsafe public static byte[] GetBytesBE (float value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 4);
- }
-
- unsafe public static byte[] GetBytesBE (double value)
- {
- return GetBytesSwap (BitConverter.IsLittleEndian, (byte *) &value, 8);
- }
-#endif
-
- }
-}