github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/protowire/decode_test.go (about) 1 package protowire 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 "io" 9 "math" 10 "reflect" 11 "strconv" 12 "testing" 13 ) 14 15 type ( 16 testOps struct { 17 // appendOps is a sequence of append operations, each appending to 18 // the output of the previous append operation. 19 appendOps []appendOp 20 21 // wantRaw (if not nil) is the bytes that the appendOps should produce. 22 wantRaw []byte 23 24 // consumeOps are a sequence of consume operations, each consuming the 25 // remaining output after the previous consume operation. 26 // The first consume operation starts with the output of appendOps. 27 consumeOps []consumeOp 28 } 29 30 appendOp = interface{} 31 32 appendVarint struct { 33 InVal uint64 34 } 35 appendFixed32 struct { 36 InVal uint32 37 } 38 appendFixed64 struct { 39 InVal uint64 40 } 41 encodeBool struct { 42 InVal bool 43 } 44 encodeByte struct { 45 InVal byte 46 } 47 encodeEnum struct { 48 InVal int32 49 } 50 encodeInt32 struct { 51 InVal int32 52 } 53 encodeSint32 struct { 54 InVal int32 55 } 56 encodeUint32 struct { 57 InVal uint32 58 } 59 encodeInt64 struct { 60 InVal int64 61 } 62 encodeSint64 struct { 63 InVal int64 64 } 65 encodeUint64 struct { 66 InVal uint64 67 } 68 encodeFixed32 struct { 69 InVal uint32 70 } 71 encodeSFixed32 struct { 72 InVal int32 73 } 74 encodeFloat32 struct { 75 InVal float32 76 } 77 encodeFixed64 struct { 78 InVal uint64 79 } 80 encodeSFixed64 struct { 81 InVal int64 82 } 83 encodeDouble struct { 84 InVal float64 85 } 86 encodeString struct { 87 InVal string 88 } 89 encodeBytes struct { 90 intVal []byte 91 } 92 93 appendRaw []byte 94 95 consumeOp = interface{} 96 consumeVarint struct { 97 wantVal uint64 98 wantCnt int 99 wantErr error 100 } 101 consumeFixed32 struct { 102 wantVal uint32 103 wantCnt int 104 wantErr error 105 } 106 consumeFixed64 struct { 107 wantVal uint64 108 wantCnt int 109 wantErr error 110 } 111 consumeBytes struct { 112 wantVal []byte 113 wantCnt int 114 wantErr error 115 } 116 decodeBool struct { 117 wantVal bool 118 wantCnt int 119 wantErr error 120 } 121 decodeByte struct { 122 wantVal byte 123 wantCnt int 124 wantErr error 125 } 126 decodeEnum struct { 127 wantVal int 128 wantCnt int 129 wantErr error 130 } 131 decodeInt32 struct { 132 wantVal int32 133 wantCnt int 134 wantErr error 135 } 136 decodeSint32 struct { 137 wantVal int32 138 wantCnt int 139 wantErr error 140 } 141 decodeUint32 struct { 142 wantVal uint32 143 wantCnt int 144 wantErr error 145 } 146 decodeInt64 struct { 147 wantVal int64 148 wantCnt int 149 wantErr error 150 } 151 decodeSint64 struct { 152 wantVal int64 153 wantCnt int 154 wantErr error 155 } 156 decodeUint64 struct { 157 wantVal uint64 158 wantCnt int 159 wantErr error 160 } 161 decodeFixed32 struct { 162 wantVal uint32 163 wantCnt int 164 wantErr error 165 } 166 decodeSfixed32 struct { 167 wantVal int32 168 wantCnt int 169 wantErr error 170 } 171 decodeFloat32 struct { 172 wantVal float32 173 wantCnt int 174 wantErr error 175 } 176 decodeFixed64 struct { 177 wantVal uint64 178 wantCnt int 179 wantErr error 180 } 181 decodeSfixed64 struct { 182 wantVal int64 183 wantCnt int 184 wantErr error 185 } 186 decodeDouble struct { 187 wantVal float64 188 wantCnt int 189 wantErr error 190 } 191 decodeString struct { 192 wantVal string 193 wantCnt int 194 wantErr error 195 } 196 decodeBytes struct { 197 wantVal []byte 198 wantCnt int 199 wantErr error 200 } 201 ops []interface{} 202 ) 203 204 // dhex decodes a hex-string and returns the bytes and panics if s is invalid. 205 func dhex(s string) []byte { 206 b, err := hex.DecodeString(s) 207 if err != nil { 208 panic(err) 209 } 210 return b 211 } 212 213 var ( 214 errFieldNumber = errors.New("invalid field number") 215 errOverflow = errors.New("variable length integer overflow") 216 errReserved = errors.New("cannot parse reserved wire type") 217 errEndGroup = errors.New("mismatching end group marker") 218 errParse = errors.New("parse error") 219 ) 220 221 // ParseError converts an error code into an error value. 222 // This returns nil if n is a non-negative number. 223 func ParseError(n int) error { 224 if n >= 0 { 225 return nil 226 } 227 switch n { 228 case errCodeTruncated: 229 return io.ErrUnexpectedEOF 230 case errCodeFieldNumber: 231 return errFieldNumber 232 case errCodeOverflow: 233 return errOverflow 234 case errCodeReserved: 235 return errReserved 236 case errCodeEndGroup: 237 return errEndGroup 238 default: 239 return errParse 240 } 241 } 242 243 var OpType2Name = map[interface{}]string{ 244 reflect.TypeOf(appendVarint{}): "Varint_en", 245 reflect.TypeOf(appendFixed32{}): "Fixed32_en", 246 reflect.TypeOf(appendFixed64{}): "Fixed64_en", 247 reflect.TypeOf(encodeBool{}): "Bool_en", 248 reflect.TypeOf(encodeByte{}): "Byte_en", 249 reflect.TypeOf(encodeEnum{}): "Enum_en", 250 reflect.TypeOf(encodeInt32{}): "Int32_en", 251 reflect.TypeOf(encodeSint32{}): "Sint32_en", 252 reflect.TypeOf(encodeUint32{}): "Uint32_en", 253 reflect.TypeOf(encodeInt64{}): "Int64_en", 254 reflect.TypeOf(encodeSint64{}): "Sint64_en", 255 reflect.TypeOf(encodeUint64{}): "Uint64_en", 256 reflect.TypeOf(encodeSFixed32{}): "Sfixed32_en", 257 reflect.TypeOf(encodeFixed32{}): "EncodeFixed32_en", 258 reflect.TypeOf(encodeSFixed64{}): "Sfixed64_en", 259 reflect.TypeOf(encodeFixed64{}): "EncodeFixed64_en", 260 reflect.TypeOf(encodeDouble{}): "Double_en", 261 reflect.TypeOf(encodeString{}): "String_en", 262 reflect.TypeOf(encodeBytes{}): "Bytes_en", 263 } 264 265 func TestVarint(t *testing.T) { 266 runTests(t, []testOps{ 267 { 268 // Test varints at various boundaries where the length changes. 269 appendOps: ops{appendVarint{InVal: 0x0}}, 270 wantRaw: dhex("00"), 271 consumeOps: ops{consumeVarint{wantVal: 0, wantCnt: 1}}, 272 }, { 273 appendOps: ops{appendVarint{InVal: 0x1}}, 274 wantRaw: dhex("01"), 275 consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 1}}, 276 }, { 277 appendOps: ops{appendVarint{InVal: 0x7f}}, 278 wantRaw: dhex("7f"), 279 consumeOps: ops{consumeVarint{wantVal: 0x7f, wantCnt: 1}}, 280 }, { 281 appendOps: ops{appendVarint{InVal: 0x7f + 1}}, 282 wantRaw: dhex("8001"), 283 consumeOps: ops{consumeVarint{wantVal: 0x7f + 1, wantCnt: 2}}, 284 }, { 285 appendOps: ops{appendVarint{InVal: 0x3fff}}, 286 wantRaw: dhex("ff7f"), 287 consumeOps: ops{consumeVarint{wantVal: 0x3fff, wantCnt: 2}}, 288 }, { 289 appendOps: ops{appendVarint{InVal: 0x3fff + 1}}, 290 wantRaw: dhex("808001"), 291 consumeOps: ops{consumeVarint{wantVal: 0x3fff + 1, wantCnt: 3}}, 292 }, { 293 appendOps: ops{appendVarint{InVal: 0x1fffff}}, 294 wantRaw: dhex("ffff7f"), 295 consumeOps: ops{consumeVarint{wantVal: 0x1fffff, wantCnt: 3}}, 296 }, { 297 appendOps: ops{appendVarint{InVal: 0x1fffff + 1}}, 298 wantRaw: dhex("80808001"), 299 consumeOps: ops{consumeVarint{wantVal: 0x1fffff + 1, wantCnt: 4}}, 300 }, { 301 appendOps: ops{appendVarint{InVal: 0xfffffff}}, 302 wantRaw: dhex("ffffff7f"), 303 consumeOps: ops{consumeVarint{wantVal: 0xfffffff, wantCnt: 4}}, 304 }, { 305 appendOps: ops{appendVarint{InVal: 0xfffffff + 1}}, 306 wantRaw: dhex("8080808001"), 307 consumeOps: ops{consumeVarint{wantVal: 0xfffffff + 1, wantCnt: 5}}, 308 }, { 309 appendOps: ops{appendVarint{InVal: 0x7ffffffff}}, 310 wantRaw: dhex("ffffffff7f"), 311 consumeOps: ops{consumeVarint{wantVal: 0x7ffffffff, wantCnt: 5}}, 312 }, { 313 appendOps: ops{appendVarint{InVal: 0x7ffffffff + 1}}, 314 wantRaw: dhex("808080808001"), 315 consumeOps: ops{consumeVarint{wantVal: 0x7ffffffff + 1, wantCnt: 6}}, 316 }, { 317 appendOps: ops{appendVarint{InVal: 0x3ffffffffff}}, 318 wantRaw: dhex("ffffffffff7f"), 319 consumeOps: ops{consumeVarint{wantVal: 0x3ffffffffff, wantCnt: 6}}, 320 }, { 321 appendOps: ops{appendVarint{InVal: 0x3ffffffffff + 1}}, 322 wantRaw: dhex("80808080808001"), 323 consumeOps: ops{consumeVarint{wantVal: 0x3ffffffffff + 1, wantCnt: 7}}, 324 }, { 325 appendOps: ops{appendVarint{InVal: 0x1ffffffffffff}}, 326 wantRaw: dhex("ffffffffffff7f"), 327 consumeOps: ops{consumeVarint{wantVal: 0x1ffffffffffff, wantCnt: 7}}, 328 }, { 329 appendOps: ops{appendVarint{InVal: 0x1ffffffffffff + 1}}, 330 wantRaw: dhex("8080808080808001"), 331 consumeOps: ops{consumeVarint{wantVal: 0x1ffffffffffff + 1, wantCnt: 8}}, 332 }, { 333 appendOps: ops{appendVarint{InVal: 0xffffffffffffff}}, 334 wantRaw: dhex("ffffffffffffff7f"), 335 consumeOps: ops{consumeVarint{wantVal: 0xffffffffffffff, wantCnt: 8}}, 336 }, { 337 appendOps: ops{appendVarint{InVal: 0xffffffffffffff + 1}}, 338 wantRaw: dhex("808080808080808001"), 339 consumeOps: ops{consumeVarint{wantVal: 0xffffffffffffff + 1, wantCnt: 9}}, 340 }, { 341 appendOps: ops{appendVarint{InVal: 0x7fffffffffffffff}}, 342 wantRaw: dhex("ffffffffffffffff7f"), 343 consumeOps: ops{consumeVarint{wantVal: 0x7fffffffffffffff, wantCnt: 9}}, 344 }, { 345 appendOps: ops{appendVarint{InVal: 0x7fffffffffffffff + 1}}, 346 wantRaw: dhex("80808080808080808001"), 347 consumeOps: ops{consumeVarint{wantVal: 0x7fffffffffffffff + 1, wantCnt: 10}}, 348 }, { 349 appendOps: ops{appendVarint{InVal: math.MaxUint64}}, 350 wantRaw: dhex("ffffffffffffffffff01"), 351 consumeOps: ops{consumeVarint{wantVal: math.MaxUint64, wantCnt: 10}}, 352 }, 353 }) 354 } 355 356 func TestFixed32(t *testing.T) { 357 runTests(t, []testOps{{ 358 appendOps: ops{appendFixed32{0}}, 359 wantRaw: dhex("00000000"), 360 consumeOps: ops{consumeFixed32{wantVal: 0, wantCnt: 4}}, 361 }, { 362 appendOps: ops{appendFixed32{math.MaxUint32}}, 363 wantRaw: dhex("ffffffff"), 364 consumeOps: ops{consumeFixed32{wantVal: math.MaxUint32, wantCnt: 4}}, 365 }, { 366 appendOps: ops{appendFixed32{0xf0e1d2c3}}, 367 wantRaw: dhex("c3d2e1f0"), 368 consumeOps: ops{consumeFixed32{wantVal: 0xf0e1d2c3, wantCnt: 4}}, 369 }}) 370 } 371 372 func TestFixed64(t *testing.T) { 373 runTests(t, []testOps{{ 374 appendOps: ops{appendFixed64{0}}, 375 wantRaw: dhex("0000000000000000"), 376 consumeOps: ops{consumeFixed64{wantVal: 0, wantCnt: 8}}, 377 }, { 378 appendOps: ops{appendFixed64{math.MaxUint64}}, 379 wantRaw: dhex("ffffffffffffffff"), 380 consumeOps: ops{consumeFixed64{wantVal: math.MaxUint64, wantCnt: 8}}, 381 }, { 382 appendOps: ops{appendFixed64{0xf0e1d2c3b4a59687}}, 383 wantRaw: dhex("8796a5b4c3d2e1f0"), 384 consumeOps: ops{consumeFixed64{wantVal: 0xf0e1d2c3b4a59687, wantCnt: 8}}, 385 }}) 386 } 387 388 func TestBool(t *testing.T) { 389 runTests(t, []testOps{{ 390 appendOps: ops{encodeBool{true}}, 391 wantRaw: dhex("01"), 392 consumeOps: ops{decodeBool{wantVal: true, wantCnt: 1}}, 393 }, { 394 appendOps: ops{encodeBool{false}}, 395 wantRaw: dhex("00"), 396 consumeOps: ops{decodeBool{wantVal: false, wantCnt: 1}}, 397 }}) 398 } 399 400 func TestByte(t *testing.T) { 401 runTests(t, []testOps{{ 402 appendOps: ops{encodeByte{0x12}}, 403 wantRaw: []byte{0x12}, 404 consumeOps: ops{decodeByte{wantVal: 0x12, wantCnt: 1}}, 405 }, { 406 appendOps: ops{encodeByte{0xff}}, 407 wantRaw: []byte{0xff}, 408 consumeOps: ops{decodeByte{wantVal: 0xff, wantCnt: 1}}, 409 }}) 410 } 411 412 func TestInt32(t *testing.T) { 413 runTests(t, []testOps{ 414 { 415 appendOps: ops{encodeInt32{26984}}, 416 wantRaw: dhex("e8d201"), 417 consumeOps: ops{decodeInt32{wantVal: 26984, wantCnt: 3}}, 418 }, 419 { 420 appendOps: ops{encodeInt32{123}}, 421 wantRaw: []byte{0x7b}, 422 consumeOps: ops{decodeInt32{wantVal: 123, wantCnt: 1}}, 423 }, 424 { 425 appendOps: ops{encodeInt32{2147483647}}, 426 wantRaw: dhex("ffffffff07"), 427 consumeOps: ops{decodeInt32{wantVal: 2147483647, wantCnt: 5}}, 428 }, 429 }) 430 } 431 432 func TestSint32(t *testing.T) { 433 runTests(t, []testOps{ 434 { 435 appendOps: ops{encodeSint32{26984}}, 436 wantRaw: dhex("d0a503"), 437 consumeOps: ops{decodeSint32{wantVal: 26984, wantCnt: 3}}, 438 }, 439 { 440 appendOps: ops{encodeSint32{-1}}, 441 wantRaw: []byte{0x1}, 442 consumeOps: ops{decodeSint32{wantVal: -1, wantCnt: 1}}, 443 }, 444 { 445 appendOps: ops{encodeSint32{-200}}, 446 wantRaw: dhex("8f03"), 447 consumeOps: ops{decodeSint32{wantVal: -200, wantCnt: 2}}, 448 }, 449 }) 450 } 451 452 func TestUint32(t *testing.T) { 453 runTests(t, []testOps{ 454 { 455 appendOps: ops{encodeUint32{26984}}, 456 wantRaw: dhex("e8d201"), 457 consumeOps: ops{decodeUint32{wantVal: 26984, wantCnt: 3}}, 458 }, 459 { 460 appendOps: ops{encodeUint32{10000}}, 461 wantRaw: dhex("904e"), 462 consumeOps: ops{decodeUint32{wantVal: 10000, wantCnt: 2}}, 463 }, 464 { 465 appendOps: ops{encodeUint32{200}}, 466 wantRaw: dhex("c801"), 467 consumeOps: ops{decodeUint32{wantVal: 200, wantCnt: 2}}, 468 }, 469 }) 470 } 471 472 func TestInt64(t *testing.T) { 473 runTests(t, []testOps{ 474 { 475 appendOps: ops{encodeInt64{26984}}, 476 wantRaw: dhex("e8d201"), 477 consumeOps: ops{decodeInt64{wantVal: 26984, wantCnt: 3}}, 478 }, 479 { 480 appendOps: ops{encodeInt64{123}}, 481 wantRaw: []byte{0x7b}, 482 consumeOps: ops{decodeInt64{wantVal: 123, wantCnt: 1}}, 483 }, 484 { 485 appendOps: ops{encodeInt64{2147483647}}, 486 wantRaw: dhex("ffffffff07"), 487 consumeOps: ops{decodeInt64{wantVal: 2147483647, wantCnt: 5}}, 488 }, 489 }) 490 } 491 492 func TestSint64(t *testing.T) { 493 runTests(t, []testOps{ 494 { 495 appendOps: ops{encodeSint64{26984}}, 496 wantRaw: dhex("d0a503"), 497 consumeOps: ops{decodeSint64{wantVal: 26984, wantCnt: 3}}, 498 }, 499 { 500 appendOps: ops{encodeSint64{-1}}, 501 wantRaw: []byte{0x1}, 502 consumeOps: ops{decodeSint64{wantVal: -1, wantCnt: 1}}, 503 }, 504 { 505 appendOps: ops{encodeSint64{-200}}, 506 wantRaw: dhex("8f03"), 507 consumeOps: ops{decodeSint64{wantVal: -200, wantCnt: 2}}, 508 }, 509 }) 510 } 511 512 func TestUint64(t *testing.T) { 513 runTests(t, []testOps{ 514 { 515 appendOps: ops{encodeUint64{26984}}, 516 wantRaw: dhex("e8d201"), 517 consumeOps: ops{decodeUint64{wantVal: 26984, wantCnt: 3}}, 518 }, 519 { 520 appendOps: ops{encodeUint64{10000}}, 521 wantRaw: dhex("904e"), 522 consumeOps: ops{decodeUint64{wantVal: 10000, wantCnt: 2}}, 523 }, 524 { 525 appendOps: ops{encodeUint64{200}}, 526 wantRaw: dhex("c801"), 527 consumeOps: ops{decodeUint64{wantVal: 200, wantCnt: 2}}, 528 }, 529 }) 530 } 531 532 func TestSfixed32(t *testing.T) { 533 runTests(t, []testOps{{ 534 appendOps: ops{encodeSFixed32{0}}, 535 wantRaw: dhex("00000000"), 536 consumeOps: ops{decodeSfixed32{wantVal: 0, wantCnt: 4}}, 537 }, { 538 appendOps: ops{encodeSFixed32{math.MaxInt32}}, 539 wantRaw: dhex("ffffff7f"), 540 consumeOps: ops{decodeSfixed32{wantVal: math.MaxInt32, wantCnt: 4}}, 541 }, { 542 appendOps: ops{encodeSFixed32{1}}, 543 wantRaw: dhex("01000000"), 544 consumeOps: ops{decodeSfixed32{wantVal: 1, wantCnt: 4}}, 545 }}) 546 } 547 548 func TestFloat32(t *testing.T) { 549 runTests(t, []testOps{ 550 { 551 appendOps: ops{encodeFloat32{0.32}}, 552 wantRaw: dhex("0ad7a33e"), 553 consumeOps: ops{decodeFloat32{wantVal: 0.32, wantCnt: 4}}, 554 }, 555 { 556 appendOps: ops{encodeFloat32{1298.222}}, 557 wantRaw: dhex("1b47a244"), 558 consumeOps: ops{decodeFloat32{wantVal: 1298.222, wantCnt: 4}}, 559 }, 560 { 561 appendOps: ops{encodeFloat32{9898989.11}}, 562 wantRaw: dhex("ed0b174b"), 563 consumeOps: ops{decodeFloat32{wantVal: 9898989.11, wantCnt: 4}}, 564 }, 565 }) 566 } 567 568 func TestSfixed64(t *testing.T) { 569 runTests(t, []testOps{ 570 { 571 appendOps: ops{encodeSFixed64{0}}, 572 wantRaw: dhex("0000000000000000"), 573 consumeOps: ops{decodeSfixed64{wantVal: 0, wantCnt: 8}}, 574 }, 575 { 576 appendOps: ops{appendFixed64{math.MaxUint64}}, 577 wantRaw: dhex("ffffffffffffffff"), 578 consumeOps: ops{consumeFixed64{wantVal: math.MaxUint64, wantCnt: 8}}, 579 }, { 580 appendOps: ops{appendFixed64{0xf0e1d2c3b4a59687}}, 581 wantRaw: dhex("8796a5b4c3d2e1f0"), 582 consumeOps: ops{consumeFixed64{wantVal: 0xf0e1d2c3b4a59687, wantCnt: 8}}, 583 }, 584 }) 585 } 586 587 func TestDouble(t *testing.T) { 588 runTests(t, []testOps{ 589 { 590 appendOps: ops{encodeDouble{0.32}}, 591 wantRaw: dhex("7b14ae47e17ad43f"), 592 consumeOps: ops{decodeDouble{wantVal: 0.32, wantCnt: 8}}, 593 }, 594 { 595 appendOps: ops{encodeDouble{1298.222}}, 596 wantRaw: dhex("d9cef753e3489440"), 597 consumeOps: ops{decodeDouble{wantVal: 1298.222, wantCnt: 8}}, 598 }, 599 { 600 appendOps: ops{encodeDouble{9898989.11}}, 601 wantRaw: dhex("b81e85a37de16241"), 602 consumeOps: ops{decodeDouble{wantVal: 9898989.11, wantCnt: 8}}, 603 }, 604 }) 605 } 606 607 func TestString(t *testing.T) { 608 runTests(t, []testOps{ 609 { 610 appendOps: ops{encodeString{"aabbcc"}}, 611 wantRaw: dhex("06616162626363"), 612 consumeOps: ops{decodeString{wantVal: "aabbcc", wantCnt: 7}}, 613 }, 614 { 615 appendOps: ops{encodeString{"dau9bkn;jasdf"}}, 616 wantRaw: dhex("0d64617539626b6e3b6a61736466"), 617 consumeOps: ops{decodeString{wantVal: "dau9bkn;jasdf", wantCnt: 14}}, 618 }, 619 }) 620 } 621 622 func TestBytes(t *testing.T) { 623 runTests(t, []testOps{ 624 { 625 appendOps: ops{encodeBytes{[]byte{0x61, 0x61, 0x62, 0x62, 0x63, 0x63}}}, 626 wantRaw: dhex("06616162626363"), 627 consumeOps: ops{decodeBytes{wantVal: []byte{0x61, 0x61, 0x62, 0x62, 0x63, 0x63}, wantCnt: 7}}, 628 }, 629 { 630 appendOps: ops{encodeBytes{[]byte{0x64, 0x61, 0x75, 0x39, 0x62, 0x6b, 0x6e, 0x3b, 0x6a, 0x61, 0x73, 0x64, 0x66}}}, 631 wantRaw: dhex("0d64617539626b6e3b6a61736466"), 632 consumeOps: ops{decodeBytes{wantVal: []byte{0x64, 0x61, 0x75, 0x39, 0x62, 0x6b, 0x6e, 0x3b, 0x6a, 0x61, 0x73, 0x64, 0x66}, wantCnt: 14}}, 633 }, 634 }) 635 } 636 637 func runTests(t *testing.T, tests []testOps) { 638 for _, tt := range tests { 639 t.Run("", func(t *testing.T) { 640 var b []byte 641 for _, op := range tt.appendOps { 642 b0 := b 643 switch op := op.(type) { 644 case appendVarint: 645 b = AppendVarint(b, op.InVal) 646 case appendFixed32: 647 b = AppendFixed32(b, op.InVal) 648 case appendFixed64: 649 b = AppendFixed64(b, op.InVal) 650 case encodeBool: 651 b = BinaryEncoder{}.EncodeBool(b, op.InVal) 652 case encodeByte: 653 b = BinaryEncoder{}.EncodeByte(b, op.InVal) 654 case encodeEnum: 655 b = BinaryEncoder{}.EncodeEnum(b, op.InVal) 656 case encodeInt32: 657 b = BinaryEncoder{}.EncodeInt32(b, op.InVal) 658 case encodeSint32: 659 b = BinaryEncoder{}.EncodeSint32(b, op.InVal) 660 case encodeUint32: 661 b = BinaryEncoder{}.EncodeUint32(b, op.InVal) 662 case encodeInt64: 663 b = BinaryEncoder{}.EncodeInt64(b, op.InVal) 664 case encodeSint64: 665 b = BinaryEncoder{}.EncodeSint64(b, op.InVal) 666 case encodeUint64: 667 b = BinaryEncoder{}.EncodeUint64(b, op.InVal) 668 case encodeSFixed32: 669 b = BinaryEncoder{}.EncodeSfixed32(b, op.InVal) 670 case encodeFixed32: 671 b = BinaryEncoder{}.EncodeFixed32(b, op.InVal) 672 case encodeSFixed64: 673 b = BinaryEncoder{}.EncodeSfixed64(b, op.InVal) 674 case encodeFixed64: 675 b = BinaryEncoder{}.EncodeFixed64(b, op.InVal) 676 case encodeFloat32: 677 b = BinaryEncoder{}.EncodeFloat32(b, op.InVal) 678 case encodeDouble: 679 b = BinaryEncoder{}.EncodeDouble(b, op.InVal) 680 case encodeString: 681 b = BinaryEncoder{}.EncodeString(b, op.InVal) 682 case encodeBytes: 683 b = BinaryEncoder{}.EncodeBytes(b, op.intVal) 684 case appendRaw: 685 b = append(b, op...) 686 } 687 688 check := func(label string, want int) { 689 t.Helper() 690 if got := len(b) - len(b0); got != want { 691 t.Errorf("len(Append%v) and Size%v mismatch: got %v, want %v", label, label, got, want) 692 } 693 } 694 695 switch op := op.(type) { 696 case appendVarint, encodeEnum, encodeInt32, encodeUint32, encodeInt64, encodeUint64: 697 data_str := fmt.Sprint(reflect.ValueOf(op).Field(0).Interface()) 698 data_conv, _ := strconv.ParseUint(data_str, 10, 64) 699 check(OpType2Name[op], SizeVarint(data_conv)) 700 case appendFixed32, encodeFixed32, encodeSFixed32, encodeFloat32: 701 check(OpType2Name[op], SizeFixed32()) 702 case appendFixed64, encodeFixed64, encodeSFixed64: 703 check(OpType2Name[op], SizeFixed64()) 704 case encodeBool, encodeByte: 705 check(OpType2Name[op], 1) 706 case encodeSint32, encodeSint64: 707 data_str := fmt.Sprint(reflect.ValueOf(op).Field(0).Interface()) 708 data_conv, _ := strconv.ParseInt(data_str, 10, 64) 709 check(OpType2Name[op], SizeVarint(EncodeZigZag(data_conv))) 710 } 711 } 712 713 if tt.wantRaw != nil && !bytes.Equal(b, tt.wantRaw) { 714 t.Errorf("raw output mismatch:\ngot %x\nwant %x", b, tt.wantRaw) 715 } 716 717 for _, op := range tt.consumeOps { 718 check := func(label string, gotCnt, wantCnt int, wantErr error) { 719 t.Helper() 720 gotErr := ParseError(gotCnt) 721 if gotCnt < 0 { 722 gotCnt = 0 723 } 724 if gotCnt != wantCnt { 725 t.Errorf("Consume%v(): consumed %d bytes, want %d bytes consumed", label, gotCnt, wantCnt) 726 } 727 if gotErr != wantErr { 728 t.Errorf("Consume%v(): got %v error, want %v error", label, gotErr, wantErr) 729 } 730 b = b[gotCnt:] 731 } 732 switch op := op.(type) { 733 case consumeVarint: 734 gotVal, n := ConsumeVarint(b) 735 if gotVal != op.wantVal { 736 t.Errorf("ConsumeVarint() = %d, want %d", gotVal, op.wantVal) 737 } 738 check("Varint_de", n, op.wantCnt, op.wantErr) 739 case consumeFixed32: 740 gotVal, n := ConsumeFixed32(b) 741 if gotVal != op.wantVal { 742 t.Errorf("ConsumeFixed32() = %d, want %d", gotVal, op.wantVal) 743 } 744 check("Fixed32_de", n, op.wantCnt, op.wantErr) 745 case consumeFixed64: 746 gotVal, n := ConsumeFixed64(b) 747 if gotVal != op.wantVal { 748 t.Errorf("ConsumeFixed64() = %d, want %d", gotVal, op.wantVal) 749 } 750 check("Fixed64_de", n, op.wantCnt, op.wantErr) 751 case consumeBytes: 752 gotVal, _, n := ConsumeBytes(b) 753 if !bytes.Equal(gotVal, op.wantVal) { 754 t.Errorf("ConsumeBytes() = %x, want %x", gotVal, op.wantVal) 755 } 756 check("Bytes_de", n, op.wantCnt, op.wantErr) 757 case decodeBool: 758 gotVal, n := BinaryDecoder{}.DecodeBool(b) 759 if gotVal != op.wantVal { 760 t.Errorf("DecodeBool() = %t, want %t", gotVal, op.wantVal) 761 } 762 check("Bool_de", n, op.wantCnt, op.wantErr) 763 case decodeByte: 764 gotVal := BinaryDecoder{}.DecodeByte(b) 765 if gotVal != op.wantVal { 766 t.Errorf("DecodeByte() = %d, want %d", gotVal, op.wantVal) 767 } 768 check("Byte_de", 1, op.wantCnt, op.wantErr) 769 case decodeInt32: 770 gotVal, n := BinaryDecoder{}.DecodeInt32(b) 771 if gotVal != op.wantVal { 772 t.Errorf("DecodeInt32() = %d, want %d", gotVal, op.wantVal) 773 } 774 check("Int32_de", n, op.wantCnt, op.wantErr) 775 case decodeSint32: 776 gotVal, n := BinaryDecoder{}.DecodeSint32(b) 777 if gotVal != op.wantVal { 778 t.Errorf("DecodeSint32() = %d, want %d", gotVal, op.wantVal) 779 } 780 check("Sint32_de", n, op.wantCnt, op.wantErr) 781 case decodeUint32: 782 gotVal, n := BinaryDecoder{}.DecodeUint32(b) 783 if gotVal != op.wantVal { 784 t.Errorf("DecodeUint32() = %d, want %d", gotVal, op.wantVal) 785 } 786 check("Uint32_de", n, op.wantCnt, op.wantErr) 787 case decodeInt64: 788 gotVal, n := BinaryDecoder{}.DecodeInt64(b) 789 if gotVal != op.wantVal { 790 t.Errorf("DecodeInt64() = %d, want %d", gotVal, op.wantVal) 791 } 792 check("Int64_de", n, op.wantCnt, op.wantErr) 793 case decodeSint64: 794 gotVal, n := BinaryDecoder{}.DecodeSint64(b) 795 if gotVal != op.wantVal { 796 t.Errorf("DecodeSint64() = %d, want %d", gotVal, op.wantVal) 797 } 798 check("Sint64_de", n, op.wantCnt, op.wantErr) 799 case decodeUint64: 800 gotVal, n := BinaryDecoder{}.DecodeUint64(b) 801 if gotVal != op.wantVal { 802 t.Errorf("DecodeUint64() = %d, want %d", gotVal, op.wantVal) 803 } 804 check("Uint64_de", n, op.wantCnt, op.wantErr) 805 case decodeFixed32: 806 gotVal, n := BinaryDecoder{}.DecodeFixed32(b) 807 if gotVal != op.wantVal { 808 t.Errorf("DecodeFixed32() = %d, want %d", gotVal, op.wantVal) 809 } 810 check("DecodeFixed32_de", n, op.wantCnt, op.wantErr) 811 case decodeSfixed32: 812 gotVal, n := BinaryDecoder{}.DecodeSfixed32(b) 813 if gotVal != op.wantVal { 814 t.Errorf("DecodeSfixed32() = %d, want %d", gotVal, op.wantVal) 815 } 816 check("DecodeSfixed32_de", n, op.wantCnt, op.wantErr) 817 case decodeFloat32: 818 gotVal, n := BinaryDecoder{}.DecodeFloat32(b) 819 if gotVal != op.wantVal { 820 t.Errorf("DecodeFloat32() = %f, want %f", gotVal, op.wantVal) 821 } 822 check("Float32_de", n, op.wantCnt, op.wantErr) 823 case decodeFixed64: 824 gotVal, n := BinaryDecoder{}.DecodeFixed64(b) 825 if gotVal != op.wantVal { 826 t.Errorf("DecodeFixed64() = %d, want %d", gotVal, op.wantVal) 827 } 828 check("DecodeFixed64_de", n, op.wantCnt, op.wantErr) 829 case decodeSfixed64: 830 gotVal, n := BinaryDecoder{}.DecodeSfixed64(b) 831 if gotVal != op.wantVal { 832 t.Errorf("DecodeSfixed64() = %d, want %d", gotVal, op.wantVal) 833 } 834 check("DecodeSfixed64_de", n, op.wantCnt, op.wantErr) 835 case decodeDouble: 836 gotVal, n := BinaryDecoder{}.DecodeDouble(b) 837 if gotVal != op.wantVal { 838 t.Errorf("DecodeDouble() = %f, want %f", gotVal, op.wantVal) 839 } 840 check("Double_de", n, op.wantCnt, op.wantErr) 841 case decodeString: 842 gotVal, _, n := BinaryDecoder{}.DecodeString(b) 843 if gotVal != op.wantVal { 844 t.Errorf("DecodeString() = %s, want %s", gotVal, op.wantVal) 845 } 846 check("String_de", n, op.wantCnt, op.wantErr) 847 case decodeBytes: 848 gotVal, _, n := BinaryDecoder{}.DecodeBytes(b) 849 if !bytes.Equal(gotVal, op.wantVal) { 850 t.Errorf("DecodeBytes() = %x, want %x", gotVal, op.wantVal) 851 } 852 check("DecodeBytes_de", n, op.wantCnt, op.wantErr) 853 } 854 } 855 }) 856 } 857 } 858 859 860 func TestZigZag(t *testing.T) { 861 tests := []struct { 862 dec int64 863 enc uint64 864 }{ 865 {math.MinInt64 + 0, math.MaxUint64 - 0}, 866 {math.MinInt64 + 1, math.MaxUint64 - 2}, 867 {math.MinInt64 + 2, math.MaxUint64 - 4}, 868 {-3, 5}, 869 {-2, 3}, 870 {-1, 1}, 871 {0, 0}, 872 {+1, 2}, 873 {+2, 4}, 874 {+3, 6}, 875 {math.MaxInt64 - 2, math.MaxUint64 - 5}, 876 {math.MaxInt64 - 1, math.MaxUint64 - 3}, 877 {math.MaxInt64 - 0, math.MaxUint64 - 1}, 878 } 879 880 for _, tt := range tests { 881 if enc := EncodeZigZag(tt.dec); enc != tt.enc { 882 t.Errorf("EncodeZigZag(%d) = %d, want %d", tt.dec, enc, tt.enc) 883 } 884 if dec := DecodeZigZag(tt.enc); dec != tt.dec { 885 t.Errorf("DecodeZigZag(%d) = %d, want %d", tt.enc, dec, tt.dec) 886 } 887 } 888 }