static List <ArzRecordHeader> readRecordHeadersTable(Stream s, long tableStartOffset, int entries, List <string> stringTable) { var recordHeadersTable = new List <ArzRecordHeader>(); s.Seek(tableStartOffset, SeekOrigin.Begin); System.IO.BinaryReader reader = new System.IO.BinaryReader(s); for (int i = 0; i < entries; i++) { var recordHeader = new ArzRecordHeader(); recordHeader.filename = stringTable[reader.ReadInt32()]; var typeLength = reader.ReadInt32(); recordHeader.type = Encoding.ASCII.GetString(reader.ReadBytes(typeLength)); recordHeader.dataOffset = reader.ReadUInt32(); recordHeader.dataCompressedSize = reader.ReadInt32(); recordHeader.dataDecompressedSize = reader.ReadInt32(); s.Seek(8, SeekOrigin.Current); // There not sure what the next 8 bytes are for recordHeadersTable.Add(recordHeader); } return(recordHeadersTable); }
internal static Dictionary <string, object> readRecord(Stream s, ArzRecordHeader recordHeader, List <string> stringTable, bool ignoreZeroedFields = true) { // Prep where we're going to store the compressed bytes, taken directly from the file byte[] compressedBytes = new byte[recordHeader.dataCompressedSize]; // Go to the correct file location and read // FIXME!!! Magic number 24 is the size of the file header on disk. // It'd be really nice for CLR to be able to just give me that size so the number doesn't have to be hard coded here. s.Seek(recordHeader.dataOffset + 24, SeekOrigin.Begin); s.Read(compressedBytes, 0, recordHeader.dataCompressedSize); // Decompress the data byte[] decompressedBytes = LZ4.LZ4Codec.Decode(compressedBytes, 0, compressedBytes.Length, recordHeader.dataDecompressedSize); MemoryStream recordStream = new MemoryStream(decompressedBytes); BinaryReader reader = new BinaryReader(recordStream); var record = new Dictionary <string, object>(); while (recordStream.Position < recordStream.Length) { var dataType = reader.ReadUInt16(); var dataCount = reader.ReadUInt16(); var dataFieldnameIndex = reader.ReadInt32(); var fieldName = stringTable[dataFieldnameIndex]; for (int i = 0; i < dataCount; i++) { object val = null; switch (dataType) { case 0: case 3: default: val = reader.ReadUInt32(); if (ignoreZeroedFields && (uint)val == 0) { continue; } break; case 1: val = reader.ReadSingle(); if (ignoreZeroedFields && (Single)val == 0.0) { continue; } break; case 2: val = stringTable[reader.ReadInt32()]; if (ignoreZeroedFields && (string)val == String.Empty) { continue; } break; } record[fieldName] = val; } } return(record); }