public static void Write(List <string> FileList, string outpath) { Directory.CreateDirectory(Path.GetDirectoryName(outpath)); using (var bw = new BinaryWriter(new FileStream(outpath, FileMode.Create))) { var data_array = BuildInfo(FileList); var buffersize = FileList.Max(x => new FileInfo(x).Length); if ((DataOffset + TotalDataSize(FileList) + GetNames(FileList).Length + GetInfo(FileList).Length) > 0xFFFFFFFF) //Switch to 64bit { Version = 2; DataOffset += 0x10; for (int i = 0; i < data_array.Count; i++) { data_array[i].PageOFfset = -1; } } if (buffersize <= CACHE_BUFFER_SIZE) { buffersize = CACHE_BUFFER_SIZE; } else { var fremainder = buffersize % CACHE_BUFFER_SIZE; buffersize += (CACHE_BUFFER_SIZE - fremainder); } bw.Write(Magic); bw.Write((UInt32)Version); date.Write(bw); if (Version >= 2) { bw.Write((UInt64)(DataOffset + TotalDataSize(FileList) + GetNames(FileList).Length)); bw.Write((UInt64)FileList.Count); bw.Write((UInt64)(DataOffset + TotalDataSize(FileList))); } else { bw.Write((UInt32)(DataOffset + TotalDataSize(FileList) + GetNames(FileList).Length)); bw.Write((UInt32)FileList.Count); bw.Write((UInt32)(DataOffset + TotalDataSize(FileList))); } bw.Write((UInt32)GetNames(FileList).Length); if (Version >= 2) { bw.Write((Unk3)); } bw.Write((UInt64)buffersize); bw.Write((CalculateChecksum(FileList))); //Write the actual contents of the files. for (int i = 0; i < FileList.Count; i++) { if (data_array[i].PageOFfset != -1) { using (var ms = new MemoryStream()) { new ZlibStream(new MemoryStream(File.ReadAllBytes(FileList[i])), CompressionMode.Compress).CopyTo(ms); bw.Write(ms.ToArray()); } } } //Write filenames and the offsets and such for the files. bw.Write(GetNames(FileList)); bw.Write(GetInfo(FileList)); } }
private void WriteHeader(BinaryWriter file) { file.BaseStream.Seek(0, SeekOrigin.Begin); file.Write(IDString); file.Write(FileVersion); file.Write(flags); Datetime.Write(file); file.Write(buildversion); file.Write(cr2wsize); file.Write(buffersize); file.Write(crc32); file.Write(numchunks); for (var i = 0; i < 10; i++) { headers[i].Write(file); } var stringbuffer_offset = (uint)file.BaseStream.Position; headers[0].offset = stringbuffer_offset; // Write string buffers var string_offsets = new Dictionary <string, uint>(); var new_string_offsets = new Dictionary <string, uint>(); // Add all strings to dictionary for (var i = 0; i < strings.Count; i++) { string_offsets.AddUnique(strings[i].str, strings[i].offset); } for (var i = 0; i < handles.Count; i++) { string_offsets.AddUnique(handles[i].str, handles[i].offset); } for (var i = 0; i < block7.Count; i++) { foreach (var str in block7[i].handles) { string_offsets.AddUnique(str, block7[i].handle_name_offset); } } // Write all strings foreach (var str in string_offsets) { var newoffset = ((uint)file.BaseStream.Position) - stringbuffer_offset; new_string_offsets.Add(str.Key, newoffset); file.WriteCR2WString(str.Key); } headers[0].size = ((uint)file.BaseStream.Position - stringbuffer_offset); // Update all offsets for (var i = 0; i < strings.Count; i++) { var newoffset = new_string_offsets.Get(strings[i].str); if (strings[i].offset != newoffset) { strings[i].offset = newoffset; } } for (var i = 0; i < handles.Count; i++) { var newoffset = new_string_offsets.Get(handles[i].str); if (newoffset != handles[i].offset) { handles[i].offset = newoffset; } } for (var i = 0; i < block7.Count; i++) { for (var j = 0; j < block7[i].handles.Count; j++) { var newoffset = new_string_offsets.Get(block7[i].handles[j]); if (newoffset != block7[i].handle_name_offset) { block7[i].handle_name_offset = newoffset; } } } headers[1].size = (uint)strings.Count; headers[1].offset = (uint)file.BaseStream.Position; for (var i = 0; i < strings.Count; i++) { strings[i].Write(file); } headers[2].size = (uint)handles.Count; headers[2].offset = (uint)file.BaseStream.Position; for (var i = 0; i < handles.Count; i++) { handles[i].Write(file); } headers[3].size = (uint)block4.Count; headers[3].offset = (uint)file.BaseStream.Position; for (var i = 0; i < block4.Count; i++) { block4[i].Write(file); } headers[4].size = (uint)chunks.Count; headers[4].offset = (uint)file.BaseStream.Position; for (var i = 0; i < chunks.Count; i++) { chunks[i].offset += headerOffset; chunks[i].Write(file); } headers[5].size = (uint)block6.Count; headers[5].offset = (uint)file.BaseStream.Position; for (var i = 0; i < block6.Count; i++) { block6[i].Write(file); } headers[6].size = (uint)block7.Count; headers[6].offset = (uint)file.BaseStream.Position; for (var i = 0; i < block7.Count; i++) { block7[i].offset += headerOffset; block7[i].Write(file); } }