podman
171 строка · 6.4 Кб
1/*
2* Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
3*
4* Permission to use, copy, modify, and distribute this software for any
5* purpose with or without fee is hereby granted, provided that the above
6* copyright notice and this permission notice appear in all copies.
7*
8* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*/
16
17/*
18Package xdr implements the data representation portion of the External Data
19Representation (XDR) standard protocol as specified in RFC 4506 (obsoletes
20RFC 1832 and RFC 1014).
21
22The XDR RFC defines both a data specification language and a data
23representation standard. This package implements methods to encode and decode
24XDR data per the data representation standard with the exception of 128-bit
25quadruple-precision floating points. It does not currently implement parsing of
26the data specification language. In other words, the ability to automatically
27generate Go code by parsing an XDR data specification file (typically .x
28extension) is not supported. In practice, this limitation of the package is
29fairly minor since it is largely unnecessary due to the reflection capabilities
30of Go as described below.
31
32This package provides two approaches for encoding and decoding XDR data:
33
341) Marshal/Unmarshal functions which automatically map between XDR and Go types
352) Individual Encoder/Decoder objects to manually work with XDR primitives
36
37For the Marshal/Unmarshal functions, Go reflection capabilities are used to
38choose the type of the underlying XDR data based upon the Go type to encode or
39the target Go type to decode into. A description of how each type is mapped is
40provided below, however one important type worth reviewing is Go structs. In
41the case of structs, each exported field (first letter capitalized) is reflected
42and mapped in order. As a result, this means a Go struct with exported fields
43of the appropriate types listed in the expected order can be used to
44automatically encode / decode the XDR data thereby eliminating the need to write
45a lot of boilerplate code to encode/decode and error check each piece of XDR
46data as is typically required with C based XDR libraries.
47
48Go Type to XDR Type Mappings
49
50The following chart shows an overview of how Go types are mapped to XDR types
51for automatic marshalling and unmarshalling. The documentation for the Marshal
52and Unmarshal functions has specific details of how the mapping proceeds.
53
54Go Type <-> XDR Type
55--------------------
56int8, int16, int32, int <-> XDR Integer
57uint8, uint16, uint32, uint <-> XDR Unsigned Integer
58int64 <-> XDR Hyper Integer
59uint64 <-> XDR Unsigned Hyper Integer
60bool <-> XDR Boolean
61float32 <-> XDR Floating-Point
62float64 <-> XDR Double-Precision Floating-Point
63string <-> XDR String
64byte <-> XDR Integer
65[]byte <-> XDR Variable-Length Opaque Data
66[#]byte <-> XDR Fixed-Length Opaque Data
67[]<type> <-> XDR Variable-Length Array
68[#]<type> <-> XDR Fixed-Length Array
69struct <-> XDR Structure
70map <-> XDR Variable-Length Array of two-element XDR Structures
71time.Time <-> XDR String encoded with RFC3339 nanosecond precision
72
73Notes and Limitations:
74
75* Automatic marshalling and unmarshalling of variable and fixed-length
76arrays of uint8s require a special struct tag `xdropaque:"false"`
77since byte slices and byte arrays are assumed to be opaque data and
78byte is a Go alias for uint8 thus indistinguishable under reflection
79* Channel, complex, and function types cannot be encoded
80* Interfaces without a concrete value cannot be encoded
81* Cyclic data structures are not supported and will result in infinite
82loops
83* Strings are marshalled and unmarshalled with UTF-8 character encoding
84which differs from the XDR specification of ASCII, however UTF-8 is
85backwards compatible with ASCII so this should rarely cause issues
86
87
88Encoding
89
90To encode XDR data, use the Marshal function.
91func Marshal(w io.Writer, v interface{}) (int, error)
92
93For example, given the following code snippet:
94
95type ImageHeader struct {
96Signature [3]byte
97Version uint32
98IsGrayscale bool
99NumSections uint32
100}
101h := ImageHeader{[3]byte{0xAB, 0xCD, 0xEF}, 2, true, 10}
102
103var w bytes.Buffer
104bytesWritten, err := xdr.Marshal(&w, &h)
105// Error check elided
106
107The result, encodedData, will then contain the following XDR encoded byte
108sequence:
109
1100xAB, 0xCD, 0xEF, 0x00,
1110x00, 0x00, 0x00, 0x02,
1120x00, 0x00, 0x00, 0x01,
1130x00, 0x00, 0x00, 0x0A
114
115
116In addition, while the automatic marshalling discussed above will work for the
117vast majority of cases, an Encoder object is provided that can be used to
118manually encode XDR primitives for complex scenarios where automatic
119reflection-based encoding won't work. The included examples provide a sample of
120manual usage via an Encoder.
121
122
123Decoding
124
125To decode XDR data, use the Unmarshal function.
126func Unmarshal(r io.Reader, v interface{}) (int, error)
127
128For example, given the following code snippet:
129
130type ImageHeader struct {
131Signature [3]byte
132Version uint32
133IsGrayscale bool
134NumSections uint32
135}
136
137// Using output from the Encoding section above.
138encodedData := []byte{
1390xAB, 0xCD, 0xEF, 0x00,
1400x00, 0x00, 0x00, 0x02,
1410x00, 0x00, 0x00, 0x01,
1420x00, 0x00, 0x00, 0x0A,
143}
144
145var h ImageHeader
146bytesRead, err := xdr.Unmarshal(bytes.NewReader(encodedData), &h)
147// Error check elided
148
149The struct instance, h, will then contain the following values:
150
151h.Signature = [3]byte{0xAB, 0xCD, 0xEF}
152h.Version = 2
153h.IsGrayscale = true
154h.NumSections = 10
155
156In addition, while the automatic unmarshalling discussed above will work for the
157vast majority of cases, a Decoder object is provided that can be used to
158manually decode XDR primitives for complex scenarios where automatic
159reflection-based decoding won't work. The included examples provide a sample of
160manual usage via a Decoder.
161
162Errors
163
164All errors are either of type UnmarshalError or MarshalError. Both provide
165human-readable output as well as an ErrorCode field which can be inspected by
166sophisticated callers if necessary.
167
168See the documentation of UnmarshalError, MarshalError, and ErrorCode for further
169details.
170*/
171package xdr172