public BinaryReader GetSectionData(int sectionID) { if (sectionID < Header.SectionCount) { CaffSection tmpSection = Sections[sectionID]; bStream.BaseStream.Seek(tmpSection.Offset, SeekOrigin.Begin); if (tmpSection.CompressedSize != tmpSection.DecompressedSize) { #if CAFF_SECTIONS_IN_MEMORY ZlibStream zs = new ZlibStream(bStream.BaseStream, CompressionMode.Decompress, CompressionLevel.BestCompression); byte[] decompressedData = new byte[tmpSection.DecompressedSize]; MemoryStream ms = new MemoryStream(decompressedData); zs.CopyTo(ms); return(new BinaryReader(ms)); #else var fs = new FileStream(FileName + tmpSection.Name, FileMode.OpenOrCreate); var zs = new ZlibStream(bStream.BaseStream, CompressionMode.Decompress, CompressionLevel.BestCompression); zs.CopyTo(fs); var bs = new BinaryReader(fs); return(bs); #endif } else { #if CAFF_SECTIONS_IN_MEMORY byte[] decompressedData = new byte[tmpSection.DecompressedSize]; bStream.Read(decompressedData, 0, tmpSection.DecompressedSize); MemoryStream ms = new MemoryStream(decompressedData); return(new BinaryReader(ms)); #else var fs = new FileStream(FileName + tmpSection.Name, FileMode.OpenOrCreate); var buffer = new byte[0x800]; int bytesRead = 0; while (bytesRead < tmpSection.DecompressedSize) { var toRead = Math.Min(tmpSection.DecompressedSize - bytesRead, 0x800); var readNow = bStream.Read(buffer, 0, toRead); if (readNow == 0) { break; } fs.Write(buffer, 0, readNow); bytesRead += readNow; } fs.Seek(0, SeekOrigin.Begin); return(new BinaryReader(fs)); #endif } } return(null); }
public bool Read(string _fileName, MainForm.UpdateStatusDelegate UpdateDelegate = null) { FileName = _fileName; TreeViewNode = new TreeNode(Path.GetFileName(FileName)); TreeViewNode.Tag = new TreeNodeTag(this, 0, 0, 0, TreeNodeTag.NodeType.File); FileStream fs = new FileStream(_fileName, FileMode.Open); bStream = new BinaryReader(fs); Header.HeaderString = IO.ReadStringF(bStream, 0x14); if (Header.HeaderString != "CAFF28.01.05.0031") { Logger.LogError("Error reading Caff File, Header section mismatch.\n"); return(false); } Header.Unk1 = IO.ReadBig32(bStream); //0x14 Header.FileCount = IO.ReadBig32(bStream); //0x18 Header.TocEntryCount = IO.ReadBig32(bStream); //0x1c Header.Unk4 = IO.ReadBig32(bStream); //0x20 Header.Unk5 = IO.ReadBig32(bStream); Header.Unk6 = IO.ReadBig32(bStream); Header.Unk7 = IO.ReadBig32(bStream); Header.Unk8 = IO.ReadBig32(bStream); //0x30 Header.TocOffset = IO.ReadBig32(bStream); Header.SectionStartOffset = IO.ReadBig32(bStream); Header.Unk11 = IO.ReadByte(bStream); Header.SectionCount = IO.ReadByte(bStream); Header.Unk13 = IO.ReadByte(bStream); Header.Unk14 = IO.ReadByte(bStream); Sections = new CaffSection[Header.SectionCount]; int sectionOffset = Header.SectionStartOffset; for (int i = 0; i < Header.SectionCount; i++) { CaffSection tmpSection = new CaffSection(); tmpSection.Name = IO.ReadString(bStream); IO.Align(bStream, 4); int tmpSectionType = IO.ReadBig32(bStream); switch (tmpSectionType) { case SECTION_TYPE_DATA: { tmpSection.Type = SectionType.Data; break; } case SECTION_TYPE_GPU: { tmpSection.Type = SectionType.GPU; break; } case SECTION_TYPE_STREAM: { tmpSection.Type = SectionType.Stream; break; } default: { Logger.LogError(string.Format("Error reading Caff File, Unknown caff section type {0:X} at 0x{1:X}", tmpSectionType, (int)bStream.BaseStream.Position)); return(false); } } tmpSection.Flags = IO.ReadBig32(bStream); tmpSection.DecompressedSize = IO.ReadBig32(bStream); tmpSection.Unk5 = IO.ReadBig32(bStream); tmpSection.Unk6 = IO.ReadBig32(bStream); tmpSection.Unk7 = IO.ReadBig32(bStream); tmpSection.Unk8 = IO.ReadBig32(bStream); tmpSection.CompressedSize = IO.ReadBig32(bStream); tmpSection.Offset = sectionOffset; Sections[i] = tmpSection; //If section isn't comrpessed, then CompressedSize and DecompressedSize will match anyways. sectionOffset += tmpSection.CompressedSize; } ReadContents(UpdateDelegate); return(true); }