A variable-length integer,
in the format used by the 0xfe chunks in the 'dcmp' (0)
and 'dcmp' (1)
resource compression formats.
See the dcmp_0 and dcmp_1 specs for more information about these compression formats.
This variable-length integer format can store an integer x
in any of the following ways:
0 <= x <= 0x7f
(7-bit unsigned integer)-0x4000 <= x <= 0x3eff
(15-bit signed integer with the highest 0x100
values unavailable)-0x80000000 <= x <= 0x7fffffff
(32-bit signed integer)In practice, values are always stored in the smallest possible format, but technically any of the larger formats could be used as well.
This page hosts a formal specification of Variable-length integer used in Apple `'dcmp' (0)` and `'dcmp' (1)` compressed resource formats using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C# generated by Kaitai Struct depends on the C# runtime library. You have to install it before you can parse data.
The C# runtime library is available in the NuGet Gallery. Installation instructions can also be found there.
Parse a local file and get structure in memory:
var data = DcmpVariableLengthInteger.FromFile("path/to/local/file.bin");
Or parse structure from a byte array:
byte[] someArray = new byte[] { ... };
var data = new DcmpVariableLengthInteger(new KaitaiStream(someArray));
After that, one can get various attributes from the structure by accessing properties like:
data.First // => The first byte of the variable-length integer.
This determines which storage format is used.
* For the 1-byte format,
this encodes the entire value of the value.
* For the 2-byte format,
this encodes the high 7 bits of the value,
minus `0xc0`.
The highest bit of the value,
i. e. the second-highest bit of this field,
is the sign bit.
* For the 5-byte format,
this is always `0xff`.
data.Value // => The decoded value of the variable-length integer.
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
namespace Kaitai
{
/// <summary>
/// A variable-length integer,
/// in the format used by the 0xfe chunks in the `'dcmp' (0)` and `'dcmp' (1)` resource compression formats.
/// See the dcmp_0 and dcmp_1 specs for more information about these compression formats.
///
/// This variable-length integer format can store an integer `x` in any of the following ways:
///
/// * In a single byte,
/// if `0 <= x <= 0x7f`
/// (7-bit unsigned integer)
/// * In 2 bytes,
/// if `-0x4000 <= x <= 0x3eff`
/// (15-bit signed integer with the highest `0x100` values unavailable)
/// * In 5 bytes, if `-0x80000000 <= x <= 0x7fffffff`
/// (32-bit signed integer)
///
/// In practice,
/// values are always stored in the smallest possible format,
/// but technically any of the larger formats could be used as well.
/// </summary>
/// <remarks>
/// Reference: <a href="https://github.com/dgelessus/python-rsrcfork/blob/f891a6e/src/rsrcfork/compress/common.py">Source</a>
/// </remarks>
public partial class DcmpVariableLengthInteger : KaitaiStruct
{
public static DcmpVariableLengthInteger FromFile(string fileName)
{
return new DcmpVariableLengthInteger(new KaitaiStream(fileName));
}
public DcmpVariableLengthInteger(KaitaiStream p__io, KaitaiStruct p__parent = null, DcmpVariableLengthInteger p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root ?? this;
f_value = false;
_read();
}
private void _read()
{
_first = m_io.ReadU1();
if (First >= 128) {
switch (First) {
case 255: {
_more = m_io.ReadS4be();
break;
}
default: {
_more = m_io.ReadU1();
break;
}
}
}
}
private bool f_value;
private int _value;
/// <summary>
/// The decoded value of the variable-length integer.
/// </summary>
public int Value
{
get
{
if (f_value)
return _value;
_value = (int) ((First == 255 ? More : (First >= 128 ? (((First << 8) | More) - 49152) : First)));
f_value = true;
return _value;
}
}
private byte _first;
private int _more;
private DcmpVariableLengthInteger m_root;
private KaitaiStruct m_parent;
/// <summary>
/// The first byte of the variable-length integer.
/// This determines which storage format is used.
///
/// * For the 1-byte format,
/// this encodes the entire value of the value.
/// * For the 2-byte format,
/// this encodes the high 7 bits of the value,
/// minus `0xc0`.
/// The highest bit of the value,
/// i. e. the second-highest bit of this field,
/// is the sign bit.
/// * For the 5-byte format,
/// this is always `0xff`.
/// </summary>
public byte First { get { return _first; } }
/// <summary>
/// The remaining bytes of the variable-length integer.
///
/// * For the 1-byte format,
/// this is not present.
/// * For the 2-byte format,
/// this encodes the low 8 bits of the value.
/// * For the 5-byte format,
/// this encodes the entire value.
/// </summary>
public int More { get { return _more; } }
public DcmpVariableLengthInteger M_Root { get { return m_root; } }
public KaitaiStruct M_Parent { get { return m_parent; } }
}
}