本人在读取shape文件时,有些字段是big endian的,有些时little endian的。
编写读取shape文件的高手应该很多了,两者之间的转换这类问题也应该解决了,
本人是新手,到网上搜了搜,也搜到一些相关的源码,但都看不懂,故请求把big endian转换成little endian的C#源码!!
非常感谢。
编写读取shape文件的高手应该很多了,两者之间的转换这类问题也应该解决了,
本人是新手,到网上搜了搜,也搜到一些相关的源码,但都看不懂,故请求把big endian转换成little endian的C#源码!!
非常感谢。
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; }
}
}
}
{
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;
}
}
{
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;
}
}
_buffer[i] = (_buffer[i] << 8) | (_buffer[i] >> 8);对于little endian则反向操作就是了。