private SwStorage Process(Stream stream) { byte[] blob = StreamHelper.ReadToEnd(m_stream); int index = 0; // yet unknown the first bytes uint header = GetUInt(blob, index); index += 4; index += 3; // skip 3 bytes // there seems to be an key for scrambling strings uint key = blob[index]; index += 1; SwStorage storage = new SwStorage(header, key); for (; index < blob.Length; index++) { // TODO: find a way to recognize if the table of contents starts SwStorageChunkInfo chunk = ReadChunk(storage, blob, index); if (chunk == null) { //readContentTable(blob, index); break; } storage.AddChunk(chunk); int nextOffset = index + (int)chunk.GetLength(); index = nextOffset - 1; // for ! } return(storage); }
public SwModelReader(Stream stream) { this.m_stream = stream; m_storage = Process(m_stream); }
private static SwStorageChunkInfo ReadChunk(SwStorage storage, byte[] blob, int startIndex) { // within a block before offset 0x12 the bytes are yet unknown int index = startIndex + 0x12; uint compressedSize = GetUInt(blob, index); index += 4; uint uncompressedSize = GetUInt(blob, index); index += 4; int nameSize = (int)GetUInt(blob, index); index += 4; int namestart = index; if (namestart + nameSize > blob.Length) { // happens if we try to read the content table return(null); } // the stream names are scrambled ;-) byte[] unrolName = new byte[nameSize]; for (; index < namestart + nameSize; index++) { byte unroledByte = Rol(blob[index], (int)storage.Key); unrolName[index - namestart] = unroledByte; } string chunkName = Encoding.UTF8.GetString(unrolName); if (string.IsNullOrEmpty(chunkName)) { chunkName = "un_" + Guid.NewGuid().ToString(); } int compressedDataStart = namestart + nameSize; SwStorageChunkInfo chunkInfo = new SwStorageChunkInfo(); chunkInfo.ChunkOffset = (uint)startIndex; chunkInfo.CompressedSize = compressedSize; chunkInfo.StartCompressedBlock = compressedDataStart; chunkInfo.ChunkName = chunkName; chunkInfo.HeaderLength = compressedDataStart - startIndex; if (uncompressedSize > 0) { byte[] uncompressedData = new byte[uncompressedSize]; ZlibCodec inflator = new ZlibCodec(); inflator.InitializeInflate(false); inflator.InputBuffer = blob; inflator.AvailableBytesIn = (int)compressedSize; inflator.AvailableBytesOut = (int)uncompressedSize; inflator.NextIn = compressedDataStart; inflator.OutputBuffer = uncompressedData; inflator.NextOut = 0; inflator.Inflate(FlushType.Full); inflator.EndInflate(); chunkInfo.Chunk = uncompressedData; } else { chunkInfo.Chunk = new byte[0]; } return(chunkInfo); }