Involved Source Filescodec.go
Package codec implements the general-purpose part of an encoder for Go
values. It relies on code generation rather than reflection so it is
significantly faster than reflection-based encoders like gob. It also
preserves sharing among struct pointers (but not other forms of sharing, like
other pointer types or sub-slices). These features are sufficient for
encoding the structures of the go/ast package, which is its sole purpose.
Encoding Scheme
Every encoded value begins with a single byte that describes what (if
anything) follows. There is enough information to skip over the value, since
the decoder must be able to do that if it encounters a struct field it
doesn't know.
Most of the values of that initial byte can be devoted to small unsigned
integers. For example, the number 17 is represented by the single byte 17.
Only a few byte values have special meaning.
The nil code indicates that the value is nil. We don't absolutely need this:
we could always represent the nil value for a type as something that couldn't
be mistaken for an encoded value of that type. For instance, we could use 0
for nil in the case of slices (which always begin with the nValues code), and
for pointers to numbers like *int, we could use something like "nBytes 0".
But it is simpler to have a reserved value for nil.
The nBytes code indicates that an unsigned integer N is encoded next,
followed by N bytes of data. This is used to represent strings and byte
slices, as well numbers bigger than can fit into the initial byte. For
example, the string "hi" is represented as:
nBytes 2 'h' 'i'
Unsigned integers that can't fit into the initial byte are encoded as byte
sequences of length 4 or 8, holding little-endian uint32 or uint64 values. We
use uint32s where possible to save space. We could have saved more space by
also considering 16-byte numbers, or using a variable-length encoding like
varints or gob's representation, but it didn't seem worth the additional
complexity.
The nValues code is for sequences of values whose size is known beforehand,
like a Go slice or array. The slice []string{"hi", "bye"} is encoded as
nValues 2 nBytes 2 'h' 'i' nBytes 3 'b' 'y' 'e'
The ref code is used to refer to an earlier encoded value. It is followed by
a uint denoting the index data of the value to use.
The start and end codes delimit a value whose length is unknown beforehand.
It is used for structs.
generate.go
Package-Level Type Names (total 8, in which 2 are exported)
Package-Level Functions (total 16, in which 4 are exported)
GenerateFile writes encoders and decoders to filename.
It generates code for the type of each given value, as well
as any types they depend on.
packageName is the name following the file's package declaration.
NewDecoder returns a Decoder for the given bytes.
NewEncoder returns an Encoder.
Register records the type of x for use by Encoders and Decoders.
builtinName returns the suffix to append to "encode" or "decode" to get the
Encoder/Decoder method name for t. If t cannot be encoded by an Encoder
method, the suffix is "". The second return value is the "native" type of the
method: the argument to the Encoder method, and the return value of the
Decoder method.
exportedFields returns the exported fields of the struct type t that
should be encoded, in the proper order.
Exported fields of embedded, unexported types are not included.
If there was a previous ordering, it is preserved, and new fields are
added to the end.
If a field was removed, we keep its number so as not to break existing
encoded values. It will appear in the return value with an empty type.
One drawback of this scheme is that it is not possible to rename a field.
A rename will look like an addition and a removal.
Template body for a map type.
A nil map is encoded as a zero.
A map of size N is encoded as a list of length 2N, containing alternating
keys and values.
In the decode function, we declare a variable v to hold the decoded map value
rather than decoding directly into m[v]. This is necessary for decode
functions that take pointers: you can't take a pointer to a map element.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
reserve a few values for future use
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Template body for a sliceBody type.
Byte codes that begin each encoded value.
See the package doc for their descriptions.
Template body for a (pointer to a) struct type.
A nil pointer is encoded as a zero. (This is done in Encoder.StartStruct.)
Otherwise, a struct is encoded as the start code, its exported fields, then
the end code. Each non-zero field is encoded as its field number followed by
its value. A field that equals its zero value isn't encoded.
The comment listing the field names is used when re-generating the file,
to make sure we don't alter the existing mapping from field names to numbers.
The pages are generated with Goldsv0.3.2-preview. (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.