protected unsafe void InitDna(byte[] bdnaOrg) { if (_dna != IntPtr.Zero) { return; } _dnaLength = bdnaOrg.Length; _dna = Marshal.AllocHGlobal(bdnaOrg.Length); Marshal.Copy(bdnaOrg, 0, _dna, _dnaLength); Stream stream = new UnmanagedMemoryStream((byte*)_dna.ToPointer(), _dnaLength); BinaryReader reader = new BinaryReader(stream); // SDNA byte[] code = reader.ReadBytes(8); string codes = ASCIIEncoding.ASCII.GetString(code); // NAME if (!codes.Equals("SDNANAME")) { throw new InvalidDataException(); } int dataLen = reader.ReadInt32(); _names = new Dna.NameInfo[dataLen]; for (int i = 0; i < dataLen; i++) { List<byte> name = new List<byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } _names[i] = new Dna.NameInfo(ASCIIEncoding.ASCII.GetString(name.ToArray())); } stream.Position = (stream.Position + 3) & ~3; // TYPE code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TYPE")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _types = new Dna.TypeDecl[dataLen]; for (int i = 0; i < dataLen; i++) { List<byte> name = new List<byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } string type = ASCIIEncoding.ASCII.GetString(name.ToArray()); _types[i] = new Dna.TypeDecl(type); } stream.Position = (stream.Position + 3) & ~3; // TLEN code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TLEN")) { throw new InvalidDataException(); } for (int i = 0; i < _types.Length; i++) { _types[i].Length = reader.ReadInt16(); } stream.Position = (stream.Position + 3) & ~3; // STRC code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("STRC")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _structs = new Dna.StructDecl[dataLen]; long shtPtr = stream.Position; for (int i = 0; i < dataLen; i++) { Dna.StructDecl structDecl = new Dna.StructDecl(); _structs[i] = structDecl; if (!BitConverter.IsLittleEndian) { throw new NotImplementedException(); } else { short typeNr = reader.ReadInt16(); structDecl.Type = _types[typeNr]; structDecl.Type.Struct = structDecl; int numElements = reader.ReadInt16(); structDecl.Elements = new Dna.ElementDecl[numElements]; for (int j = 0; j < numElements; j++) { typeNr = reader.ReadInt16(); short nameNr = reader.ReadInt16(); structDecl.Elements[j] = new Dna.ElementDecl(_types[typeNr], _names[nameNr]); } } } reader.Dispose(); stream.Dispose(); // build reverse lookups _structReverse = new Dictionary<string, Dna.StructDecl>(_structs.Length); foreach (Dna.StructDecl s in _structs) { _structReverse.Add(s.Type.Name, s); } }
protected unsafe void InitDna(byte[] bdnaOrg) { if (_dna != IntPtr.Zero) { return; } _dnaLength = bdnaOrg.Length; _dna = Marshal.AllocHGlobal(bdnaOrg.Length); Marshal.Copy(bdnaOrg, 0, _dna, _dnaLength); Stream stream = new UnmanagedMemoryStream((byte *)_dna.ToPointer(), _dnaLength); BinaryReader reader = new BinaryReader(stream); // SDNA byte[] code = reader.ReadBytes(8); string codes = ASCIIEncoding.ASCII.GetString(code); // NAME if (!codes.Equals("SDNANAME")) { throw new InvalidDataException(); } int dataLen = reader.ReadInt32(); _names = new Dna.NameInfo[dataLen]; for (int i = 0; i < dataLen; i++) { List <byte> name = new List <byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } _names[i] = new Dna.NameInfo(ASCIIEncoding.ASCII.GetString(name.ToArray())); } stream.Position = (stream.Position + 3) & ~3; // TYPE code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TYPE")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _types = new Dna.TypeDecl[dataLen]; for (int i = 0; i < dataLen; i++) { List <byte> name = new List <byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } string type = ASCIIEncoding.ASCII.GetString(name.ToArray()); _types[i] = new Dna.TypeDecl(type); } stream.Position = (stream.Position + 3) & ~3; // TLEN code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TLEN")) { throw new InvalidDataException(); } for (int i = 0; i < _types.Length; i++) { _types[i].Length = reader.ReadInt16(); } stream.Position = (stream.Position + 3) & ~3; // STRC code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("STRC")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _structs = new Dna.StructDecl[dataLen]; // NU long shtPtr = stream.Position; for (int i = 0; i < dataLen; i++) { Dna.StructDecl structDecl = new Dna.StructDecl(); _structs[i] = structDecl; if (!BitConverter.IsLittleEndian) { throw new NotImplementedException(); } else { short typeNr = reader.ReadInt16(); structDecl.Type = _types[typeNr]; structDecl.Type.Struct = structDecl; int numElements = reader.ReadInt16(); structDecl.Elements = new Dna.ElementDecl[numElements]; for (int j = 0; j < numElements; j++) { typeNr = reader.ReadInt16(); short nameNr = reader.ReadInt16(); structDecl.Elements[j] = new Dna.ElementDecl(_types[typeNr], _names[nameNr]); } } } reader.Dispose(); stream.Dispose(); // build reverse lookups _structReverse = new Dictionary <string, Dna.StructDecl>(_structs.Length); foreach (Dna.StructDecl s in _structs) { _structReverse.Add(s.Type.Name, s); } }