internal bool Read(WzFileStream zs) { this.Items.Clear(); zs.Seek(this.Offset); int count = zs.Read4(true); for (int i = 0; i < count; i++) { WzArchiveItem item = null; WzArchiveItemType itemtype; string itemname = zs.StringPool.DirectoryRead(out itemtype, WzArchiveItemType.Reference); if (itemtype == WzArchiveItemType.Directory) { item = new WzDirectory(itemname); } else if (itemtype == WzArchiveItemType.File) { item = new WzFile(itemname, zs.KeyType) { Stream = zs.BaseStream }; } else { throw new InvalidDataException("Undefined item type : " + (int)itemtype); } item.Size = zs.Read4(true); item.Checksum = zs.Read4(true); uint offKey = HashTools.GenerateOffsetKey((uint)zs.Tell(), this.Archive.DataOffset, this.Archive.Hash); item.Offset = HashTools.DecryptOffsetHash(zs.Read4u(), offKey, this.Archive.DataOffset); if ((item.Offset + item.Size) > zs.Length) { return(false); } this.Add(item); } for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i].Type == WzArchiveItemType.Directory) { (this.Items[i] as WzDirectory).Read(zs); } } return(true); }
internal override void Write(WzFileStream zf) { // start write int count = this.Items.Count; long[] itemoff = new long[count]; this.Offset = (uint)zf.Tell(); zf.Write4(count, true); // write header for (int i = 0; i < count; i++) { WzArchiveItem item = this.Items[i]; zf.StringPool.DirectoryWrite(item.Name, item.Type, WzArchiveItemType.Reference); zf.Write4(item.Size, true); zf.Write4(item.Checksum, true); itemoff[i] = zf.Tell(); zf.Write4u(0u); // reserve } // package items for (int i = 0; i < count; i++) { this.Items[i].Write(zf); } long endoff = zf.Tell(); // rewrite offset for (int i = 0; i < count; i++) { zf.Seek(itemoff[i]); uint offKey = HashTools.GenerateOffsetKey((uint)zf.Tell(), this.Archive.DataOffset, this.Archive.Hash); uint encoff = HashTools.EncryptOffsetHash(this.Items[i].Offset, offKey, this.Archive.DataOffset); zf.Write4u(encoff); } // end write zf.Seek(endoff); }