Beispiel #1
0
def ClassImpl(id):
    return C.FocusedSeq(
        "classes", "_class" /
        C.Computed(lambda this: this._root.defs[evaluate(id, this)]),
        "classes" / C.FocusedSeq(
            "entries", "_index" / C.Index, "_member" /
            C.Computed(lambda this: this._._class.members[this._index]),
            "entries" /
            C.Sequence(C.Computed(this._._member.name),
                       DataEntry(lambda this: this._._._member.type)))[C.len_(
                           this._class.members)])
Beispiel #2
0
def Backwards(subcon):
    r"""
    Adapter used to parse a given subconstruct backwards in the stream.
    This ia a macro for seeking backwards before parsing the construct.
    (This will not work for subcons that don't have a valid sizeof)

    The stream will be left off at the start of the parsed result by design.
    Therefore, doing something like Int32ul >> Backwards(Int32ul) >> Int32ul will parse
    the same data 3 times.

    e.g.
    >>> (Bytes(14) >> Backwards(Int32ul) >> Tell).parse(b'junk stuff\x01\x02\x00\x00')
    ['junk stuff\x01\x02\x00\x00', 513, 10L]
    >>> spec = Struct(Seek(0, os.SEEK_END), 'name' / Backwards(String(9)), 'number' / Backwards(Int32ul))
    >>> spec.parse(b'A BUNCH OF JUNK DATA\x01\x00\x00\x00joe shmoe')
    Container(name='joe shmoe')(number=1)

    WARNING: This will break if the subcon doesn't have a valid sizeof.
    >>> spec = Struct(Seek(0, os.SEEK_END), 'name' / Backwards(CString()), 'number' / Backwards(Int32ul))
    >>> spec.parse(b'A BUNCH OF JUNK DATA\x01\x00\x00\x00joe shmoe\x00')
    Traceback (most recent call last):
      ...
    SizeofError: cannot calculate size
        parsing -> name
    """
    return construct.FocusedSeq(
        1, construct.Seek(lambda ctx: subcon.sizeof(ctx) * -1, os.SEEK_CUR),
        construct.Peek(subcon))
Beispiel #3
0
def PrefixedOffset(sizetype, type, offs=0):
    return C.FocusedSeq(
        "content", "_data" / C.Rebuild(
            C.Struct("size" / C.Rebuild(sizetype,
                                        C.len_(this.data) - offs),
                     "data" / C.Bytes(this.size + offs)), lambda obj:
            {"data": type.build(obj.content, **{
                **obj._params,
                **obj
            })}), "content" / C.RestreamData(this._data.data, type))
Beispiel #4
0
def DataEntry(type):
    return C.FocusedSeq(
        "values",
        "_count" / C.Rebuild(Int32ul, C.len_(this.values)),
        "values" / C.Switch(
            type,
            {
                0: Pass,
                1: ClassEntry(),
                2: ClassEntry(),
                3: Byte,  #boolean
                4: Int8ul,
                5: Int16ul,
                6: Int32ul,
                7: Int64ul,
                8: Int8sl,
                9: Int16sl,
                10: Int32sl,
                11: Int64sl,
                12: Float32l,
                13: Float64l,
                14: CString("utf8"),
                15: RGBA(),
                16: Int64ul,  #pointer
                #17: Int32ul #size, potentially not a uint but that's probably the best option of it
                20: Vector3(),
                21: Vector4(),
                22: Quat4(),
                32: CString(
                    'utf8'
                ),  #specifically a CString, while 14 is probably something like std::string
                46: Capsule(),
                64: Vector2()
            },
            default=C.StopFieldError)[this._count],
    )
Beispiel #5
0
def OptionalValue(subcon):
    return construct.FocusedSeq(
        "value",
        present=Rebuild(Flag, construct.this.value != None),
        value=If(construct.this.present, subcon),
    )
Beispiel #6
0
KeyValue = c.Struct(
    "key" / c.Prefixed(CompactUint, c.Struct(
        "type" / c.Byte,
        "data" / c.GreedyBytes,
    )),
    "value" / c.Prefixed(CompactUint, c.GreedyBytes),
    "ofs" / c.Tell,
)

