/// <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; } }
/// <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; } }