/// <summary> /// Reads data from a file at the specified offset, of specified size into a stream and returns the stream. If no stream is specified, a new memory stream is created. /// </summary> /// <param name="filePath"></param> /// <param name="offset"></param> /// <param name="size"></param> /// <returns></returns> public static Stream ReadExternalData(string filePath, long offset, int size, Stream outStream = null) { if (!File.Exists(filePath)) { return(null); } using Stream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); if (offset + size > fs.Length) { return(null); //invalid pointer, outside bounds } outStream ??= new MemoryStream(); fs.Seek(offset, SeekOrigin.Begin); var startPos = outStream.Position; fs.CopyToEx(outStream, size); outStream.Position = startPos; return(outStream); }
public MemoryStream DecompressEntry(int index) { MemoryStream result = MixinHandler.MixinMemoryStreamManager.GetStream(); FileEntryStruct e = Files[index]; uint count = 0; byte[] inputBlock; byte[] outputBlock = new byte[Header.MaxBlockSize]; long left = e.RealUncompressedSize; FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read); fs.Seek(e.BlockOffsets[0], SeekOrigin.Begin); //byte[] buff; if (e.BlockSizeIndex == 0xFFFFFFFF) { fs.CopyToEx(result, (int)e.RealUncompressedSize); //buff = new byte[e.RealUncompressedSize]; //fs.Read(buff, 0, buff.Length); //result.Write(buff, 0, buff.Length); } else { while (left > 0) { uint compressedBlockSize = e.BlockSizes[count]; if (compressedBlockSize == 0) { compressedBlockSize = Header.MaxBlockSize; } if (compressedBlockSize == Header.MaxBlockSize || compressedBlockSize == left) { fs.CopyToEx(result, (int)compressedBlockSize); //buff = new byte[compressedBlockSize]; //fs.Read(buff, 0, buff.Length); //result.Write(buff, 0, buff.Length); left -= compressedBlockSize; } else { var uncompressedBlockSize = (uint)Math.Min(left, Header.MaxBlockSize); if (compressedBlockSize < 5) { throw new Exception("SFAR compressed block size smaller than 5 bytes"); } inputBlock = new byte[compressedBlockSize]; fs.Read(inputBlock, 0, (int)compressedBlockSize); uint actualUncompressedBlockSize = uncompressedBlockSize; uint actualCompressedBlockSize = compressedBlockSize; outputBlock = SevenZipHelper.LZMA.Decompress(inputBlock, actualUncompressedBlockSize); if (outputBlock.Length != actualUncompressedBlockSize) { throw new Exception("SFAR decompression error"); } result.Write(outputBlock, 0, (int)actualUncompressedBlockSize); left -= uncompressedBlockSize; } count++; } } fs.Close(); result.Position = 0; return(result); }