gitlab.com/SiaPrime/SiaPrime@v1.4.1/doc/Encoding.md (about)

     1  Encoding
     2  ========
     3  
     4  The encoding package converts arbitrary objects into byte slices, and vice
     5  versa. Objects are encoded as binary data, without type information. The
     6  decoder will attempt to decode its input bytes into whatever type it is
     7  passed. For example:
     8  
     9  ```go
    10  Marshal(int64(3))  ==  []byte{3, 0, 0, 0, 0, 0, 0, 0}
    11  
    12  var x int64
    13  Unmarshal([]byte{3, 0, 0, 0, 0, 0, 0, 0}, &x)
    14  // x == 3
    15  ```
    16  
    17  Note that this leads to some ambiguity. Since an `int64` and a `uint64` are
    18  both 8 bytes long, it is possible to encode an `int64` and successfully decode
    19  it as a `uint64`. As a result, it is imperative that *the decoder knows
    20  exactly what it is decoding*. Developers must rely on context to determine
    21  what type to decode into.
    22  
    23  The specific rules for encoding Go's builtin types are as follows:
    24  
    25  Integers are little-endian, and are always encoded as 8 bytes, i.e. their
    26  `int64` or `uint64` equivalent.
    27  
    28  Booleans are encoded as one byte, either zero (false) or one (true). No other
    29  values may be used.
    30  
    31  Nil pointers are equivalent to "false," i.e. a single zero byte. Valid
    32  pointers are represented by a "true" byte (0x01) followed by the encoding of
    33  the dereferenced value.
    34  
    35  Variable-length types, such as strings and slices, are represented by an
    36  8-byte unsigned length prefix followed by the encoded value. Strings are
    37  encoded as their literal UTF-8 bytes. Slices are encoded as the concatenation
    38  of their encoded elements. For example:
    39  
    40  ```go
    41  //                                  slice len: 1     string len: 3   string data
    42  Marshal([]string{"foo"}) == []byte{1,0,0,0,0,0,0,0, 3,0,0,0,0,0,0,0, 'f','o','o'}
    43  ```
    44  
    45  Maps are not supported; attempting to encode a map will cause `Marshal` to
    46  panic. This is because their elements are not ordered in a consistent way, and
    47  it is imperative that this encoding scheme be deterministic. To encode a map,
    48  either convert it to a slice of structs, or define a `MarshalSia` method (see
    49  below).
    50  
    51  Arrays and structs are simply the concatenation of their encoded elements.
    52  Byte slices are not subject to the 8-byte integer rule; they are encoded as
    53  their literal representation, one byte per byte.
    54  
    55  All struct fields must be exported. (For some types this is a bit awkward, so
    56  this rule is subject to change.) The ordering of struct fields is determined
    57  by their type definition. For example:
    58  
    59  ```go
    60  type foo struct {
    61  	S string
    62  	I int
    63  }
    64  
    65  Marshal(foo{"bar", 3}) == append(Marshal("bar"), Marshal(3)...)
    66  ```
    67  
    68  Finally, if a type implements the SiaMarshaler interface, its MarshalSia
    69  method will be used to encode the type. Similarly, if a type implements the
    70  SiaUnmarshal interface, its UnmarshalSia method will be used to decode the
    71  type. Note that unless a type implements both interfaces, it must conform to
    72  the spec above. Otherwise, it may encode and decode itself however desired.
    73  This may be an attractive option where speed is critical, since it allows for
    74  more compact representations, and bypasses the use of reflection.