//Takes the file, splits it based upon which pointer accesses it. //Also modifies all pointers to be 0-based! public PointeredFile(string inFilename, byte[] rawData, byte[] subHeader, int[] ptrs, int baseAddr, bool useAsBigEndian) { isBigEndian = useAsBigEndian; header = subHeader; filename = inFilename; fileLength = BitConverter.ToInt32(rawData, 4); if (ptrs == null) { ptrs = new int[0]; } var memStream = new MemoryStream(rawData); var fileReader = BigEndianBinaryReader.GetEndianSpecificBinaryReader(memStream, useAsBigEndian); List <int> pointerDestinations = new List <int>(ptrs.Length + 1); memStream.Seek(8, SeekOrigin.Begin); int rootPtr = fileReader.ReadInt32(); if (rootPtr < 0 || rootPtr >= rawData.Length) { markFileBroken(rawData, ptrs, baseAddr); return; } addToMaps(8, rootPtr); for (int i = 0; i < ptrs.Length; i++) { int effectivePtr = ptrs[i] - baseAddr; if (effectivePtr < 0 || effectivePtr >= rawData.Length) { markFileBroken(rawData, ptrs, baseAddr); return; } memStream.Seek(effectivePtr, SeekOrigin.Begin); int tempPtr = fileReader.ReadInt32(); if (tempPtr - baseAddr < 0 || tempPtr - baseAddr > rawData.Length) { markFileBroken(rawData, ptrs, baseAddr); return; } addToMaps(effectivePtr, tempPtr - baseAddr); } int startAddr = 0; splitData = new List <FileChunk>(destinationToPointers.Count + 1); foreach (int dest in destinationToPointers.Keys.Union(new int[] { rawData.Length }).OrderBy(key => key)) { memStream.Seek(startAddr, SeekOrigin.Begin); byte[] bytes = fileReader.ReadBytes(dest - startAddr); splitData.Add(new FileChunk { chunkLocation = startAddr, contents = bytes }); startAddr = dest; } }
public SetFile(string inFilename, byte[] rawData, byte[] inHeader, int[] ptrs, int baseAddr, bool bigEndian = false) { header = inHeader; filename = inFilename; //Assuming they'll always base 0. MemoryStream transFile = new MemoryStream(rawData); BinaryReader fileReader = BigEndianBinaryReader.GetEndianSpecificBinaryReader(transFile, bigEndian); transFile.Seek(8, SeekOrigin.Begin); int headerLoc = fileReader.ReadInt32(); transFile.Seek(headerLoc, SeekOrigin.Begin); areaID = fileReader.ReadInt16(); short mapCount = fileReader.ReadInt16(); int mainListPointer = fileReader.ReadInt32() - baseAddr; mapData = new MapListing[mapCount]; for (int i = 0; i < mapCount; i++) { transFile.Seek(mainListPointer + i * 12, SeekOrigin.Begin); mapData[i] = new MapListing(); mapData[i].mapNumber = fileReader.ReadInt16(); short listCount = fileReader.ReadInt16(); mapData[i].headers = new ListHeader[listCount]; int listPtr = fileReader.ReadInt32() - baseAddr; for (int j = 0; j < listCount; j++) { transFile.Seek(listPtr + j * 0x28, SeekOrigin.Begin); mapData[i].headers[j] = new ListHeader(); mapData[i].headers[j].headerBytes = fileReader.ReadBytes(34); short listEntryCount = fileReader.ReadInt16(); mapData[i].headers[j].objects = new ObjectEntry[listEntryCount]; int objectListLoc = fileReader.ReadInt32() - baseAddr; for (int k = 0; k < listEntryCount; k++) { transFile.Seek(objectListLoc + k * 0x34, SeekOrigin.Begin); ObjectEntry temp = new ObjectEntry(); temp.startBytes = fileReader.ReadBytes(14); temp.objID = fileReader.ReadInt16(); temp.unkInt1 = fileReader.ReadInt32(); temp.objX = fileReader.ReadSingle(); temp.objY = fileReader.ReadSingle(); temp.objZ = fileReader.ReadSingle(); temp.objRotX = fileReader.ReadSingle(); temp.objRotY = fileReader.ReadSingle(); temp.objRotZ = fileReader.ReadSingle(); temp.metadataLength = fileReader.ReadInt32(); int metadataLoc = fileReader.ReadInt32() - baseAddr; transFile.Seek(metadataLoc, SeekOrigin.Begin); temp.metadata = fileReader.ReadBytes(temp.metadataLength); mapData[i].headers[j].objects[k] = temp; } } } }
private BinaryReader getBinaryReader(Stream s) { return(BigEndianBinaryReader.GetEndianSpecificBinaryReader(s, isBigEndian)); }