internal object ReadField(long dataOffset, Partition.FieldDefinitionEntry field) { lock (this._DataLock) { this._Data.Position = dataOffset + field.DataOffset; return(this.ReadData(field.TypeIndex, field.Flags)); } }
public void Deserialize(Stream input) { var basePosition = input.Position; var magic = input.ReadValueU32(Endian.Little); if (magic != Signature && magic.Swap() != Signature) { throw new FormatException(); } var endian = magic == Signature ? Endian.Little : Endian.Big; var headerSize = input.ReadValueU32(endian); if (basePosition + headerSize > input.Length) { throw new EndOfStreamException(); } var dataSize = input.ReadValueU32(endian); if (basePosition + headerSize + dataSize > input.Length) { throw new EndOfStreamException(); } var importCount = input.ReadValueU32(endian); var instanceCount = input.ReadValueU16(endian); var namedInstanceCount = input.ReadValueU16(endian); var exportedInstanceCount = input.ReadValueU16(endian); var typeDefinitionCount = input.ReadValueU16(endian); var fieldDefinitionCount = input.ReadValueU16(endian); var nameTableSize = input.ReadValueU16(endian); var stringTableSize = input.ReadValueU32(endian); var arrayCount = input.ReadValueU32(endian); var arrayOffset = input.ReadValueU32(endian); var guid = input.ReadValueGuid(endian); input.Seek(8, SeekOrigin.Current); var computedHeaderSize = 64 + (importCount * 32) + nameTableSize + (fieldDefinitionCount * 16) + (typeDefinitionCount * 16) + (instanceCount * 4).Align(16) + (arrayCount * 12).Align(16); if (computedHeaderSize != headerSize) { throw new FormatException(); } var importEntries = new Partition.ImportEntry[importCount]; for (int i = 0; i < importCount; i++) { importEntries[i] = Partition.ImportEntry.Read(input, endian); } var nameTableBytes = input.ReadBytes(nameTableSize); var names = new List <string>(); using (var data = new MemoryStream(nameTableBytes, false)) { while (data.Position < data.Length) { names.Add(data.ReadStringZ(Encoding.UTF8)); } } // TODO(gibbed): do this better. var hashesToNames = names.Distinct().ToDictionary(Common.Hashing.DJB.Compute, s => s); var fieldDefinitionEntries = new Partition.FieldDefinitionEntry[fieldDefinitionCount]; for (int i = 0; i < fieldDefinitionCount; i++) { var fieldDefinitionEntry = fieldDefinitionEntries[i] = Partition.FieldDefinitionEntry.Read(input, endian); if (fieldDefinitionEntry.Flags.UnknownFlags2 != 0) { throw new FormatException(); } fieldDefinitionEntries[i].Name = hashesToNames[fieldDefinitionEntries[i].NameHash]; } var typeDefinitionEntries = new Partition.TypeDefinitionEntry[typeDefinitionCount]; for (int i = 0; i < typeDefinitionCount; i++) { var typeDefinitionEntry = typeDefinitionEntries[i] = Partition.TypeDefinitionEntry.Read(input, endian); if (typeDefinitionEntry.Flags.UnknownFlags2 != 0) { throw new FormatException(); } typeDefinitionEntries[i].Name = hashesToNames[typeDefinitionEntries[i].NameHash]; } var instancePadding = (instanceCount * 4).Padding(16); var instanceEntries = new Partition.InstanceEntry[instanceCount]; for (int i = 0; i < instanceCount; i++) { instanceEntries[i] = Partition.InstanceEntry.Read(input, endian); } input.Seek(instancePadding, SeekOrigin.Current); var arrayPadding = (arrayCount * 12).Padding(16); var arrayEntries = new Partition.ArrayEntry[arrayCount]; for (int i = 0; i < arrayCount; i++) { arrayEntries[i] = Partition.ArrayEntry.Read(input, endian); } input.Seek(arrayPadding, SeekOrigin.Current); if (basePosition + headerSize != input.Position) { throw new FormatException(); } var dataBytes = input.ReadBytes(dataSize); this._ImportEntries.Clear(); this._FieldDefinitionEntries.Clear(); this._TypeDefinitionEntries.Clear(); this._InstanceEntries.Clear(); this._ArrayEntries.Clear(); this._Endian = endian; this._Guid = guid; this._ImportEntries.AddRange(importEntries); this._NameTableBytes = nameTableBytes; this._FieldDefinitionEntries.AddRange(fieldDefinitionEntries); this._TypeDefinitionEntries.AddRange(typeDefinitionEntries); this._InstanceEntries.AddRange(instanceEntries); this._ArrayEntries.AddRange(arrayEntries); this._NamedInstanceCount = namedInstanceCount; this._ExportedInstanceCount = exportedInstanceCount; this._StringTableSize = stringTableSize; this._ArrayOffset = arrayOffset; this._DataBytes = dataBytes; }