public void Parse(IBinaryStream index) { index.Position = 16; int segment_count = Binary.BigEndian(index.ReadInt32()); m_segments = new List <BundleSegment> (segment_count); long packed_offset = m_data_offset; long unpacked_offset = 0; for (int i = 0; i < segment_count; ++i) { var segment = new BundleSegment(); segment.Offset = packed_offset; segment.UnpackedOffset = unpacked_offset; segment.UnpackedSize = Binary.BigEndian(index.ReadUInt32()); segment.PackedSize = Binary.BigEndian(index.ReadUInt32()); segment.Compression = Binary.BigEndian(index.ReadUInt16()); m_segments.Add(segment); packed_offset += segment.PackedSize; unpacked_offset += segment.UnpackedSize; } int count = Binary.BigEndian(index.ReadInt32()); m_bundles = new List <BundleEntry> (count); for (int i = 0; i < count; ++i) { var entry = new BundleEntry(); entry.Offset = Binary.BigEndian(index.ReadInt64()); entry.Size = (uint)Binary.BigEndian(index.ReadInt64()); entry.Flags = Binary.BigEndian(index.ReadUInt32()); entry.Name = index.ReadCString(Encoding.UTF8); m_bundles.Add(entry); } }
void ReadCompressedSegment(BundleSegment segment) { m_input.Position = segment.Offset; int method = segment.Compression & 0x3F; if (1 == method) { m_buffer_len = LzmaDecompressBlock(segment.PackedSize, segment.UnpackedSize); return; } if (null == m_packed || segment.PackedSize > m_packed.Length) { m_packed = new byte[segment.PackedSize]; } int packed_size = m_input.Read(m_packed, 0, (int)segment.PackedSize); var output = PrepareBuffer(segment.UnpackedSize); if (3 == method || 2 == method) { m_buffer_len = Lz4Compressor.DecompressBlock(m_packed, packed_size, output, (int)segment.UnpackedSize); } else { throw new NotImplementedException("Not supported Unity asset bundle compression."); } }
int ReadFromSegment(BundleSegment segment, byte[] buffer, int offset, int count) { Debug.Assert(m_position >= segment.UnpackedOffset && m_position <= segment.UnpackedOffset + segment.UnpackedSize); if (!segment.IsCompressed) { int available = (int)Math.Min(count, (segment.UnpackedOffset + segment.UnpackedSize) - m_position); return(m_input.Read(buffer, offset, available)); } else { if (0 == m_buffer_len) { ReadCompressedSegment(segment); } int available = Math.Min(count, m_buffer_len - m_buffer_pos); Buffer.BlockCopy(m_buffer, m_buffer_pos, buffer, offset, available); m_buffer_pos += available; return(available); } }
void ReadCompressedSegment(BundleSegment segment) { m_input.Position = segment.Offset; if (null == m_packed || segment.PackedSize > m_packed.Length) { m_packed = new byte[segment.PackedSize]; } int packed_size = m_input.Read(m_packed, 0, (int)segment.PackedSize); if (null == m_buffer || segment.UnpackedSize > m_buffer.Length) { m_buffer = new byte[segment.UnpackedSize]; } if (3 == segment.Compression) { m_buffer_len = Lz4Compressor.DecompressBlock(m_packed, packed_size, m_buffer, (int)segment.UnpackedSize); } else { throw new NotImplementedException("Not supported Unity asset bundle compression."); } }