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 void AddChunk(SwStorageChunkInfo chunk)
 {
     this.m_chunks.Add(chunk);
 }
        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);
        }