本人在读取shape文件时,有些字段是big endian的,有些时little endian的。
编写读取shape文件的高手应该很多了,两者之间的转换这类问题也应该解决了,
本人是新手,到网上搜了搜,也搜到一些相关的源码,但都看不懂,故请求把big endian转换成little endian的C#源码!!
       非常感谢。

解决方案 »

  1.   


    public abstract class EndianBitConverter
    { public abstract bool IsLittleEndian();
    public abstract Endianness Endianness { get; } static LittleEndianBitConverter little = new LittleEndianBitConverter();
    public static LittleEndianBitConverter Little
    {
    get { return little; }
    } static BigEndianBitConverter big = new BigEndianBitConverter();
    public static BigEndianBitConverter Big
    {
    get { return big; }
    }
    public long DoubleToInt64Bits(double value)
    {
    return BitConverter.DoubleToInt64Bits(value);
    } public double Int64BitsToDouble (long value)
    {
    return BitConverter.Int64BitsToDouble(value);
    } public int SingleToInt32Bits(float value)
    {
    return new Int32SingleUnion(value).AsInt32;
    } public float Int32BitsToSingle (int value)
    {
    return new Int32SingleUnion(value).AsSingle;
    }
    public bool ToBoolean (byte[] value, int startIndex)
    {
    CheckByteArgument(value, startIndex, 1);
    return BitConverter.ToBoolean(value, startIndex);
    }
    public char ToChar (byte[] value, int startIndex)
    {
    return unchecked((char) (CheckedFromBytes(value, startIndex, 2)));
    }
    public double ToDouble (byte[] value, int startIndex)
    {
    return Int64BitsToDouble(ToInt64(value, startIndex));
    } public float ToSingle (byte[] value, int startIndex)
    {
    return Int32BitsToSingle(ToInt32(value, startIndex));
    } public short ToInt16 (byte[] value, int startIndex)
    {
    return unchecked((short) (CheckedFromBytes(value, startIndex, 2)));
    } public int ToInt32 (byte[] value, int startIndex)
    {
    return unchecked((int) (CheckedFromBytes(value, startIndex, 4)));
    }
    public long ToInt64 (byte[] value, int startIndex)
    {
    return CheckedFromBytes(value, startIndex, 8);
    }
    public ushort ToUInt16 (byte[] value, int startIndex)
    {
    return unchecked((ushort) (CheckedFromBytes(value, startIndex, 2)));
    } public uint ToUInt32 (byte[] value, int startIndex)
    {
    return unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));
    } public ulong ToUInt64 (byte[] value, int startIndex)
    {
    return unchecked((ulong) (CheckedFromBytes(value, startIndex, 8)));
    } static void CheckByteArgument(byte[] value, int startIndex, int bytesRequired)
    {
    if (value==null)
    {
    throw new ArgumentNullException("value");
    }
    if (startIndex < 0 || startIndex > value.Length-bytesRequired)
    {
    throw new ArgumentOutOfRangeException("startIndex");
    }
    }        long CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)
    {
    CheckByteArgument(value, startIndex, bytesToConvert);
    return FromBytes(value, startIndex, bytesToConvert);
    } protected abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);
    public static string ToString(byte[] value)
    {
    return BitConverter.ToString(value);
    }
    public static string ToString(byte[] value, int startIndex)
    {
    return BitConverter.ToString(value, startIndex);
    } public static string ToString(byte[] value, int startIndex, int length)
    {
    return BitConverter.ToString(value, startIndex, length);
    }
    public decimal ToDecimal (byte[] value, int startIndex)
    {
    int[] parts = new int[4];
    for (int i=0; i < 4; i++)
    {
    parts[i] = ToInt32(value, startIndex+i*4);
    }
    return new Decimal(parts);
    } public byte[] GetBytes(decimal value)
    {
    byte[] bytes = new byte[16];
    int[] parts = decimal.GetBits(value);
    for (int i=0; i < 4; i++)
    {
    CopyBytesImpl(parts[i], 4, bytes, i*4);
    }
    return bytes;
    } public void CopyBytes(decimal value, byte[] buffer, int index)
    {
    int[] parts = decimal.GetBits(value);
    for (int i=0; i < 4; i++)
    {
    CopyBytesImpl(parts[i], 4, buffer, i*4+index);
    }
    }
    byte[] GetBytes(long value, int bytes)
    {
    byte[] buffer = new byte[bytes];
    CopyBytes(value, bytes, buffer, 0);
    return buffer;
    } public byte[] GetBytes(bool value)
    {
    return BitConverter.GetBytes(value);
    } public byte[] GetBytes(char value)
    {
    return GetBytes(value, 2);
    } public byte[] GetBytes(double value)
    {
    return GetBytes(DoubleToInt64Bits(value), 8);
    }

    public byte[] GetBytes(short value)
    {
    return GetBytes(value, 2);
    } public byte[] GetBytes(int value)
    {
    return GetBytes(value, 4);
    } public byte[] GetBytes(long value)
    {
    return GetBytes(value, 8);
    } public byte[] GetBytes(float value)
    {
    return GetBytes(SingleToInt32Bits(value), 4);
    } public byte[] GetBytes(ushort value)
    {
    return GetBytes(value, 2);
    } public byte[] GetBytes(uint value)
    {
    return GetBytes(value, 4);
    } public byte[] GetBytes(ulong value)
    {
    return GetBytes(unchecked((long)value), 8);
    } void CopyBytes(long value, int bytes, byte[] buffer, int index)
    {
    if (buffer==null)
    {
    throw new ArgumentNullException("buffer", "Byte array must not be null");
    }
    if (buffer.Length < index+bytes)
    {
    throw new ArgumentOutOfRangeException("Buffer not big enough for value");
    }
    CopyBytesImpl(value, bytes, buffer, index);
    } public void CopyBytes(bool value, byte[] buffer, int index)
    {
    CopyBytes(value ? 1 : 0, 1, buffer, index);
    } public void CopyBytes(char value, byte[] buffer, int index)
    {
    CopyBytes(value, 2, buffer, index);
    } public void CopyBytes(double value, byte[] buffer, int index)
    {
    CopyBytes(DoubleToInt64Bits(value), 8, buffer, index);
    }
    public void CopyBytes(short value, byte[] buffer, int index)
    {
    CopyBytes(value, 2, buffer, index);
    }
                    public void CopyBytes(int value, byte[] buffer, int index)
    {
    CopyBytes(value, 4, buffer, index);
    }
    public void CopyBytes(long value, byte[] buffer, int index)
    {
    CopyBytes(value, 8, buffer, index);
    } public void CopyBytes(float value, byte[] buffer, int index)
    {
    CopyBytes(SingleToInt32Bits(value), 4, buffer, index);
    }
    public void CopyBytes(ushort value, byte[] buffer, int index)
    {
    CopyBytes(value, 2, buffer, index);
    } public void CopyBytes(uint value, byte[] buffer, int index)
    {
    CopyBytes(value, 4, buffer, index);
    } public void CopyBytes(ulong value, byte[] buffer, int index)
    {
    CopyBytes(unchecked((long)value), 8, buffer, index);
    } [StructLayout(LayoutKind.Explicit)]
    struct Int32SingleUnion
    {
    /// <summary>
    /// Int32 version of the value.
    /// </summary>
    [FieldOffset(0)]
    int i;
    /// <summary>
    /// Single version of the value.
    /// </summary>
    [FieldOffset(0)]
    float f;
    internal Int32SingleUnion(int i)
    {
    this.f = 0; // Just to keep the compiler happy
    this.i = i;
    } internal Int32SingleUnion(float f)
    {
    this.i = 0; // Just to keep the compiler happy
    this.f = f;
    } internal int AsInt32
    {
    get { return i; }
    } internal float AsSingle
    {
    get { return f; }
    }
    }
    }
      

  2.   

    internal sealed class BigEndianBitConverter : EndianBitConverter
    {
    public sealed override bool IsLittleEndian()
    {
    return false;
    } public sealed override Endianness Endianness 

    get { return Endianness.BigEndian; }
    } protected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)
    {
    int endOffset = index+bytes-1;
    for (int i=0; i < bytes; i++)
    {
    buffer[endOffset-i] = unchecked((byte)(value&0xff));
    value = value >> 8;
    }
    }

    protected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
    {
    long ret = 0;
    for (int i=0; i < bytesToConvert; i++)
    {
    ret = unchecked((ret << 8) | buffer[startIndex+i]);
    }
    return ret;
    }
    }
      

  3.   

    四楼是继承三楼的类,忘了用代码形式了,重发一遍internal sealed class BigEndianBitConverter : EndianBitConverter
    {
    public sealed override bool IsLittleEndian()
    {
    return false;
    } public sealed override Endianness Endianness 

    get { return Endianness.BigEndian; }
    } protected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)
    {
    int endOffset = index+bytes-1;
    for (int i=0; i < bytes; i++)
    {
    buffer[endOffset-i] = unchecked((byte)(value&0xff));
    value = value >> 8;
    }
    }

    protected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
    {
    long ret = 0;
    for (int i=0; i < bytesToConvert; i++)
    {
    ret = unchecked((ret << 8) | buffer[startIndex+i]);
    }
    return ret;
    }
    }
      

  4.   

    对于big endian类型的,其实主要的代码就如下一句:
    _buffer[i] = (_buffer[i] << 8) | (_buffer[i] >> 8);对于little endian则反向操作就是了。