Mercurial > repos > RelicTools > RelicTools
view RelicChunkyReader.cs @ 0:82db9430c2e4 default tip
Initial commit under GPLv3
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 06 Oct 2018 19:49:25 +0100 |
parents | |
children |
line wrap: on
line source
// This file is a part of the Relic Tools and is copyright 2006-2018 IBBoard. // // The file and the library/program it is in are licensed under the GNU GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. using System; using System.Collections; using System.IO; using System.Text; using IBBoard.Relic.RelicTools.Collections; using IBBoard.Relic.RelicTools.Exceptions; namespace IBBoard.Relic.RelicTools { /// <summary> /// Summary description for RelicChunkyReader. /// </summary> public class RelicChunkyReader { public static RelicChunkyFile ReadChunkyFile(string filepath) { if (!File.Exists(filepath)) { throw new RelicTools.Exceptions.FileNotFoundException("No 'RelicChunky' file found at "+filepath); } FileInfo chunkyFile = new FileInfo(filepath); BinaryReader br = new BinaryReader(chunkyFile.OpenRead()); byte[] start = br.ReadBytes(4); int version = 0; string fileType = ""; if (start[1] == 0 && start[2] == 0 && start[3] == 0) { version = start[0]; fileType = ReadString(br, 4, 8); } else { br.BaseStream.Seek(0, SeekOrigin.Begin); } ChunkyStructureCollection structCol = ReadChunkyFileStructure(br); br.Close(); string filename = filepath.Substring(filepath.LastIndexOf(Path.DirectorySeparatorChar)+1); if (filepath.EndsWith(".rec")) { return new RECFile(filename, structCol, version, fileType); } else if (structCol.Count==1 && structCol[0].RootChunks[0].ID=="TPAT") { return new WTPFile(filename, structCol); } else if (structCol.Count==1 && structCol[0].RootChunks[0].ID=="SHRF") { return new RSHFile(filename, structCol); } else if (structCol.Count==1 && structCol[0].RootChunks[0].ID=="TXTR") { return new RTXFile(filename, structCol); } else { return new RelicChunkyFile(filename, structCol); } } private static ChunkyStructureCollection ReadChunkyFileStructure(BinaryReader br) { string name = ""; name = ReadString(br, (int)br.BaseStream.Position, 12); if (name!="Relic Chunky") { /*if (name == "Relic Chunky") { //handle REC files which are chunkys with data at the start br.BaseStream.Seek(0, SeekOrigin.Begin); //version = br.ReadInt32(); //fileType = ReadString(br, 4, 8); br.BaseStream.Seek(12, SeekOrigin.Current); //skip the name string we just read } else {*/ throw new InvalidFileException("File was not recognised as a valid RelicChunky File");//"File '"+filepath+"' was not recognised as a valid RelicChunky File"); } //} return ReadChunkyStructure(br, br.BaseStream.Length); } private static ChunkyStructureCollection ReadChunkyStructure(BinaryReader br, long fileLength) { //long end = fileLength - 20; ChunkyStructureCollection structCol = new ChunkyStructureCollection(); int unknown1 = br.ReadInt32(); int unknown2 = br.ReadInt32(); int unknown3 = br.ReadInt32(); byte[] bytes = br.ReadBytes((int)(fileLength-br.BaseStream.Position)); structCol.Add(new RelicChunkyStructure(RelicChunkReader.ReadChunkyChunks(bytes), unknown1, unknown2, unknown3)); if (RelicChunkReader.HasRemainingBytes()) { byte[] remainingData = RelicChunkReader.GetRemainingBytes(); if (remainingData[0]==0x52 && remainingData[1]==0x65 && remainingData[2]==0x6C && remainingData[3]==0x69) { MemoryStream ms = new MemoryStream(remainingData); BinaryReader br2 = new BinaryReader(ms); ChunkyStructureCollection col = ReadChunkyFileStructure(br2); foreach (RelicChunkyStructure strct in col) { structCol.Add(strct); } } else { ChunkyCollection col = new ChunkyCollection(); col.Add(new ChunkyRawData(remainingData)); structCol.Add(new RelicChunkyStructure(col)); } } return structCol; } /// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="length"></param> /// <returns></returns> private static string ReadString(BinaryReader br, int start, int length) { StringBuilder str = new StringBuilder(); byte tempByte = 0; br.BaseStream.Seek(start, SeekOrigin.Begin); if (length>0) { for (int i = 0; i<length; i++) { tempByte = br.ReadByte(); if (tempByte>=30) str.Append((char)tempByte); } } else { try { do { tempByte = br.ReadByte(); if (tempByte>=30) str.Append((char)tempByte); } while (tempByte!=0); } catch{} } return str.ToString(); } } }