Пример #1
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            Stream input;

            if (arc is NpaArchive && entry is NpaEntry)
            {
                input = new EncryptedStream(arc as NpaArchive, entry as NpaEntry);
            }
            else
            {
                input = arc.File.CreateStream(entry.Offset, entry.Size);
            }
            return(UnpackEntry(input, entry as PackedEntry));
        }
Пример #2
0
        public override void Create(Stream output, IEnumerable <Entry> list, ResourceOptions options,
                                    EntryCallback callback)
        {
            var npa_options    = GetOptions <NpaOptions> (options);
            int callback_count = 0;

            // build file index
            var index = new Indexer(list, npa_options);

            output.Position = 41 + index.Size;
            long data_offset = 0;

            // write files
            foreach (var entry in index.Entries.Where(e => e.Type != "directory"))
            {
                if (data_offset > uint.MaxValue)
                {
                    throw new FileSizeException();
                }
                if (null != callback)
                {
                    callback(callback_count++, entry, arcStrings.MsgAddingFile);
                }
                using (var file = File.OpenRead(entry.Name))
                {
                    var size = file.Length;
                    if (size > uint.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    entry.Offset       = data_offset;
                    entry.UnpackedSize = (uint)size;
                    Stream destination = output;
                    if (null != npa_options.Scheme)
                    {
                        destination = new EncryptedStream(output, entry, npa_options.Scheme, index.Key);
                    }
                    try
                    {
                        if (entry.IsPacked)
                        {
                            var start = destination.Position;
                            using (var zstream = new ZLibStream(destination, CompressionMode.Compress,
                                                                CompressionLevel.Level9, true))
                            {
                                file.CopyTo(zstream);
                            }
                            entry.Size = (uint)(destination.Position - start);
                        }
                        else
                        {
                            file.CopyTo(destination);
                            entry.Size = entry.UnpackedSize;
                        }
                    }
                    finally
                    {
                        if (destination is EncryptedStream)
                        {
                            destination.Dispose();
                        }
                    }
                    data_offset += entry.Size;
                }
            }
            if (null != callback)
            {
                callback(callback_count++, null, arcStrings.MsgWritingIndex);
            }

            output.Position = 0;
            using (var header = new BinaryWriter(output, Encoding.ASCII, true))
            {
                header.Write(Signature);
                header.Write((short)0);
                header.Write((byte)0);
                header.Write(npa_options.Key1);
                header.Write(npa_options.Key2);
                header.Write(npa_options.CompressContents);
                header.Write(npa_options.Scheme != null);
                header.Write(index.TotalCount);
                header.Write(index.FolderCount);
                header.Write(index.FileCount);
                header.Write((long)0);
                header.Write(index.Size);
                int entry_number = 0;
                foreach (var entry in index.Entries)
                {
                    header.Write(entry.RawName.Length);
                    for (int i = 0; i < entry.RawName.Length; ++i)
                    {
                        header.Write((byte)(entry.RawName[i] - DecryptName(i, entry_number, index.Key)));
                    }
                    header.Write((byte)("directory" == entry.Type ? 1 : 2));
                    header.Write(entry.FolderId);
                    header.Write((uint)entry.Offset);
                    header.Write(entry.Size);
                    header.Write(entry.UnpackedSize);
                    ++entry_number;
                }
            }
        }