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
17package xdr_test
18
19import (
20	"bytes"
21	"fmt"
22
23	"github.com/davecgh/go-xdr/xdr2"
24)
25
26// This example demonstrates how to use Marshal to automatically XDR encode
27// data using reflection.
28func ExampleMarshal() {
29	// Hypothetical image header format.
30	type ImageHeader struct {
31		Signature   [3]byte
32		Version     uint32
33		IsGrayscale bool
34		NumSections uint32
35	}
36
37	// Sample image header data.
38	h := ImageHeader{[3]byte{0xAB, 0xCD, 0xEF}, 2, true, 10}
39
40	// Use marshal to automatically determine the appropriate underlying XDR
41	// types and encode.
42	var w bytes.Buffer
43	bytesWritten, err := xdr.Marshal(&w, &h)
44	if err != nil {
45		fmt.Println(err)
46		return
47	}
48
49	fmt.Println("bytes written:", bytesWritten)
50	fmt.Println("encoded data:", w.Bytes())
51
52	// Output:
53	// bytes written: 16
54	// encoded data: [171 205 239 0 0 0 0 2 0 0 0 1 0 0 0 10]
55}
56
57// This example demonstrates how to use Unmarshal to decode XDR encoded data
58// from a byte slice into a struct.
59func ExampleUnmarshal() {
60	// Hypothetical image header format.
61	type ImageHeader struct {
62		Signature   [3]byte
63		Version     uint32
64		IsGrayscale bool
65		NumSections uint32
66	}
67
68	// XDR encoded data described by the above structure.  Typically this
69	// would be read from a file or across the network, but use a manual
70	// byte array here as an example.
71	encodedData := []byte{
72		0xAB, 0xCD, 0xEF, 0x00, // Signature
73		0x00, 0x00, 0x00, 0x02, // Version
74		0x00, 0x00, 0x00, 0x01, // IsGrayscale
75		0x00, 0x00, 0x00, 0x0A, // NumSections
76	}
77
78	// Declare a variable to provide Unmarshal with a concrete type and
79	// instance to decode into.
80	var h ImageHeader
81	bytesRead, err := xdr.Unmarshal(bytes.NewReader(encodedData), &h)
82	if err != nil {
83		fmt.Println(err)
84		return
85	}
86
87	fmt.Println("bytes read:", bytesRead)
88	fmt.Printf("h: %+v", h)
89
90	// Output:
91	// bytes read: 16
92	// h: {Signature:[171 205 239] Version:2 IsGrayscale:true NumSections:10}
93}
94
95// This example demonstrates how to manually decode XDR encoded data from a
96// reader. Compare this example with the Unmarshal example which performs the
97// same task automatically by utilizing a struct type definition and reflection.
98func ExampleNewDecoder() {
99	// XDR encoded data for a hypothetical ImageHeader struct as follows:
100	// type ImageHeader struct {
101	// 		Signature	[3]byte
102	// 		Version		uint32
103	// 		IsGrayscale	bool
104	// 		NumSections	uint32
105	// }
106	encodedData := []byte{
107		0xAB, 0xCD, 0xEF, 0x00, // Signature
108		0x00, 0x00, 0x00, 0x02, // Version
109		0x00, 0x00, 0x00, 0x01, // IsGrayscale
110		0x00, 0x00, 0x00, 0x0A, // NumSections
111	}
112
113	// Get a new decoder for manual decoding.
114	dec := xdr.NewDecoder(bytes.NewReader(encodedData))
115
116	signature, _, err := dec.DecodeFixedOpaque(3)
117	if err != nil {
118		fmt.Println(err)
119		return
120	}
121
122	version, _, err := dec.DecodeUint()
123	if err != nil {
124		fmt.Println(err)
125		return
126	}
127
128	isGrayscale, _, err := dec.DecodeBool()
129	if err != nil {
130		fmt.Println(err)
131		return
132	}
133
134	numSections, _, err := dec.DecodeUint()
135	if err != nil {
136		fmt.Println(err)
137		return
138	}
139
140	fmt.Println("signature:", signature)
141	fmt.Println("version:", version)
142	fmt.Println("isGrayscale:", isGrayscale)
143	fmt.Println("numSections:", numSections)
144
145	// Output:
146	// signature: [171 205 239]
147	// version: 2
148	// isGrayscale: true
149	// numSections: 10
150}
151
152// This example demonstrates how to manually encode XDR data from Go variables.
153// Compare this example with the Marshal example which performs the same task
154// automatically by utilizing a struct type definition and reflection.
155func ExampleNewEncoder() {
156	// Data for a hypothetical ImageHeader struct as follows:
157	// type ImageHeader struct {
158	// 		Signature	[3]byte
159	//		Version		uint32
160	//		IsGrayscale	bool
161	//		NumSections	uint32
162	// }
163	signature := []byte{0xAB, 0xCD, 0xEF}
164	version := uint32(2)
165	isGrayscale := true
166	numSections := uint32(10)
167
168	// Get a new encoder for manual encoding.
169	var w bytes.Buffer
170	enc := xdr.NewEncoder(&w)
171
172	_, err := enc.EncodeFixedOpaque(signature)
173	if err != nil {
174		fmt.Println(err)
175		return
176	}
177
178	_, err = enc.EncodeUint(version)
179	if err != nil {
180		fmt.Println(err)
181		return
182	}
183
184	_, err = enc.EncodeBool(isGrayscale)
185	if err != nil {
186		fmt.Println(err)
187		return
188	}
189
190	_, err = enc.EncodeUint(numSections)
191	if err != nil {
192		fmt.Println(err)
193		return
194	}
195
196	fmt.Println("encoded data:", w.Bytes())
197
198	// Output:
199	// encoded data: [171 205 239 0 0 0 0 2 0 0 0 1 0 0 0 10]
200}
201