Пример #1
0
        bool SaveEntry(RpaEntry entry)
        {
            byte opcode = null == entry.Header ? TUPLE2 : TUPLE3;

            SaveLong(entry.Offset);
            SaveInt(entry.UnpackedSize);
            if (null != entry.Header)
            {
                SaveString(entry.Header);
            }
            m_stream.WriteByte(opcode);
            return(true);
        }
Пример #2
0
        public override void Create(Stream output, IEnumerable <Entry> list, ResourceOptions options,
                                    EntryCallback callback)
        {
            var  rpa_options    = GetOptions <RpaOptions> (options);
            int  callback_count = 0;
            var  file_table     = new Dictionary <PyString, ArrayList>();
            long data_offset    = 0x22;

            output.Position = data_offset;
            foreach (var entry in list)
            {
                if (null != callback)
                {
                    callback(callback_count++, entry, arcStrings.MsgAddingFile);
                }

                string name      = entry.Name.Replace(@"\", "/");
                var    rpa_entry = new RpaEntry {
                    Name = name
                };
                using (var file = File.OpenRead(entry.Name))
                {
                    var size = file.Length;
                    if (size > uint.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    int header_size = (int)Math.Min(size, 0x10);
                    rpa_entry.Offset       = output.Position ^ rpa_options.Key;
                    rpa_entry.Header       = new byte[header_size];
                    rpa_entry.UnpackedSize = (uint)size ^ rpa_options.Key;
                    rpa_entry.Size         = (uint)(size - header_size);
                    file.Read(rpa_entry.Header, 0, header_size);
                    file.CopyTo(output);
                }
                var py_name = new PyString(name);
                if (file_table.ContainsKey(py_name))
                {
                    file_table[py_name].Add(rpa_entry);
                }
                else
                {
                    file_table[py_name] = new ArrayList {
                        rpa_entry
                    }
                };
            }
            long   index_pos = output.Position;
            string signature = string.Format(CultureInfo.InvariantCulture, "RPA-3.0 {0:x16} {1:x8}\n",
                                             index_pos, rpa_options.Key);
            var header = Encoding.ASCII.GetBytes(signature);

            if (header.Length > data_offset)
            {
                throw new ApplicationException("Signature serialization failed.");
            }

            if (null != callback)
            {
                callback(callback_count++, null, arcStrings.MsgWritingIndex);
            }

            using (var index = new ZLibStream(output, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                var pickle = new Pickle(index);
                if (!pickle.Dump(file_table))
                {
                    throw new ApplicationException("Archive index serialization failed.");
                }
            }
            output.Position = 0;
            output.Write(header, 0, header.Length);
        }
    }