List <Entry> ReadIndex(BinaryReader index, int count, long max_offset) { var name_buffer = new byte[0x104]; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { index.ReadByte(); int name_length = index.ReadUInt16(); if (0 == name_length || name_length > name_buffer.Length) { return(null); } index.Read(name_buffer, 0, name_length); var name = DefaultEncoding.GetString(name_buffer, 0, name_length); var entry = FormatCatalog.Instance.Create <NpkEntry> (name); entry.UnpackedSize = index.ReadUInt32(); index.Read(name_buffer, 0, 0x20); // skip int segment_count = index.ReadInt32(); if (segment_count < 0) { return(null); } if (0 == segment_count) { entry.Offset = 0; dir.Add(entry); continue; } entry.Segments.Capacity = segment_count; uint packed_size = 0; bool is_packed = false; for (int j = 0; j < segment_count; ++j) { var segment = new NpkSegment(); segment.Offset = index.ReadInt64(); segment.AlignedSize = index.ReadUInt32(); segment.Size = index.ReadUInt32(); segment.UnpackedSize = index.ReadUInt32(); entry.Segments.Add(segment); packed_size += segment.AlignedSize; is_packed = is_packed || segment.IsCompressed; } entry.Offset = entry.Segments[0].Offset; entry.Size = packed_size; entry.IsPacked = is_packed; if (!entry.CheckPlacement(max_offset)) { return(null); } dir.Add(entry); } return(dir); }
void RewriteSegment(NpkSegment segment, int chunk_size) { using (var proxy = new ProxyStream(m_archive, true)) using (var encryptor = m_aes.CreateEncryptor()) using (var output = new CryptoStream(proxy, encryptor, CryptoStreamMode.Write)) { if (m_remaining == chunk_size) { m_input.CopyTo(output); } else { chunk_size = m_input.Read(m_buffer, 0, chunk_size); output.Write(m_buffer, 0, chunk_size); } } segment.UnpackedSize = segment.Size = (uint)chunk_size; segment.AlignedSize = (uint)(m_archive.Position - segment.Offset); }
NpkSegment WriteSegment(int chunk_size, bool compress) { var segment = new NpkSegment { Offset = m_archive.Position }; using (var proxy = new ProxyStream(m_archive, true)) using (var encryptor = m_aes.CreateEncryptor()) { Stream output = new CryptoStream(proxy, encryptor, CryptoStreamMode.Write); var measure = new CountedStream(output); output = measure; if (compress) { output = new DeflateStream(output, CompressionLevel.Optimal); } using (output) { if (m_remaining == chunk_size) { var file_pos = m_input.Position; m_input.CopyTo(output); m_input.Position = file_pos; m_input.CopyTo(m_checksum_stream); } else { chunk_size = m_input.Read(m_buffer, 0, chunk_size); output.Write(m_buffer, 0, chunk_size); m_checksum_stream.Write(m_buffer, 0, chunk_size); } } segment.UnpackedSize = (uint)chunk_size; segment.Size = (uint)measure.Count; segment.AlignedSize = (uint)(m_archive.Position - segment.Offset); return(segment); } }
List<Entry> ReadIndex(BinaryReader index, int count, long max_offset) { var name_buffer = new byte[0x80]; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { index.ReadByte(); int name_length = index.ReadUInt16(); if (name_length > name_buffer.Length) name_buffer = new byte[name_length]; index.Read (name_buffer, 0, name_length); var name = Encodings.cp932.GetString (name_buffer, 0, name_length); var entry = FormatCatalog.Instance.Create<NpkEntry> (name); entry.UnpackedSize = index.ReadUInt32(); index.Read (name_buffer, 0, 0x20); // skip int segment_count = index.ReadInt32(); if (segment_count <= 0) return null; entry.Segments.Capacity = segment_count; uint packed_size = 0; bool is_packed = false; for (int j = 0; j < segment_count; ++j) { var segment = new NpkSegment(); segment.Offset = index.ReadInt64(); segment.AlignedSize = index.ReadUInt32(); segment.Size = index.ReadUInt32(); segment.UnpackedSize = index.ReadUInt32(); entry.Segments.Add (segment); packed_size += segment.AlignedSize; is_packed = is_packed || segment.IsCompressed; } entry.Offset = entry.Segments[0].Offset; entry.Size = packed_size; entry.IsPacked = is_packed; if (!entry.CheckPlacement (max_offset)) return null; dir.Add (entry); } return dir; }