github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/xdr2/encode.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 package xdr 18 19 import ( 20 "fmt" 21 "io" 22 "math" 23 "reflect" 24 "time" 25 ) 26 27 var errIOEncode = "%s while encoding %d bytes" 28 29 /* 30 Marshal writes the XDR encoding of v to writer w and returns the number of bytes 31 written. It traverses v recursively and automatically indirects pointers 32 through arbitrary depth to encode the actual value pointed to. 33 34 Marshal uses reflection to determine the type of the concrete value contained by 35 v and performs a mapping of Go types to the underlying XDR types as follows: 36 37 Go Type -> XDR Type 38 -------------------- 39 int8, int16, int32, int -> XDR Integer 40 uint8, uint16, uint32, uint -> XDR Unsigned Integer 41 int64 -> XDR Hyper Integer 42 uint64 -> XDR Unsigned Hyper Integer 43 bool -> XDR Boolean 44 float32 -> XDR Floating-Point 45 float64 -> XDR Double-Precision Floating-Point 46 string -> XDR String 47 byte -> XDR Integer 48 []byte -> XDR Variable-Length Opaque Data 49 [#]byte -> XDR Fixed-Length Opaque Data 50 []<type> -> XDR Variable-Length Array 51 [#]<type> -> XDR Fixed-Length Array 52 struct -> XDR Structure 53 map -> XDR Variable-Length Array of two-element XDR Structures 54 time.Time -> XDR String encoded with RFC3339 nanosecond precision 55 56 Notes and Limitations: 57 58 * Automatic marshalling of variable and fixed-length arrays of uint8s 59 requires a special struct tag `xdropaque:"false"` since byte slices and 60 byte arrays are assumed to be opaque data and byte is a Go alias for uint8 61 thus indistinguishable under reflection 62 * Channel, complex, and function types cannot be encoded 63 * Interfaces without a concrete value cannot be encoded 64 * Cyclic data structures are not supported and will result in infinite loops 65 * Strings are marshalled with UTF-8 character encoding which differs from 66 the XDR specification of ASCII, however UTF-8 is backwards compatible with 67 ASCII so this should rarely cause issues 68 69 If any issues are encountered during the marshalling process, a MarshalError is 70 returned with a human readable description as well as an ErrorCode value for 71 further inspection from sophisticated callers. Some potential issues are 72 unsupported Go types, attempting to encode more opaque data than can be 73 represented by a single opaque XDR entry, and exceeding max slice limitations. 74 */ 75 func Marshal(w io.Writer, v interface{}) (int, error) { 76 enc := Encoder{w: w} 77 return enc.Encode(v) 78 } 79 80 // An Encoder wraps an io.Writer that will receive the XDR encoded byte stream. 81 // See NewEncoder. 82 type Encoder struct { 83 w io.Writer 84 } 85 86 // EncodeInt writes the XDR encoded representation of the passed 32-bit signed 87 // integer to the encapsulated writer and returns the number of bytes written. 88 // 89 // A MarshalError with an error code of ErrIO is returned if writing the data 90 // fails. 91 // 92 // Reference: 93 // RFC Section 4.1 - Integer 94 // 32-bit big-endian signed integer in range [-2147483648, 2147483647] 95 func (enc *Encoder) EncodeInt(v int32) (int, error) { 96 var b [4]byte 97 b[0] = byte(v >> 24) 98 b[1] = byte(v >> 16) 99 b[2] = byte(v >> 8) 100 b[3] = byte(v) 101 102 n, err := enc.w.Write(b[:]) 103 if err != nil { 104 msg := fmt.Sprintf(errIOEncode, err.Error(), 4) 105 err := marshalError("EncodeInt", ErrIO, msg, b[:n], err) 106 return n, err 107 } 108 109 return n, nil 110 } 111 112 // EncodeUint writes the XDR encoded representation of the passed 32-bit 113 // unsigned integer to the encapsulated writer and returns the number of bytes 114 // written. 115 // 116 // A MarshalError with an error code of ErrIO is returned if writing the data 117 // fails. 118 // 119 // Reference: 120 // RFC Section 4.2 - Unsigned Integer 121 // 32-bit big-endian unsigned integer in range [0, 4294967295] 122 func (enc *Encoder) EncodeUint(v uint32) (int, error) { 123 var b [4]byte 124 b[0] = byte(v >> 24) 125 b[1] = byte(v >> 16) 126 b[2] = byte(v >> 8) 127 b[3] = byte(v) 128 129 n, err := enc.w.Write(b[:]) 130 if err != nil { 131 msg := fmt.Sprintf(errIOEncode, err.Error(), 4) 132 err := marshalError("EncodeUint", ErrIO, msg, b[:n], err) 133 return n, err 134 } 135 136 return n, nil 137 } 138 139 // EncodeEnum treats the passed 32-bit signed integer as an enumeration value 140 // and, if it is in the list of passed valid enumeration values, writes the XDR 141 // encoded representation of it to the encapsulated writer. It returns the 142 // number of bytes written. 143 // 144 // A MarshalError is returned if the enumeration value is not one of the 145 // provided valid values or if writing the data fails. 146 // 147 // Reference: 148 // RFC Section 4.3 - Enumeration 149 // Represented as an XDR encoded signed integer 150 func (enc *Encoder) EncodeEnum(v int32, validEnums map[int32]bool) (int, error) { 151 if !validEnums[v] { 152 err := marshalError("EncodeEnum", ErrBadEnumValue, 153 "invalid enum", v, nil) 154 return 0, err 155 } 156 return enc.EncodeInt(v) 157 } 158 159 // EncodeBool writes the XDR encoded representation of the passed boolean to the 160 // encapsulated writer and returns the number of bytes written. 161 // 162 // A MarshalError with an error code of ErrIO is returned if writing the data 163 // fails. 164 // 165 // Reference: 166 // RFC Section 4.4 - Boolean 167 // Represented as an XDR encoded enumeration where 0 is false and 1 is true 168 func (enc *Encoder) EncodeBool(v bool) (int, error) { 169 i := int32(0) 170 if v == true { 171 i = 1 172 } 173 return enc.EncodeInt(i) 174 } 175 176 // EncodeHyper writes the XDR encoded representation of the passed 64-bit 177 // signed integer to the encapsulated writer and returns the number of bytes 178 // written. 179 // 180 // A MarshalError with an error code of ErrIO is returned if writing the data 181 // fails. 182 // 183 // Reference: 184 // RFC Section 4.5 - Hyper Integer 185 // 64-bit big-endian signed integer in range [-9223372036854775808, 9223372036854775807] 186 func (enc *Encoder) EncodeHyper(v int64) (int, error) { 187 var b [8]byte 188 b[0] = byte(v >> 56) 189 b[1] = byte(v >> 48) 190 b[2] = byte(v >> 40) 191 b[3] = byte(v >> 32) 192 b[4] = byte(v >> 24) 193 b[5] = byte(v >> 16) 194 b[6] = byte(v >> 8) 195 b[7] = byte(v) 196 197 n, err := enc.w.Write(b[:]) 198 if err != nil { 199 msg := fmt.Sprintf(errIOEncode, err.Error(), 8) 200 err := marshalError("EncodeHyper", ErrIO, msg, b[:n], err) 201 return n, err 202 } 203 204 return n, nil 205 } 206 207 // EncodeUhyper writes the XDR encoded representation of the passed 64-bit 208 // unsigned integer to the encapsulated writer and returns the number of bytes 209 // written. 210 // 211 // A MarshalError with an error code of ErrIO is returned if writing the data 212 // fails. 213 // 214 // Reference: 215 // RFC Section 4.5 - Unsigned Hyper Integer 216 // 64-bit big-endian unsigned integer in range [0, 18446744073709551615] 217 func (enc *Encoder) EncodeUhyper(v uint64) (int, error) { 218 var b [8]byte 219 b[0] = byte(v >> 56) 220 b[1] = byte(v >> 48) 221 b[2] = byte(v >> 40) 222 b[3] = byte(v >> 32) 223 b[4] = byte(v >> 24) 224 b[5] = byte(v >> 16) 225 b[6] = byte(v >> 8) 226 b[7] = byte(v) 227 228 n, err := enc.w.Write(b[:]) 229 if err != nil { 230 msg := fmt.Sprintf(errIOEncode, err.Error(), 8) 231 err := marshalError("EncodeUhyper", ErrIO, msg, b[:n], err) 232 return n, err 233 } 234 235 return n, nil 236 } 237 238 // EncodeFloat writes the XDR encoded representation of the passed 32-bit 239 // (single-precision) floating point to the encapsulated writer and returns the 240 // number of bytes written. 241 // 242 // A MarshalError with an error code of ErrIO is returned if writing the data 243 // fails. 244 // 245 // Reference: 246 // RFC Section 4.6 - Floating Point 247 // 32-bit single-precision IEEE 754 floating point 248 func (enc *Encoder) EncodeFloat(v float32) (int, error) { 249 ui := math.Float32bits(v) 250 return enc.EncodeUint(ui) 251 } 252 253 // EncodeDouble writes the XDR encoded representation of the passed 64-bit 254 // (double-precision) floating point to the encapsulated writer and returns the 255 // number of bytes written. 256 // 257 // A MarshalError with an error code of ErrIO is returned if writing the data 258 // fails. 259 // 260 // Reference: 261 // RFC Section 4.7 - Double-Precision Floating Point 262 // 64-bit double-precision IEEE 754 floating point 263 func (enc *Encoder) EncodeDouble(v float64) (int, error) { 264 ui := math.Float64bits(v) 265 return enc.EncodeUhyper(ui) 266 } 267 268 // RFC Section 4.8 - Quadruple-Precision Floating Point 269 // 128-bit quadruple-precision floating point 270 // Not Implemented 271 272 // EncodeFixedOpaque treats the passed byte slice as opaque data of a fixed 273 // size and writes the XDR encoded representation of it to the encapsulated 274 // writer. It returns the number of bytes written. 275 // 276 // A MarshalError with an error code of ErrIO is returned if writing the data 277 // fails. 278 // 279 // Reference: 280 // RFC Section 4.9 - Fixed-Length Opaque Data 281 // Fixed-length uninterpreted data zero-padded to a multiple of four 282 func (enc *Encoder) EncodeFixedOpaque(v []byte) (int, error) { 283 l := len(v) 284 pad := (4 - (l % 4)) % 4 285 286 // Write the actual bytes. 287 n, err := enc.w.Write(v) 288 if err != nil { 289 msg := fmt.Sprintf(errIOEncode, err.Error(), len(v)) 290 err := marshalError("EncodeFixedOpaque", ErrIO, msg, v[:n], err) 291 return n, err 292 } 293 294 // Write any padding if needed. 295 if pad > 0 { 296 b := make([]byte, pad) 297 n2, err := enc.w.Write(b) 298 n += n2 299 if err != nil { 300 written := make([]byte, l+n2) 301 copy(written, v) 302 copy(written[l:], b[:n2]) 303 msg := fmt.Sprintf(errIOEncode, err.Error(), l+pad) 304 err := marshalError("EncodeFixedOpaque", ErrIO, msg, 305 written, err) 306 return n, err 307 } 308 } 309 310 return n, nil 311 } 312 313 // EncodeOpaque treats the passed byte slice as opaque data of a variable 314 // size and writes the XDR encoded representation of it to the encapsulated 315 // writer. It returns the number of bytes written. 316 // 317 // A MarshalError with an error code of ErrIO is returned if writing the data 318 // fails. 319 // 320 // Reference: 321 // RFC Section 4.10 - Variable-Length Opaque Data 322 // Unsigned integer length followed by fixed opaque data of that length 323 func (enc *Encoder) EncodeOpaque(v []byte) (int, error) { 324 // Length of opaque data. 325 n, err := enc.EncodeUint(uint32(len(v))) 326 if err != nil { 327 return n, err 328 } 329 330 n2, err := enc.EncodeFixedOpaque(v) 331 n += n2 332 return n, err 333 } 334 335 // EncodeString writes the XDR encoded representation of the passed string 336 // to the encapsulated writer and returns the number of bytes written. 337 // Character encoding is assumed to be UTF-8 and therefore ASCII compatible. If 338 // the underlying character encoding is not compatible with this assumption, the 339 // data can instead be written as variable-length opaque data (EncodeOpaque) and 340 // manually converted as needed. 341 // 342 // A MarshalError with an error code of ErrIO is returned if writing the data 343 // fails. 344 // 345 // Reference: 346 // RFC Section 4.11 - String 347 // Unsigned integer length followed by bytes zero-padded to a multiple of four 348 func (enc *Encoder) EncodeString(v string) (int, error) { 349 // Length of string. 350 n, err := enc.EncodeUint(uint32(len(v))) 351 if err != nil { 352 return n, err 353 } 354 355 n2, err := enc.EncodeFixedOpaque([]byte(v)) 356 n += n2 357 return n, err 358 } 359 360 // encodeFixedArray writes the XDR encoded representation of each element 361 // in the passed array represented by the reflection value to the encapsulated 362 // writer and returns the number of bytes written. The ignoreOpaque flag 363 // controls whether or not uint8 (byte) elements should be encoded individually 364 // or as a fixed sequence of opaque data. 365 // 366 // A MarshalError is returned if any issues are encountered while encoding 367 // the array elements. 368 // 369 // Reference: 370 // RFC Section 4.12 - Fixed-Length Array 371 // Individually XDR encoded array elements 372 func (enc *Encoder) encodeFixedArray(v reflect.Value, ignoreOpaque bool) (int, error) { 373 // Treat [#]byte (byte is alias for uint8) as opaque data unless ignored. 374 if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 { 375 // Create a slice of the underlying array for better efficiency 376 // when possible. Can't create a slice of an unaddressable 377 // value. 378 if v.CanAddr() { 379 return enc.EncodeFixedOpaque(v.Slice(0, v.Len()).Bytes()) 380 } 381 382 // When the underlying array isn't addressable fall back to 383 // copying the array into a new slice. This is rather ugly, but 384 // the inability to create a constant slice from an 385 // unaddressable array is a limitation of Go. 386 slice := make([]byte, v.Len(), v.Len()) 387 reflect.Copy(reflect.ValueOf(slice), v) 388 return enc.EncodeFixedOpaque(slice) 389 } 390 391 // Encode each array element. 392 var n int 393 for i := 0; i < v.Len(); i++ { 394 n2, err := enc.encode(v.Index(i)) 395 n += n2 396 if err != nil { 397 return n, err 398 } 399 } 400 401 return n, nil 402 } 403 404 // encodeArray writes an XDR encoded integer representing the number of 405 // elements in the passed slice represented by the reflection value followed by 406 // the XDR encoded representation of each element in slice to the encapsulated 407 // writer and returns the number of bytes written. The ignoreOpaque flag 408 // controls whether or not uint8 (byte) elements should be encoded individually 409 // or as a variable sequence of opaque data. 410 // 411 // A MarshalError is returned if any issues are encountered while encoding 412 // the array elements. 413 // 414 // Reference: 415 // RFC Section 4.13 - Variable-Length Array 416 // Unsigned integer length followed by individually XDR encoded array elements 417 func (enc *Encoder) encodeArray(v reflect.Value, ignoreOpaque bool) (int, error) { 418 numItems := uint32(v.Len()) 419 n, err := enc.EncodeUint(numItems) 420 if err != nil { 421 return n, err 422 } 423 424 n2, err := enc.encodeFixedArray(v, ignoreOpaque) 425 n += n2 426 return n, err 427 } 428 429 // encodeStruct writes an XDR encoded representation of each value in the 430 // exported fields of the struct represented by the passed reflection value to 431 // the encapsulated writer and returns the number of bytes written. Pointers 432 // are automatically indirected through arbitrary depth to encode the actual 433 // value pointed to. 434 // 435 // A MarshalError is returned if any issues are encountered while encoding 436 // the elements. 437 // 438 // Reference: 439 // RFC Section 4.14 - Structure 440 // XDR encoded elements in the order of their declaration in the struct 441 func (enc *Encoder) encodeStruct(v reflect.Value) (int, error) { 442 var n int 443 vt := v.Type() 444 for i := 0; i < v.NumField(); i++ { 445 // Skip unexported fields and indirect through pointers. 446 vtf := vt.Field(i) 447 if vtf.PkgPath != "" { 448 continue 449 } 450 vf := v.Field(i) 451 vf = enc.indirect(vf) 452 453 // Handle non-opaque data to []uint8 and [#]uint8 based on struct tag. 454 tag := vtf.Tag.Get("xdropaque") 455 if tag == "false" { 456 switch vf.Kind() { 457 case reflect.Slice: 458 n2, err := enc.encodeArray(vf, true) 459 n += n2 460 if err != nil { 461 return n, err 462 } 463 continue 464 465 case reflect.Array: 466 n2, err := enc.encodeFixedArray(vf, true) 467 n += n2 468 if err != nil { 469 return n, err 470 } 471 continue 472 } 473 } 474 475 // Encode each struct field. 476 n2, err := enc.encode(vf) 477 n += n2 478 if err != nil { 479 return n, err 480 } 481 } 482 483 return n, nil 484 } 485 486 // RFC Section 4.15 - Discriminated Union 487 // RFC Section 4.16 - Void 488 // RFC Section 4.17 - Constant 489 // RFC Section 4.18 - Typedef 490 // RFC Section 4.19 - Optional data 491 // RFC Sections 4.15 though 4.19 only apply to the data specification language 492 // which is not implemented by this package. In the case of discriminated 493 // unions, struct tags are used to perform a similar function. 494 495 // encodeMap treats the map represented by the passed reflection value as a 496 // variable-length array of 2-element structures whose fields are of the same 497 // type as the map keys and elements and writes its XDR encoded representation 498 // to the encapsulated writer. It returns the number of bytes written. 499 // 500 // A MarshalError is returned if any issues are encountered while encoding 501 // the elements. 502 func (enc *Encoder) encodeMap(v reflect.Value) (int, error) { 503 // Number of elements. 504 n, err := enc.EncodeUint(uint32(v.Len())) 505 if err != nil { 506 return n, err 507 } 508 509 // Encode each key and value according to their type. 510 for _, key := range v.MapKeys() { 511 n2, err := enc.encode(key) 512 n += n2 513 if err != nil { 514 return n, err 515 } 516 517 n2, err = enc.encode(v.MapIndex(key)) 518 n += n2 519 if err != nil { 520 return n, err 521 } 522 } 523 524 return n, nil 525 } 526 527 // encodeInterface examines the interface represented by the passed reflection 528 // value to detect whether it is an interface that can be encoded if it is, 529 // extracts the underlying value to pass back into the encode function for 530 // encoding according to its type. 531 // 532 // A MarshalError is returned if any issues are encountered while encoding 533 // the interface. 534 func (enc *Encoder) encodeInterface(v reflect.Value) (int, error) { 535 if v.IsNil() || !v.CanInterface() { 536 msg := fmt.Sprintf("can't encode nil interface") 537 err := marshalError("encodeInterface", ErrNilInterface, msg, 538 nil, nil) 539 return 0, err 540 } 541 542 // Extract underlying value from the interface and indirect through pointers. 543 ve := reflect.ValueOf(v.Interface()) 544 ve = enc.indirect(ve) 545 return enc.encode(ve) 546 } 547 548 // encode is the main workhorse for marshalling via reflection. It uses 549 // the passed reflection value to choose the XDR primitives to encode into 550 // the encapsulated writer and returns the number of bytes written. It is a 551 // recursive function, so cyclic data structures are not supported and will 552 // result in an infinite loop. 553 func (enc *Encoder) encode(v reflect.Value) (int, error) { 554 if !v.IsValid() { 555 msg := fmt.Sprintf("type '%s' is not valid", v.Kind().String()) 556 err := marshalError("encode", ErrUnsupportedType, msg, nil, nil) 557 return 0, err 558 } 559 560 // Indirect through pointers to get at the concrete value. 561 ve := enc.indirect(v) 562 563 // Handle time.Time values by encoding them as an RFC3339 formatted 564 // string with nanosecond precision. Check the type string before 565 // doing a full blown conversion to interface and type assertion since 566 // checking a string is much quicker. 567 if ve.Type().String() == "time.Time" && ve.CanInterface() { 568 viface := ve.Interface() 569 if tv, ok := viface.(time.Time); ok { 570 return enc.EncodeString(tv.Format(time.RFC3339Nano)) 571 } 572 } 573 574 // Handle native Go types. 575 switch ve.Kind() { 576 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int: 577 return enc.EncodeInt(int32(ve.Int())) 578 579 case reflect.Int64: 580 return enc.EncodeHyper(ve.Int()) 581 582 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint: 583 return enc.EncodeUint(uint32(ve.Uint())) 584 585 case reflect.Uint64: 586 return enc.EncodeUhyper(ve.Uint()) 587 588 case reflect.Bool: 589 return enc.EncodeBool(ve.Bool()) 590 591 case reflect.Float32: 592 return enc.EncodeFloat(float32(ve.Float())) 593 594 case reflect.Float64: 595 return enc.EncodeDouble(ve.Float()) 596 597 case reflect.String: 598 return enc.EncodeString(ve.String()) 599 600 case reflect.Array: 601 return enc.encodeFixedArray(ve, false) 602 603 case reflect.Slice: 604 return enc.encodeArray(ve, false) 605 606 case reflect.Struct: 607 return enc.encodeStruct(ve) 608 609 case reflect.Map: 610 return enc.encodeMap(ve) 611 612 case reflect.Interface: 613 return enc.encodeInterface(ve) 614 } 615 616 // The only unhandled types left are unsupported. At the time of this 617 // writing the only remaining unsupported types that exist are 618 // reflect.Uintptr and reflect.UnsafePointer. 619 msg := fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String()) 620 err := marshalError("encode", ErrUnsupportedType, msg, nil, nil) 621 return 0, err 622 } 623 624 // indirect dereferences pointers until it reaches a non-pointer. This allows 625 // transparent encoding through arbitrary levels of indirection. 626 func (enc *Encoder) indirect(v reflect.Value) reflect.Value { 627 rv := v 628 for rv.Kind() == reflect.Ptr { 629 rv = rv.Elem() 630 } 631 return rv 632 } 633 634 // Encode operates identically to the Marshal function with the exception of 635 // using the writer associated with the Encoder for the destination of the 636 // XDR-encoded data instead of a user-supplied writer. See the Marshal 637 // documentation for specifics. 638 func (enc *Encoder) Encode(v interface{}) (int, error) { 639 if v == nil { 640 msg := "can't marshal nil interface" 641 err := marshalError("Marshal", ErrNilInterface, msg, nil, nil) 642 return 0, err 643 } 644 645 vv := reflect.ValueOf(v) 646 vve := vv 647 for vve.Kind() == reflect.Ptr { 648 if vve.IsNil() { 649 msg := fmt.Sprintf("can't marshal nil pointer '%v'", 650 vv.Type().String()) 651 err := marshalError("Marshal", ErrBadArguments, msg, 652 nil, nil) 653 return 0, err 654 } 655 vve = vve.Elem() 656 } 657 658 return enc.encode(vve) 659 } 660 661 // NewEncoder returns an object that can be used to manually choose fields to 662 // XDR encode to the passed writer w. Typically, Marshal should be used instead 663 // of manually creating an Encoder. An Encoder, along with several of its 664 // methods to encode XDR primitives, is exposed so it is possible to perform 665 // manual encoding of data without relying on reflection should it be necessary 666 // in complex scenarios where automatic reflection-based encoding won't work. 667 func NewEncoder(w io.Writer) *Encoder { 668 return &Encoder{w: w} 669 }