public void WriteFile(Stream outstream, FileInArchive file, byte[] data) { MemoryStream inputMS = new MemoryStream(data); MemoryStream outputMS = new MemoryStream(); byte[] output_buffer = new byte[0]; if (file.Descriptor.CompressionMethod == 1) //ZLib compression { ICSharpCode.SharpZipLib.Zip.Compression.Deflater def = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(); ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream defstream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(outputMS, def); defstream.Write(data, 0, data.Length); defstream.Flush(); defstream.Finish(); output_buffer = outputMS.GetBuffer(); file.Descriptor.UncompressedSize = (uint)inputMS.Length; Write(outstream, file, outputMS); } else if (file.Descriptor.CompressionMethod == 0) //No compression { file.Descriptor.CompressionMethod = 0; inputMS.CopyTo(outputMS); file.Descriptor.UncompressedSize = (uint)inputMS.Length; Write(outstream, file, outputMS); } }
private void Write(Stream stream, FileInArchive file, MemoryStream ms) { stream.Seek((long)file.Descriptor.FileTableEntryPosition + 12, SeekOrigin.Begin); int lowMSLength = (int)(ms.Length & 0xFFFFFFFF); stream.Write(BitConverter.GetBytes(lowMSLength), 0, 4); stream.Seek((long)file.Descriptor.FileTableEntryPosition + 16, SeekOrigin.Begin); lowMSLength = (int)(file.Descriptor.UncompressedSize & 0xFFFFFFFF); stream.Write(BitConverter.GetBytes(lowMSLength), 0, 4); stream.Seek((long)file.Descriptor.FileTableEntryPosition + 32, SeekOrigin.Begin); byte[] bArray = new byte[1]; bArray[0] = (byte)file.CompressionMethod; stream.Write(bArray, 0, 1); byte[] tmp_bytearray = ms.GetBuffer(); if (ms.Length <= file.Descriptor.CompressedSize) { stream.Seek((long)(file.Descriptor.StartingPosition + file.Descriptor.FileHeaderSize), SeekOrigin.Begin); stream.Write(tmp_bytearray, 0, (int)ms.Length); } else { long fileSize = stream.Length; stream.Seek(0, SeekOrigin.End); if (file.Descriptor.metadata != null) { stream.Write(file.Descriptor.metadata, 0, file.Descriptor.metadata.Length); } else { byte[] fakeMetadata = new byte[file.Descriptor.FileHeaderSize]; stream.Write(fakeMetadata, 0, fakeMetadata.Length); //Should throw an exception, but not all files have meta data so... } stream.Seek(0, SeekOrigin.End); stream.Write(tmp_bytearray, 0, (int)ms.Length); stream.Seek((long)file.Descriptor.FileTableEntryPosition, SeekOrigin.Begin); stream.Write(BitConverter.GetBytes((int)(fileSize & 0xFFFFFFFF)), 0, 4); stream.Seek((long)file.Descriptor.FileTableEntryPosition + 4, SeekOrigin.Begin); stream.Write(BitConverter.GetBytes((int)((fileSize >> 32) & 0xFFFFFFFF)), 0, 4); file.Descriptor.StartingPosition = (int)(fileSize & 0xFFFFFFFF); } file.Descriptor.CompressedSize = (uint)ms.Length; tmp_bytearray = null; }
public byte[] ReadFile(Stream outstream, FileInArchive file) { if (file.Descriptor.CompressionMethod == 1) //ZLib compression { outstream.Position = file.Descriptor.StartingPosition + file.Descriptor.FileHeaderSize; byte[] compressedData = new byte[file.Descriptor.CompressedSize]; outstream.Read(compressedData, 0, (int)file.Descriptor.CompressedSize); byte[] output_buffer = new byte[file.Descriptor.UncompressedSize]; ICSharpCode.SharpZipLib.Zip.Compression.Inflater inf = new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(); inf.SetInput(compressedData); inf.Inflate(output_buffer); return(output_buffer); } else { outstream.Position = file.Descriptor.StartingPosition + file.Descriptor.FileHeaderSize; byte[] compressedData = new byte[file.Descriptor.CompressedSize]; outstream.Read(compressedData, 0, (int)file.Descriptor.CompressedSize); return(compressedData); } }
public void Load(Stream stream) { //read the position of the starting file table stream.Seek(0x0C, SeekOrigin.Begin); byte[] buffer = new byte[8]; stream.Read(buffer, 0, buffer.Length); long tableStart = FileInArchiveDescriptor.convertLittleEndianBufferToInt(buffer, 0); tableStart += ((long)FileInArchiveDescriptor.convertLittleEndianBufferToInt(buffer, 4)) << 32; //get file count stream.Seek(24, SeekOrigin.Begin); buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); _fileCount = FileInArchiveDescriptor.convertLittleEndianBufferToInt(buffer, 0); //Init long currentReadingPosition; uint numberOfFileInTable = 0; long endOfTableAddress; byte[] bufferTableHeader = new byte[12]; byte[] bufferFileDesc = new byte[FileInArchiveDescriptor.fileDescriptorSize]; FileInArchive myArchFile; while (tableStart != 0) { stream.Seek(tableStart, SeekOrigin.Begin); stream.Read(bufferTableHeader, 0, bufferTableHeader.Length); numberOfFileInTable = FileInArchiveDescriptor.convertLittleEndianBufferToInt(bufferTableHeader, 0); //get number of files currentReadingPosition = tableStart + 12; endOfTableAddress = tableStart + 12 + (long)FileInArchiveDescriptor.fileDescriptorSize * (long)numberOfFileInTable; // calculates the end address tableStart = FileInArchiveDescriptor.convertLittleEndianBufferToInt(bufferTableHeader, 4); //find the next filetable tableStart += (long)FileInArchiveDescriptor.convertLittleEndianBufferToInt(bufferTableHeader, 8) << 32; //mostly 0 while (currentReadingPosition < endOfTableAddress) { stream.Seek(currentReadingPosition, SeekOrigin.Begin); stream.Read(bufferFileDesc, 0, bufferFileDesc.Length); myArchFile = new FileInArchive(); myArchFile.Descriptor = new FileInArchiveDescriptor(bufferFileDesc); myArchFile.Descriptor.FileTableEntryPosition = currentReadingPosition; if (myArchFile.Descriptor.StartingPosition > 0 && myArchFile.Descriptor.CompressedSize > 0 && myArchFile.Descriptor.UncompressedSize > 0 //If the compressed size is 0, then there is no file ) { _files[((long)myArchFile.Descriptor.ph << 32) + myArchFile.Descriptor.sh] = myArchFile; //Retrieve header myArchFile.Descriptor.metadata = new byte[myArchFile.Descriptor.FileHeaderSize]; stream.Seek(myArchFile.Descriptor.StartingPosition, SeekOrigin.Begin); stream.Read(myArchFile.Descriptor.metadata, 0, myArchFile.Descriptor.metadata.Length); } currentReadingPosition += FileInArchiveDescriptor.fileDescriptorSize; } } }