github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/xdr/doc.go (about)

     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  /*
    18  Package xdr implements the data representation portion of the External Data
    19  Representation (XDR) standard protocol as specified in RFC 4506 (obsoletes
    20  RFC 1832 and RFC 1014).
    21  
    22  The XDR RFC defines both a data specification language and a data
    23  representation standard.  This package implements methods to encode
    24  and decode XDR data per the data representation standard with the exception
    25  of 128-bit quadruple-precision floating points.  It does not currently implement
    26  parsing of the data specification language.  In other words, the ability to
    27  automatically generate Go code by parsing an XDR data specification file
    28  (typically .x extension) is not supported.  In practice, this limitation of the
    29  package is fairly minor since it is largely unnecessary due to the reflection
    30  capabilities of Go as described below.
    31  
    32  This package provides two approaches for encoding and decoding XDR data:
    33  
    34  	1) Marshal/Unmarshal functions which automatically map between XDR and Go types
    35  	2) Individual Encoder/Decoder objects to manually work with XDR primitives
    36  
    37  For the Marshal/Unmarshal functions, Go reflection capabilities are used to choose
    38  the type of the underlying XDR data based upon the Go type to encode or the target
    39  Go type to decode into.  A description of how each type is mapped is provided
    40  below, however one important type worth reviewing is Go structs.  In the case of
    41  structs, each exported field (first letter capitalized) is reflected and mapped
    42  in order.  As a result, this means a Go struct with exported fields of the
    43  appropriate types listed in the expected order can be used to automatically
    44  encode / decode the XDR data thereby eliminating the need to write a lot of
    45  boilerplate code to encode/decode and error check each piece of XDR data as is
    46  typically required with C based XDR libraries.
    47  
    48  Go Type to XDR Type Mappings
    49  
    50  The following chart shows an overview of how Go types are mapped to XDR types
    51  for automatic marshalling and unmarshalling.  The documentation for the Marshal
    52  and Unmarshal functions has specific details of how the mapping proceeds.
    53  
    54  	Go Type <-> XDR Type
    55  	--------------------
    56  	int8, int16, int32, int <-> XDR Integer
    57  	uint8, uint16, uint32, uint <-> XDR Unsigned Integer
    58  	int64 <-> XDR Hyper Integer
    59  	uint64 <-> XDR Unsigned Hyper Integer
    60  	bool <-> XDR Boolean
    61  	float32 <-> XDR Floating-Point
    62  	float64 <-> XDR Double-Precision Floating-Point
    63  	string <-> XDR String
    64  	byte <-> 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
    69  	struct <-> XDR Structure
    70  	map <-> XDR Variable-Length Array of two-element XDR Structures
    71  	time.Time <-> XDR String encoded with RFC3339 nanosecond precision
    72  
    73  Notes and Limitations:
    74  
    75  	* Automatic marshalling and unmarshalling of variable and fixed-length arrays
    76  	  of uint8s require a special struct tag `xdropaque:"false"` since byte
    77  	  slices and byte arrays are assumed to be opaque data and byte is a Go
    78  	  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 loops
    82  	* Strings are marshalled and unmarshalled with UTF-8 character encoding
    83  	  which differs from the XDR specification of ASCII, however UTF-8 is
    84  	  backwards compatible with ASCII so this should rarely cause issues
    85  
    86  
    87  Encoding
    88  
    89  To encode XDR data, use the Marshal function.
    90  	func Marshal(v interface{}) (rv []byte, err error)
    91  
    92  For example, given the following code snippet:
    93  
    94  	type ImageHeader struct {
    95  		Signature	[3]byte
    96  		Version		uint32
    97  		IsGrayscale	bool
    98  		NumSections	uint32
    99  	}
   100  	h := ImageHeader{[3]byte{0xAB, 0xCD, 0xEF}, 2, true, 10}
   101  
   102  	encodedData, err := xdr.Marshal(&h)
   103  	// Error check elided
   104  
   105  The result, encodedData, will then contain the following XDR encoded byte
   106  sequence:
   107  
   108  	0xAB, 0xCD, 0xEF, 0x00,
   109  	0x00, 0x00, 0x00, 0x02,
   110  	0x00, 0x00, 0x00, 0x01,
   111  	0x00, 0x00, 0x00, 0x0A
   112  
   113  
   114  In addition, while the automatic marshalling discussed above will work for the
   115  vast majority of cases, an Encoder object is provided that can be used to
   116  manually encode XDR primitives for complex scenarios where automatic
   117  reflection-based encoding won't work.  The included examples provide a sample of
   118  manual usage via an Encoder.
   119  
   120  
   121  Decoding
   122  
   123  To decode XDR data, use the Unmarshal function.
   124  	func Unmarshal(data []byte, v interface{}) (rest []byte, err error)
   125  
   126  For example, given the following code snippet:
   127  
   128  	type ImageHeader struct {
   129  		Signature	[3]byte
   130  		Version		uint32
   131  		IsGrayscale	bool
   132  		NumSections	uint32
   133  	}
   134  
   135  	// Using output from the Encoding section above.
   136  	encodedData := []byte{
   137  		0xAB, 0xCD, 0xEF, 0x00,
   138  		0x00, 0x00, 0x00, 0x02,
   139  		0x00, 0x00, 0x00, 0x01,
   140  		0x00, 0x00, 0x00, 0x0A}
   141  
   142  	var h ImageHeader
   143  	remainingBytes, err := xdr.Unmarshal(encodedData, &h)
   144  	// Error check elided
   145  
   146  The struct instance, h, will then contain the following values:
   147  
   148  	h.Signature = [3]byte{0xAB, 0xCD, 0xEF}
   149  	h.Version = 2
   150  	h.IsGrayscale = true
   151  	h.NumSections = 10
   152  
   153  In addition, while the automatic unmarshalling discussed above will work for the
   154  vast majority of cases, a Decoder object is provided that can be used to
   155  manually decode XDR primitives for complex scenarios where automatic
   156  reflection-based decoding won't work.  The included examples provide a sample of
   157  manual usage via an Decoder.
   158  
   159  Errors
   160  
   161  All errors are either of type UnmarshalError or MarshalError.  Both provide
   162  human readable output as well as an ErrorCode field which can be inspected by
   163  sophisticated callers if necessary
   164  
   165  See the documentation of UnmarshalError, MarshalError, and ErrorCode for further
   166  details.
   167  
   168  */
   169  package xdr