implemented Xfl.Create method.

This commit is contained in:
morkt 2014-07-25 06:57:14 +04:00
parent c807fcb1e7
commit ee4584d1f0
4 changed files with 97 additions and 0 deletions

View File

@ -7,8 +7,10 @@ using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using GameRes.Formats.Strings;
namespace GameRes.Formats
{
@ -50,6 +52,71 @@ namespace GameRes.Formats
}
return new ArcFile (file, this, dir);
}
public override void Create (Stream output, IEnumerable<Entry> list, ResourceOptions options)
{
using (var writer = new BinaryWriter (output, Encoding.ASCII, true))
{
writer.Write (Signature);
int list_size = list.Count();
uint dir_size = (uint)(list_size * 40);
writer.Write (dir_size);
writer.Write (list_size);
var encoding = Encodings.cp932.Clone() as Encoding;
encoding.EncoderFallback = EncoderFallback.ExceptionFallback;
byte[] name_buf = new byte[32];
// first, write names only
foreach (var entry in list)
{
try
{
string name = Path.GetFileName (entry.Name);
int size = encoding.GetBytes (name, 0, name.Length, name_buf, 0);
if (size < name_buf.Length)
name_buf[size] = 0;
}
catch (EncoderFallbackException X)
{
throw new InvalidFileName (entry.Name, arcStrings.MsgIllegalCharacters, X);
}
catch (ArgumentException X)
{
throw new InvalidFileName (entry.Name, arcStrings.MsgFileNameTooLong, X);
}
writer.Write (name_buf);
writer.BaseStream.Seek (8, SeekOrigin.Current);
}
// now, write files and remember offset/sizes
uint current_offset = 0;
foreach (var entry in list)
{
entry.Offset = current_offset;
using (var input = File.Open (entry.Name, FileMode.Open, FileAccess.Read))
{
var size = input.Length;
if (size > uint.MaxValue || current_offset + size > uint.MaxValue)
throw new FileSizeException();
current_offset += (uint)size;
entry.Size = (uint)size;
input.CopyTo (output);
}
}
// at last, go back to directory and write offset/sizes
long dir_offset = 12+32;
foreach (var entry in list)
{
writer.BaseStream.Position = dir_offset;
writer.Write ((uint)entry.Offset);
writer.Write (entry.Size);
dir_offset += 40;
}
}
}
}
public class LwgImageEntry : ImageEntry

View File

@ -171,6 +171,24 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to File name is too long.
/// </summary>
public static string MsgFileNameTooLong {
get {
return ResourceManager.GetString("MsgFileNameTooLong", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File name contains illegal characters.
/// </summary>
public static string MsgIllegalCharacters {
get {
return ResourceManager.GetString("MsgIllegalCharacters", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nitro+ resource archive.
/// </summary>

View File

@ -156,6 +156,12 @@ predefined encryption scheme.</value>
<data name="LWGDescription" xml:space="preserve">
<value>Liar-soft image archive</value>
</data>
<data name="MsgFileNameTooLong" xml:space="preserve">
<value>File name is too long</value>
</data>
<data name="MsgIllegalCharacters" xml:space="preserve">
<value>File name contains illegal characters</value>
</data>
<data name="NPADescription" xml:space="preserve">
<value>Nitro+ resource archive</value>
</data>

View File

@ -141,6 +141,12 @@
Введите ключ шифрования или выберите
один из предопределённых вариантов.</value>
</data>
<data name="MsgFileNameTooLong" xml:space="preserve">
<value>Слишком длинное имя файла</value>
</data>
<data name="MsgIllegalCharacters" xml:space="preserve">
<value>Имя файла содержит недопустимые символы</value>
</data>
<data name="YPFLabelKey" xml:space="preserve">
<value>8-битный ключ шифрования</value>
</data>