Пример #1
0
        /// <summary>
        /// Decompresses the given bitinput using the GPX compression format. Only use this method
        /// if you are sure the binary data is compressed using the GPX format. Otherwise unexpected
        /// behavior can occure. 
        /// </summary>
        /// <param name="src">the bitInput to read the data from</param>
        /// <param name="skipHeader">true if the header should NOT be included in the result byteset, otherwise false</param>
        /// <returns>the decompressed byte data. if skipHeader is set to false the BCFS header is included.</returns>
        public byte[] Decompress(BitReader src, bool skipHeader = false)
        {
            var uncompressed = ByteBuffer.Empty();
            byte[] buffer;
            var expectedLength = GetInteger(src.ReadBytes(4), 0);

            try
            {
                // as long we reach our expected length we try to decompress, a EOF might occure. 
                while (uncompressed.Length < expectedLength)
                {
                    // compression flag
                    var flag = src.ReadBits(1);

                    if (flag == 1) // compressed content
                    {
                        // get offset and size of the content we need to read.
                        // compressed does mean we already have read the data and need 
                        // to copy it from our uncompressed buffer to the end
                        var wordSize = src.ReadBits(4);
                        var offset = src.ReadBitsReversed(wordSize);
                        var size = src.ReadBitsReversed(wordSize);

                        // the offset is relative to the end
                        var sourcePosition = uncompressed.Length - offset;
                        var toRead = Math.Min(offset, size);

                        // get the subbuffer storing the data and add it again to the end
                        buffer = uncompressed.GetBuffer();
                        uncompressed.Write(buffer, (int) sourcePosition, toRead);
                    }
                    else // raw content
                    {
                        // on raw content we need to read the data from the source buffer 
                        var size = src.ReadBitsReversed(2);
                        for (int i = 0; i < size; i++)
                        {
                            uncompressed.WriteByte((byte) src.ReadByte());
                        }
                    }
                }
            }
            catch (EndOfReaderException)
            {
            }

            buffer = uncompressed.GetBuffer();
            var resultOffset = skipHeader ? 4 : 0;
            var resultSize = uncompressed.Length - resultOffset;
            var result = new byte[(int)resultSize];
            Std.BlockCopy(buffer, resultOffset, result, 0, (int)resultSize);
            return result;
        }
Пример #2
0
 /// <summary>
 /// Load a complete FileSystem to the memory.
 /// </summary>
 /// <param name="s">the binary source to read from.</param>
 /// <returns></returns>
 public void Load(IReadable s)
 {
     var src = new BitReader(s);
     ReadBlock(src);
 }
Пример #3
0
 /// <summary>
 /// Reads the 4 byte header as a string.
 /// </summary>
 /// <param name="src">the BitInput to read from</param>
 /// <returns>a string with 4 characters representing the header.</returns>
 public string ReadHeader(BitReader src)
 {
     return GetString(src.ReadBytes(4), 0, 4);
 }
Пример #4
0
 /// <summary>
 /// Reads a block from the given data source.
 /// </summary>
 /// <param name="data">the data source</param>
 /// <returns></returns>
 private void ReadBlock(BitReader data)
 {
     var header = ReadHeader(data);
     if (header == HeaderBcFz) // compressed file?
     {
         // decompress the data and use this 
         // we will skip the header 
         ReadUncompressedBlock(Decompress(data, true));
     }
     else if (header == HeaderBcFs) // uncompressed file?
     {
         ReadUncompressedBlock(data.ReadAll());
     }
     else
     {
         throw new UnsupportedFormatException();
     }
 }