This commit is contained in:
@@ -1,21 +1,17 @@
|
||||
GM Serialization
|
||||
=====
|
||||
# GM Serialization
|
||||
|
||||
Serialization helpers for the Gajumaru.
|
||||
|
||||
Build
|
||||
-----
|
||||
## Build
|
||||
|
||||
$ rebar3 compile
|
||||
|
||||
|
||||
Test
|
||||
----
|
||||
## Test
|
||||
|
||||
$ rebar3 eunit
|
||||
|
||||
Dynamic encoding
|
||||
----
|
||||
## Dynamic encoding
|
||||
|
||||
The module `gmser_dyn` offers dynamic encoding support, encoding most 'regular'
|
||||
Erlang data types into an internal RLP representation.
|
||||
@@ -34,6 +30,7 @@ how the type information is represented. The fully serialized form is
|
||||
produced by the `serialize` functions.
|
||||
|
||||
The basic types supported by the encoder are:
|
||||
* `neg_integer()` (`negint`, code: 247)
|
||||
* `non_neg_integer()` (`int` , code: 248)
|
||||
* `binary()` (`binary`, code: 249)
|
||||
* `boolean()` (`bool` , code: 250)
|
||||
@@ -48,8 +45,8 @@ When encoding `map` types, the map elements are first sorted.
|
||||
When specifying a map type for template-driven encoding, use
|
||||
the `#{items => [{Key, Value}]}` construct.
|
||||
|
||||
Labels
|
||||
----
|
||||
|
||||
## Labels
|
||||
|
||||
Labels correspond to (existing) atoms in Erlang.
|
||||
Decoding of a label results in a call to `binary_to_existing_atom/2`, so will
|
||||
@@ -63,8 +60,7 @@ Labels are encoded as `[<<255>>, << AtomToBinary/binary >>]`.
|
||||
If a cached label is used, the encoding becomes `[<<255>, [Ix]]`, where
|
||||
`Ix` is the integer-encoded index value of the cached label.
|
||||
|
||||
Examples
|
||||
----
|
||||
## Examples
|
||||
|
||||
Dynamically encoded objects have the basic structure `[<<0>>,V,Obj]`, where `V` is the
|
||||
integer-coded version, and `Obj` is the top-level encoding on the form `[Tag,Data]`.
|
||||
@@ -88,8 +84,7 @@ Note that tuples and list are encoded the same way, except for the initial type
|
||||
Maps are encoded as `[<Map>, [KV1, KV2, ...]]`, where `[KV1, KV2, ...]` is the sorted
|
||||
list of key-value tuples from `map:to_list(Map)`, but with the `tuple` type tag omitted.
|
||||
|
||||
Template-driven encoding
|
||||
----
|
||||
## Template-driven encoding
|
||||
|
||||
Templates can be provided to the encoder by either naming an already registered
|
||||
type, or by passing a template directly. In both cases, the encoder will enforce
|
||||
@@ -112,3 +107,23 @@ ET([{int,int}], [{1,2}]) -> [<<0>>,<<1>>,[<<251>>,[[[<<248>>,<<1>>],[<<248>>,<<2
|
||||
gmser_dyn:register_type(1000,lt2i,[{int,int}]).
|
||||
ET(lt2i, [{1,2}]) -> [<<0>>,<<1>>,[<<3,232>>,[[<<1>>,<<2>>]]]]
|
||||
```
|
||||
|
||||
### Alternative types
|
||||
|
||||
The dynamic encoder supports two additions to the `gmserialization` template
|
||||
language: `any` and `#{alt => [AltTypes]}`.
|
||||
|
||||
The `any` type doesn't have an associated code, but enforces dynamic encoding.
|
||||
|
||||
The `#{alt => [Type]}` construct also enforces dynamic encoding, and will try
|
||||
to encode as each type in the list, in the specified order, until one matches.
|
||||
|
||||
```erlang
|
||||
gmser_dyn:encode_typed(#{alt => [negint,int]}, 5) -> [<<0>>,<<1>>,[<<247>>,<<5>>]]
|
||||
gmser_dyn:encode_typed(#{alt => [negint,int]}, 5) -> [<<0>>,<<1>>,[<<248>>,<<5>>]]
|
||||
|
||||
gmser_dyn:register_type(246, anyint, #{alt => [negint, int]})
|
||||
|
||||
gmser_dyn:encode_typed(anyint,-5) -> [<<0>>,<<1>>,[<<246>>,[<<247>>,<<5>>]]]
|
||||
gmser_dyn:encode_typed(anyint,5) -> [<<0>>,<<1>>,[<<246>>,[<<248>>,<<5>>]]]
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user