Sequence = c.FocusedSeq("content",
    "content" / c.GreedyRange(
        c.FocusedSeq(
            "keyvalue",
            "terminator" / c.Peek(c.Byte),
            c.StopIf(c.this.terminator == 0),
            "keyvalue" / KeyValue,
        )
    ),
    c.Const(b'\0'),
)

PSBT = c.Struct(
    "magic" / c.Const(b'psbt'),
    "sep" / c.Const(b'\xff'),
    "general" / Sequence,
    "transaction" / c.RestreamData(c.this.general[0].value, Transaction),
    "inputs" / c.Array(c.len_(c.this.transaction.inputs), Sequence),
    "outputs" / c.Array(c.len_(c.this.transaction.outputs), Sequence),
    c.Terminated,
)
Beispiel #7
0
PermalinkBinary = construct.FocusedSeq(
    "fields",
    schema_version=construct.Const(_CURRENT_SCHEMA_VERSION, construct.Byte),
    fields=construct.RawCopy(
        construct.Aligned(
            3,
            construct.Struct(
                header=construct.BitStruct(
                    has_seed_hash=construct.Rebuild(
                        construct.Flag, construct.this._.seed_hash != None),
                    bytes_rotation=construct.Rebuild(
                        construct.BitsInteger(7),
                        lambda ctx: single_byte_hash(ctx._.generator_params) >>
                        1,
                    )),
                seed_hash=construct.If(construct.this.header.has_seed_hash,
                                       construct.Bytes(5)),
                randovania_version=construct.Bytes(4),  # short git hash
                generator_params=construct.ExprAdapter(
                    construct.Prefixed(construct.VarInt,
                                       construct.GreedyBytes),
                    # parsing
                    decoder=create_rotator(inverse=True),
                    # building
                    encoder=create_rotator(inverse=False),
                ),
            ))),
    permalink_checksum=construct.Checksum(
        construct.Bytes(2),
        lambda data: hashlib.blake2b(data, digest_size=2).digest(),
        construct.this.fields.data,
    ),
    end=construct.Terminated,
)
Beispiel #8
0
        c.Struct(
            "type" / CompactUint,
            "data" / Optional(c.GreedyBytes),
        )),
    "value" / c.Prefixed(CompactUint, c.GreedyBytes),
)

PsbtProprietaryKey = c.Struct(
    "prefix" / c.CString("utf-8"),
    "subtype" / CompactUint,
    "data" / Optional(c.GreedyBytes),
)

PsbtSequence = c.FocusedSeq(
    "content",
    "content" / c.GreedyRange(PsbtKeyValue),
    c.Const(b"\0"),
)

PsbtEnvelope = c.FocusedSeq(
    "sequences",
    "magic" / c.Const(b"psbt\xff"),
    "sequences" / c.GreedyRange(PsbtSequence),
    c.Terminated,
)

Bip32Field = c.Struct(
    "fingerprint" / c.Bytes(4),
    "address_n" / c.GreedyRange(c.Int32ul),
)
# fmt: on
Beispiel #9
0
    "size" / Byte,
    "_unknData" / C.Default(Byte[69], [0 for _ in range(69)]),
)

ClassDefinition = DataPointer(
    Int64ul,
    Struct("hash" / Int64ul,
           "members" / C.PrefixedArray(Int64ul, ClassMemberDefinition)),
    "definitionData")

ClassDefinitionList = C.FocusedSeq(
    "definitions", "_count" / C.Rebuild(Int32ul, C.len_(this.definitions)),
    "definitions" / C.Prefixed(
        Int32ul,
        C.Aligned(
            8,
            C.FocusedSeq(
                "definitions",
                "definitions" / ClassDefinition[this._._count],
                DataEntries("definitionData"),
                DataEntries("names"),
            ))))

# Hierarchy handling
varcount = 0


def varHandling(this):
    global varcount
    ret = varcount
    varcount += 1
    return ret