private void FixBufferCRC32(ref CR2WBuffer buffer) { //This might throw errors, the way it should be checked for is by reading //the object tree to find the deferred data buffers that will point to a buffer. //The flag of the parent object indicates where to read the data from. //For now this is a crude workaround. if (m_hasInternalBuffer) { m_stream.Seek(buffer.offset, SeekOrigin.Begin); m_temp = new byte[buffer.diskSize]; m_stream.Read(m_temp, 0, m_temp.Length); buffer.crc32 = Crc32Algorithm.Compute(m_temp); } else { var path = String.Format("{0}.{1}.buffer", m_filePath, buffer.index); if (!File.Exists(path)) { return; } m_temp = File.ReadAllBytes(path); buffer.crc32 = Crc32Algorithm.Compute(m_temp); } }
public void Read(BinaryReader file) { m_stream = file.BaseStream; #region Read Headers var id = ReadStruct <uint>(); if (id != MAGIC) { throw new FormatException($"Not a CR2W file, Magic read as 0x{id:X8}"); } m_fileheader = ReadStruct <CR2WFileHeader>(); if (m_fileheader.version > 163 || m_fileheader.version < 159) { throw new FormatException($"Unknown Version {m_fileheader.version}. Supported versions: 159 - 163."); } var dt = new CDateTime(m_fileheader.timeStamp); m_hasInternalBuffer = m_fileheader.bufferSize > m_fileheader.fileSize; m_tableheaders = ReadStructs <CR2WTableHeader>(10); m_strings = ReadStringsBuffer(); m_names = ReadTable <CR2WName>(1); m_imports = ReadTable <CR2WImportHeader>(2); m_table4 = ReadTable <CR2WTable4Item>(3); m_exports = ReadTable <CR2WExportHeader>(4); m_buffers = ReadTable <CR2WBufferHeader>(5); m_embedded = ReadTable <CR2WEmbeddedHeader>(6); #endregion #region Read Data // read Name data names = (from n in m_names let str = new CR2WString() { hash = n.hash, offset = n.value, str = m_dictionary[n.value] } select str).ToList(); // Read Handle data (imports) imports = (from i in m_imports let handle = new CR2WHandle() { offset = i.depotPath, filetype = i.className, flags = i.flags, str = m_dictionary[i.depotPath] } select handle).ToList(); // Read Chunk data (exports) chunks = new List <CR2WChunk>(); foreach (var c in m_exports) { var chunk = new CR2WChunk(this) { typeId = c.className, Flags = c.objectFlags, ParentChunkId = c.parentID, size = c.dataSize, offset = c.dataOffset, template = c.template, crc = c.crc32 }; chunks.Add(chunk); chunk.ReadData(file); } // Read Buffer Data (block 6) buffers = new List <CR2WBuffer>(); foreach (var b in m_buffers) { var buffer = new CR2WBuffer() { flags = b.flags, index = b.index, offset = b.offset, size = b.diskSize, memsize = b.memSize, crc = b.crc32 }; buffers.Add(buffer); } // Read Embedded Data (Block 7) embedded = new List <CR2WEmbedded>(); foreach (var e in m_embedded) { var emb = new CR2WEmbedded() { handle_name_count = e.importIndex, handle_name_offset = e.path, pathHash = e.pathHash, offset = e.dataOffset, size = e.dataSize }; var offset = e.path; for (int i = 0; i < e.importIndex; i++) { if (offset > m_dictionary.Last().Key) { continue; } emb.handles.Add(m_dictionary[offset]); offset += (uint)m_dictionary[offset].Length + 1; } embedded.Add(emb); emb.ReadData(file); } #endregion #region Read Buffer file.BaseStream.Seek(m_fileheader.fileSize, SeekOrigin.Begin); var actualbuffersize = (int)(m_fileheader.bufferSize - m_fileheader.fileSize); if (actualbuffersize > 0) { bufferdata = new byte[actualbuffersize]; file.BaseStream.Read(bufferdata, 0, actualbuffersize); } #endregion m_stream = null; }