예제 #1
0
        /// <summary>
        /// Reads an uncompressed data block into the model.
        /// </summary>
        /// <param name="data">the data store to read from.</param>
        private void ReadUncompressedBlock(byte[] data)
        {
            // the uncompressed block contains a list of filesystem entires
            // as long we have data we will try to read more entries

            // the first sector (0x1000 bytes) is empty (filled with 0xFF)
            // so the first sector starts at 0x1000
            // (we already skipped the 4 byte header so we don't have to take care of this)

            var sectorSize = 0x1000;
            var offset     = sectorSize;

            // we always need 4 bytes (+3 including offset) to read the type
            while ((offset + 3) < data.Length)
            {
                var entryType = GetInteger(data, offset);

                if (entryType == 2) // is a file?
                {
                    // file structure:
                    //   offset |   type   |   size   | what
                    //  --------+----------+----------+------
                    //    0x04  |  string  |  127byte | FileName (zero terminated)
                    //    0x83  |    ?     |    9byte | Unknown
                    //    0x8c  |   int    |    4byte | FileSize
                    //    0x90  |    ?     |    4byte | Unknown
                    //    0x94  |   int[]  |  n*4byte | Indices of the sector containing the data (end is marked with 0)

                    // The sectors marked at 0x94 are absolutely positioned ( 1*0x1000 is sector 1, 2*0x1000 is sector 2,...)

                    var file = new GpxFile();
                    file.FileName = GetString(data, offset + 0x04, 127);
                    file.FileSize = GetInteger(data, offset + 0x8C);

                    // store file if needed
                    var storeFile = FileFilter == null || FileFilter(file.FileName);
                    if (storeFile)
                    {
                        Files.Add(file);
                    }

                    // we need to iterate the blocks because we need to move after the last datasector

                    var dataPointerOffset = offset + 0x94;
                    var sector            = 0; // this var is storing the sector index
                    var sectorCount       = 0; // we're keeping count so we can calculate the offset of the array item

                    // as long we have data blocks we need to iterate them,
                    var fileData = storeFile ? ByteBuffer.WithCapactiy(file.FileSize) : null;
                    while ((sector = GetInteger(data, (dataPointerOffset + (4 * (sectorCount++))))) != 0)
                    {
                        // the next file entry starts after the last data sector so we
                        // move the offset along
                        offset = sector * sectorSize;

                        // write data only if needed
                        if (storeFile)
                        {
                            fileData.Write(data, offset, sectorSize);
                        }
                    }

                    if (storeFile)
                    {
                        // trim data to filesize if needed
                        file.Data = new byte[(int)Math.Min(file.FileSize, fileData.Length)];
                        // we can use the getBuffer here because we are intelligent and know not to read the empty data.
                        byte[] raw = fileData.ToArray();
                        Platform.Platform.BlockCopy(raw, 0, file.Data, 0, file.Data.Length);
                    }
                }

                // let's move to the next sector
                offset += sectorSize;
            }
        }
예제 #2
0
        /// <summary>
        /// Reads an uncompressed data block into the model.
        /// </summary>
        /// <param name="data">the data store to read from.</param>
        private void ReadUncompressedBlock(byte[] data)
        {
            // the uncompressed block contains a list of filesystem entires
            // as long we have data we will try to read more entries

            // the first sector (0x1000 bytes) is empty (filled with 0xFF) 
            // so the first sector starts at 0x1000 
            // (we already skipped the 4 byte header so we don't have to take care of this) 

            var sectorSize = 0x1000;
            var offset = sectorSize;

            // we always need 4 bytes (+3 including offset) to read the type
            while ((offset + 3) < data.Length)
            {
                var entryType = GetInteger(data, offset);

                if (entryType == 2) // is a file?
                {
                    // file structure: 
                    //   offset |   type   |   size   | what
                    //  --------+----------+----------+------
                    //    0x04  |  string  |  127byte | FileName (zero terminated)
                    //    0x83  |    ?     |    9byte | Unknown 
                    //    0x8c  |   int    |    4byte | FileSize
                    //    0x90  |    ?     |    4byte | Unknown
                    //    0x94  |   int[]  |  n*4byte | Indices of the sector containing the data (end is marked with 0)

                    // The sectors marked at 0x94 are absolutely positioned ( 1*0x1000 is sector 1, 2*0x1000 is sector 2,...)

                    var file = new GpxFile();
                    file.FileName = GetString(data, offset + 0x04, 127);
                    file.FileSize = GetInteger(data, offset + 0x8C);

                    // store file if needed
                    var storeFile = FileFilter == null || FileFilter(file.FileName);
                    if (storeFile)
                    {
                        Files.Add(file);
                    }

                    // we need to iterate the blocks because we need to move after the last datasector

                    var dataPointerOffset = offset + 0x94;
                    var sector = 0; // this var is storing the sector index
                    var sectorCount = 0; // we're keeping count so we can calculate the offset of the array item

                    // as long we have data blocks we need to iterate them, 
                    var fileData = storeFile ? ByteBuffer.WithCapactiy(file.FileSize) : null;
                    while ((sector = GetInteger(data, (dataPointerOffset + (4 * (sectorCount++))))) != 0)
                    {
                        // the next file entry starts after the last data sector so we 
                        // move the offset along
                        offset = sector * sectorSize;

                        // write data only if needed
                        if (storeFile)
                        {
                            fileData.Write(data, offset, sectorSize);
                        }
                    }

                    if (storeFile)
                    {
                        // trim data to filesize if needed
                        file.Data = new byte[(int)Math.Min(file.FileSize, fileData.Length)];
                        // we can use the getBuffer here because we are intelligent and know not to read the empty data.
                        byte[] raw = fileData.ToArray();
                        Std.BlockCopy(raw, 0, file.Data, 0, file.Data.Length);
                    }
                }

                // let's move to the next sector
                offset += sectorSize;
            }
        }