Небезопасный код. Битовое чтение файла и преобразование к определенному формату - C#
Формулировка задачи:
Доброго времени суток.
Решаю задачу битового чтения файла и преобразование к определенному формату.
Реализовал следующим образом
Подскажите пожалуйста есть ли более оптимальная реализация.
А то приходится создавать два буфера и производить чтение буфера, копирование в другой буфер и
потом только преобразовать к структуре.
Может можно попроще, а то я неуверен. Заранее спасибо за ответы
[StructLayout(LayoutKind.Sequential)]
struct SHP_Header
{
int FileCode;
.........
double Mmax;
}
private SHP_Header ReadHeader()
{
byte[] buffer = new byte[100];
fileStram.Read(buffer, 0, 100);
SHP_Header l_header=new SHP_Header();
unsafe
{
IntPtr ptr = Marshal.AllocHGlobal(100);
Marshal.Copy(buffer, 0, ptr, 100);
l_header = (SHP_Header) Marshal.PtrToStructure(ptr,typeof(SHP_Header));
}
return l_header;
}Решение задачи: «Небезопасный код. Битовое чтение файла и преобразование к определенному формату»
textual
Листинг программы
enum ShapeType
{
NullShape = 0,
Point = 1,
PolyLine = 3,
Polygon = 5,
MultiPoint = 8,
PointZ = 11,
PolyLineZ = 13,
PolygonZ = 15,
MultiPointZ = 18,
PointM = 21,
PolyLineM = 23,
PolygonM = 25,
MultiPointM = 28,
MultiPatch = 31
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
unsafe struct ShpHeader
{
public int FileCode;
private fixed int Unused [5];
public int FileLength;
public int Version;
public ShapeType ShapeType;
public double Xmin;
public double Ymin;
public double Xmax;
public double Ymax;
public double Zmin;
public double Zmax;
public double Mmin;
public double Mmax;
}
unsafe static class DataTransformer
{
public static ushort EndianSwap ( ushort x )
{
return (ushort)((x >> 8) | (x << 8));
}
public static int EndianSwap ( int x )
{
return (x >> 24) |
((x << 8) & 0x00FF0000) |
((x >> 8) & 0x0000FF00) |
(x << 24);
}
public static long EndianSwap ( long x )
{
return (x >> 56) |
((x << 40) & 0x00FF000000000000) |
((x << 24) & 0x0000FF0000000000) |
((x << 8) & 0x000000FF00000000) |
((x >> 8) & 0x00000000FF000000) |
((x >> 24) & 0x0000000000FF0000) |
((x >> 40) & 0x000000000000FF00) |
(x << 56);
}
}
public unsafe class ShpReader
{
private ShpHeader mHeader;
private readonly Stream mStream;
private byte[] mBuffer;
public ShpReader ( Stream stream )
: this()
{
mStream = stream;
ReadHeader();
}
private ShpReader ( )
{
mBuffer = new byte[4096];
}
private void ReadHeader ( )
{
mStream.Read( mBuffer, 0, mBuffer.Length );
fixed ( byte* ptr = mBuffer )
mHeader = *(ShpHeader*)ptr;
mHeader.FileCode = DataTransformer.EndianSwap( mHeader.FileCode );
mHeader.FileLength = DataTransformer.EndianSwap( mHeader.FileLength );
}
}