Exemple #1
0
        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;
        }