(RPA): added missing Pickle codes for long integers (#104)

This commit is contained in:
morkt 2017-11-07 16:00:58 +04:00
parent e783d26957
commit 857f4c544b
2 changed files with 57 additions and 2 deletions

View File

@ -62,6 +62,7 @@
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />

View File

@ -29,6 +29,7 @@ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.IO;
using System.Text;
using GameRes.Compression;
@ -99,8 +100,8 @@ namespace GameRes.Formats.RenPy
return null;
}
var entry = FormatCatalog.Instance.Create<RpaEntry> (name);
entry.Offset = (uint)((int)tuple[0] ^ key);
entry.UnpackedSize = (uint)((int)tuple[1] ^ key);
entry.Offset = (long)(Convert.ToInt64 (tuple[0]) ^ key);
entry.UnpackedSize = (uint)(Convert.ToInt32 (tuple[1]) ^ key);
entry.Size = entry.UnpackedSize;
if (tuple.Count > 2)
{
@ -205,6 +206,8 @@ namespace GameRes.Formats.RenPy
const byte PROTO = 0x80; /* identify pickle protocol */
const byte TUPLE2 = 0x86; /* build 2-tuple from two topmost stack items */
const byte TUPLE3 = 0x87; /* build 3-tuple from three topmost stack items */
const byte LONG1 = 0x8A; /* push long from < 256 bytes */
const byte LONG4 = 0x8B; /* push really big long */
const byte MARK = (byte)'(';
const byte STOP = (byte)'.';
const byte INT = (byte)'I';
@ -527,6 +530,16 @@ namespace GameRes.Formats.RenPy
break;
continue;
case LONG1:
if (!LoadLong())
break;
continue;
case LONG4:
if (!LoadLong4())
break;
continue;
case APPEND:
if (!LoadAppend())
break;
@ -675,6 +688,47 @@ namespace GameRes.Formats.RenPy
return true;
}
bool LoadLong ()
{
int count = m_stream.ReadByte();
if (-1 == count)
return false;
m_stack.Push (DecodeLong (count));
return true;
}
bool LoadLong4 ()
{
int count = 0;
if (!ReadInt (4, out count) || count < 0)
return false;
m_stack.Push (DecodeLong (count));
return true;
}
object DecodeLong (int count)
{
if (count <= 0)
return 0L;
else if (count > 8)
{
var bytes = new byte[count];
m_stream.Read (bytes, 0, count);
return new BigInteger (bytes);
}
else
{
var bytes = new byte[8];
m_stream.Read (bytes, 0, count);
if (0 != (bytes[count-1] & 0x80)) // sign bit is set
{
for (int i = count; i < bytes.Length; ++i)
bytes[i] = 0xFF;
}
return bytes.ToInt64 (0);
}
}
bool LoadCountedTuple (int count)
{
if (m_stack.Count < count)