diff --git a/doc/datatypes.md b/doc/datatypes.md index 578ce05..73d3ddc 100644 --- a/doc/datatypes.md +++ b/doc/datatypes.md @@ -18,3 +18,4 @@ * * [bitfield](./datatypes/utils.md) * * [mapper](./datatypes/utils.md) * * [pstring](./datatypes/utils.md) +* * [hash](./datatypes/utils.md) diff --git a/doc/datatypes/utils.md b/doc/datatypes/utils.md index c64a3aa..2bafc8f 100644 --- a/doc/datatypes/utils.md +++ b/doc/datatypes/utils.md @@ -124,3 +124,27 @@ Example: A string length prefixed by a varint. ] ``` Example of value: `"my string"` + +### **hash** ({ alg: String, type: Type, body: Type }) +Arguments: +* alg : the hash algorithm: `crc32`, `crc32c`, or any digest the platform's crypto library provides (`md5`, `sha1`, `sha256`, ...) +* type : the type the hash is written and read as +* body : the type the value is serialized as before being hashed + +Represents a hash of a value instead of the value itself: writing serializes the value as `body`, hashes the bytes and writes the hash as `type`; reading reads `type` and yields the hash. The value is not recoverable from the buffer, so the read side sees only the hash. + +CRC hashes are unsigned integers. When `type` is signed (for example `i32`) the hash is written in two's complement, so it reads back the way a language with only signed integers would produce it. Other algorithms produce raw digest bytes, so `type` must then be a `buffer` of the digest's length. + +Example: a CRC32C of an item component, written as a signed int like Minecraft's `HashedSlot` carries it. +```json +[ + "hash", + { + "alg": "crc32c", + "type": "i32", + "body": "ItemComponent" + } +] +``` + +Example of value: `{ "id": 5, "level": 3 }` (whatever `body` accepts) / reads as `-486237565` diff --git a/schemas/datatype.json b/schemas/datatype.json index 66b37d8..94a1431 100644 --- a/schemas/datatype.json +++ b/schemas/datatype.json @@ -45,6 +45,7 @@ { "$ref": "buffer" }, { "$ref": "bitfield" }, { "$ref": "bitflags" }, - { "$ref": "mapper" } + { "$ref": "mapper" }, + { "$ref": "hash" } ] } diff --git a/schemas/utils.json b/schemas/utils.json index c9d48b5..99690c3 100644 --- a/schemas/utils.json +++ b/schemas/utils.json @@ -144,5 +144,31 @@ } ], "additionalItems": false + }, + "hash": { + "title": "hash", + "type": "array", + "items": [ + { + "enum": ["hash"] + }, + { + "type": "object", + "properties": { + "alg": { + "type": "string" + }, + "type": { + "$ref": "dataType" + }, + "body": { + "$ref": "dataType" + } + }, + "required": ["alg", "type", "body"], + "additionalProperties": false + } + ], + "additionalItems": false } }