Esempio n. 1
0
        public override void Create(Stream output, IEnumerable<Entry> list, ResourceOptions options,
                                     EntryCallback callback)
        {
            var ons_options = GetOptions<NsaOptions> (options);
            var encoding = Encodings.cp932.WithFatalFallback();
            int callback_count = 0;

            var real_entry_list = new List<NsaEntry>();
            var used_names = new HashSet<string>();
            int index_size = 0;
            foreach (var entry in list)
            {
                if (!used_names.Add (entry.Name)) // duplicate name
                    continue;
                try
                {
                    index_size += encoding.GetByteCount (entry.Name) + 1;
                }
                catch (EncoderFallbackException X)
                {
                    throw new InvalidFileName (entry.Name, arcStrings.MsgIllegalCharacters, X);
                }
                var header_entry = new NsaEntry { Name = entry.Name };
                if (Compression.None != ons_options.CompressionType)
                {
                    if (entry.Name.EndsWith (".bmp", StringComparison.InvariantCultureIgnoreCase))
                        header_entry.CompressionType = ons_options.CompressionType;
                }
                index_size += 13;
                real_entry_list.Add (header_entry);
            }

            long start_offset = output.Position;
            long base_offset = 6+index_size;
            output.Seek (base_offset, SeekOrigin.Current);
            foreach (var entry in real_entry_list)
            {
                using (var input = File.OpenRead (entry.Name))
                {
                    var file_size = input.Length;
                    if (file_size > uint.MaxValue)
                        throw new FileSizeException();
                    long file_offset = output.Position - base_offset;
                    if (file_offset+file_size > uint.MaxValue)
                        throw new FileSizeException();
                    if (null != callback)
                        callback (callback_count++, entry, arcStrings.MsgAddingFile);
                    entry.Offset = file_offset;
                    entry.UnpackedSize = (uint)file_size;
                    if (Compression.LZSS == entry.CompressionType)
                    {
                        var packer = new Packer (input, output);
                        entry.Size = packer.EncodeLZSS();
                    }
                    else
                    {
                        entry.Size            = entry.UnpackedSize;
                        entry.CompressionType = Compression.None;
                        input.CopyTo (output);
                    }
                }
            }

            if (null != callback)
                callback (callback_count++, null, arcStrings.MsgWritingIndex);
            output.Position = start_offset;
            using (var writer = new BinaryWriter (output, encoding, true))
            {
                writer.Write (Binary.BigEndian ((short)real_entry_list.Count));
                writer.Write (Binary.BigEndian ((uint)base_offset));
                foreach (var entry in real_entry_list)
                {
                    writer.Write (encoding.GetBytes (entry.Name));
                    writer.Write ((byte)0);
                    writer.Write ((byte)entry.CompressionType);
                    writer.Write (Binary.BigEndian ((uint)entry.Offset));
                    writer.Write (Binary.BigEndian ((uint)entry.Size));
                    writer.Write (Binary.BigEndian ((uint)entry.UnpackedSize));
                }
            }
        }
Esempio n. 2
0
        public override void Create(Stream output, IEnumerable <Entry> list, ResourceOptions options,
                                    EntryCallback callback)
        {
            var ons_options    = GetOptions <NsaOptions> (options);
            var encoding       = Encodings.cp932.WithFatalFallback();
            int callback_count = 0;

            var real_entry_list = new List <NsaEntry>();
            var used_names      = new HashSet <string>();
            int index_size      = 0;

            foreach (var entry in list)
            {
                if (!used_names.Add(entry.Name))  // duplicate name
                {
                    continue;
                }
                try
                {
                    index_size += encoding.GetByteCount(entry.Name) + 1;
                }
                catch (EncoderFallbackException X)
                {
                    throw new InvalidFileName(entry.Name, arcStrings.MsgIllegalCharacters, X);
                }
                var header_entry = new NsaEntry {
                    Name = entry.Name
                };
                if (Compression.None != ons_options.CompressionType)
                {
                    if (entry.Name.HasExtension(".bmp"))
                    {
                        header_entry.CompressionType = ons_options.CompressionType;
                    }
                }
                index_size += 13;
                real_entry_list.Add(header_entry);
            }

            long start_offset = output.Position;
            long base_offset  = 6 + index_size;

            output.Seek(base_offset, SeekOrigin.Current);
            foreach (var entry in real_entry_list)
            {
                using (var input = File.OpenRead(entry.Name))
                {
                    var file_size = input.Length;
                    if (file_size > uint.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    long file_offset = output.Position - base_offset;
                    if (file_offset + file_size > uint.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    if (null != callback)
                    {
                        callback(callback_count++, entry, arcStrings.MsgAddingFile);
                    }
                    entry.Offset       = file_offset;
                    entry.UnpackedSize = (uint)file_size;
                    if (Compression.LZSS == entry.CompressionType)
                    {
                        var packer = new Packer(input, output);
                        entry.Size = packer.EncodeLZSS();
                    }
                    else
                    {
                        entry.Size            = entry.UnpackedSize;
                        entry.CompressionType = Compression.None;
                        input.CopyTo(output);
                    }
                }
            }

            if (null != callback)
            {
                callback(callback_count++, null, arcStrings.MsgWritingIndex);
            }
            output.Position = start_offset;
            using (var writer = new BinaryWriter(output, encoding, true))
            {
                writer.Write(Binary.BigEndian((short)real_entry_list.Count));
                writer.Write(Binary.BigEndian((uint)base_offset));
                foreach (var entry in real_entry_list)
                {
                    writer.Write(encoding.GetBytes(entry.Name));
                    writer.Write((byte)0);
                    writer.Write((byte)entry.CompressionType);
                    writer.Write(Binary.BigEndian((uint)entry.Offset));
                    writer.Write(Binary.BigEndian((uint)entry.Size));
                    writer.Write(Binary.BigEndian((uint)entry.UnpackedSize));
                }
            }
        }