1*1c12ee1eSDan Willemsen// Copyright 2018 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsenpackage protowire 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "bytes" 9*1c12ee1eSDan Willemsen "encoding/hex" 10*1c12ee1eSDan Willemsen "io" 11*1c12ee1eSDan Willemsen "math" 12*1c12ee1eSDan Willemsen "strings" 13*1c12ee1eSDan Willemsen "testing" 14*1c12ee1eSDan Willemsen) 15*1c12ee1eSDan Willemsen 16*1c12ee1eSDan Willemsentype ( 17*1c12ee1eSDan Willemsen testOps struct { 18*1c12ee1eSDan Willemsen // appendOps is a sequence of append operations, each appending to 19*1c12ee1eSDan Willemsen // the output of the previous append operation. 20*1c12ee1eSDan Willemsen appendOps []appendOp 21*1c12ee1eSDan Willemsen 22*1c12ee1eSDan Willemsen // wantRaw (if not nil) is the bytes that the appendOps should produce. 23*1c12ee1eSDan Willemsen wantRaw []byte 24*1c12ee1eSDan Willemsen 25*1c12ee1eSDan Willemsen // consumeOps are a sequence of consume operations, each consuming the 26*1c12ee1eSDan Willemsen // remaining output after the previous consume operation. 27*1c12ee1eSDan Willemsen // The first consume operation starts with the output of appendOps. 28*1c12ee1eSDan Willemsen consumeOps []consumeOp 29*1c12ee1eSDan Willemsen } 30*1c12ee1eSDan Willemsen 31*1c12ee1eSDan Willemsen // appendOp represents an Append operation. 32*1c12ee1eSDan Willemsen appendOp = interface{} 33*1c12ee1eSDan Willemsen appendTag struct { 34*1c12ee1eSDan Willemsen inNum Number 35*1c12ee1eSDan Willemsen inType Type 36*1c12ee1eSDan Willemsen } 37*1c12ee1eSDan Willemsen appendVarint struct { 38*1c12ee1eSDan Willemsen inVal uint64 39*1c12ee1eSDan Willemsen } 40*1c12ee1eSDan Willemsen appendFixed32 struct { 41*1c12ee1eSDan Willemsen inVal uint32 42*1c12ee1eSDan Willemsen } 43*1c12ee1eSDan Willemsen appendFixed64 struct { 44*1c12ee1eSDan Willemsen inVal uint64 45*1c12ee1eSDan Willemsen } 46*1c12ee1eSDan Willemsen appendBytes struct { 47*1c12ee1eSDan Willemsen inVal []byte 48*1c12ee1eSDan Willemsen } 49*1c12ee1eSDan Willemsen appendGroup struct { 50*1c12ee1eSDan Willemsen inNum Number 51*1c12ee1eSDan Willemsen inVal []byte 52*1c12ee1eSDan Willemsen } 53*1c12ee1eSDan Willemsen appendRaw []byte 54*1c12ee1eSDan Willemsen 55*1c12ee1eSDan Willemsen // consumeOp represents an Consume operation. 56*1c12ee1eSDan Willemsen consumeOp = interface{} 57*1c12ee1eSDan Willemsen consumeField struct { 58*1c12ee1eSDan Willemsen wantNum Number 59*1c12ee1eSDan Willemsen wantType Type 60*1c12ee1eSDan Willemsen wantCnt int 61*1c12ee1eSDan Willemsen wantErr error 62*1c12ee1eSDan Willemsen } 63*1c12ee1eSDan Willemsen consumeFieldValue struct { 64*1c12ee1eSDan Willemsen inNum Number 65*1c12ee1eSDan Willemsen inType Type 66*1c12ee1eSDan Willemsen wantCnt int 67*1c12ee1eSDan Willemsen wantErr error 68*1c12ee1eSDan Willemsen } 69*1c12ee1eSDan Willemsen consumeTag struct { 70*1c12ee1eSDan Willemsen wantNum Number 71*1c12ee1eSDan Willemsen wantType Type 72*1c12ee1eSDan Willemsen wantCnt int 73*1c12ee1eSDan Willemsen wantErr error 74*1c12ee1eSDan Willemsen } 75*1c12ee1eSDan Willemsen consumeVarint struct { 76*1c12ee1eSDan Willemsen wantVal uint64 77*1c12ee1eSDan Willemsen wantCnt int 78*1c12ee1eSDan Willemsen wantErr error 79*1c12ee1eSDan Willemsen } 80*1c12ee1eSDan Willemsen consumeFixed32 struct { 81*1c12ee1eSDan Willemsen wantVal uint32 82*1c12ee1eSDan Willemsen wantCnt int 83*1c12ee1eSDan Willemsen wantErr error 84*1c12ee1eSDan Willemsen } 85*1c12ee1eSDan Willemsen consumeFixed64 struct { 86*1c12ee1eSDan Willemsen wantVal uint64 87*1c12ee1eSDan Willemsen wantCnt int 88*1c12ee1eSDan Willemsen wantErr error 89*1c12ee1eSDan Willemsen } 90*1c12ee1eSDan Willemsen consumeBytes struct { 91*1c12ee1eSDan Willemsen wantVal []byte 92*1c12ee1eSDan Willemsen wantCnt int 93*1c12ee1eSDan Willemsen wantErr error 94*1c12ee1eSDan Willemsen } 95*1c12ee1eSDan Willemsen consumeGroup struct { 96*1c12ee1eSDan Willemsen inNum Number 97*1c12ee1eSDan Willemsen wantVal []byte 98*1c12ee1eSDan Willemsen wantCnt int 99*1c12ee1eSDan Willemsen wantErr error 100*1c12ee1eSDan Willemsen } 101*1c12ee1eSDan Willemsen 102*1c12ee1eSDan Willemsen ops []interface{} 103*1c12ee1eSDan Willemsen) 104*1c12ee1eSDan Willemsen 105*1c12ee1eSDan Willemsen// dhex decodes a hex-string and returns the bytes and panics if s is invalid. 106*1c12ee1eSDan Willemsenfunc dhex(s string) []byte { 107*1c12ee1eSDan Willemsen b, err := hex.DecodeString(s) 108*1c12ee1eSDan Willemsen if err != nil { 109*1c12ee1eSDan Willemsen panic(err) 110*1c12ee1eSDan Willemsen } 111*1c12ee1eSDan Willemsen return b 112*1c12ee1eSDan Willemsen} 113*1c12ee1eSDan Willemsen 114*1c12ee1eSDan Willemsenfunc TestTag(t *testing.T) { 115*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 116*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 117*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantErr: io.ErrUnexpectedEOF}}, 118*1c12ee1eSDan Willemsen }, { 119*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 0, inType: Fixed32Type}}, 120*1c12ee1eSDan Willemsen wantRaw: dhex("05"), 121*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantErr: errFieldNumber}}, 122*1c12ee1eSDan Willemsen }, { 123*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 1, inType: Fixed32Type}}, 124*1c12ee1eSDan Willemsen wantRaw: dhex("0d"), 125*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantNum: 1, wantType: Fixed32Type, wantCnt: 1}}, 126*1c12ee1eSDan Willemsen }, { 127*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: FirstReservedNumber, inType: BytesType}}, 128*1c12ee1eSDan Willemsen wantRaw: dhex("c2a309"), 129*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantNum: FirstReservedNumber, wantType: BytesType, wantCnt: 3}}, 130*1c12ee1eSDan Willemsen }, { 131*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: LastReservedNumber, inType: StartGroupType}}, 132*1c12ee1eSDan Willemsen wantRaw: dhex("fbe109"), 133*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantNum: LastReservedNumber, wantType: StartGroupType, wantCnt: 3}}, 134*1c12ee1eSDan Willemsen }, { 135*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: MaxValidNumber, inType: VarintType}}, 136*1c12ee1eSDan Willemsen wantRaw: dhex("f8ffffff0f"), 137*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantNum: MaxValidNumber, wantType: VarintType, wantCnt: 5}}, 138*1c12ee1eSDan Willemsen }, { 139*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: ((math.MaxInt32+1)<<3 | uint64(VarintType))}}, 140*1c12ee1eSDan Willemsen wantRaw: dhex("8080808040"), 141*1c12ee1eSDan Willemsen consumeOps: ops{consumeTag{wantErr: errFieldNumber}}, 142*1c12ee1eSDan Willemsen }}) 143*1c12ee1eSDan Willemsen} 144*1c12ee1eSDan Willemsen 145*1c12ee1eSDan Willemsenfunc TestVarint(t *testing.T) { 146*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 147*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 148*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 149*1c12ee1eSDan Willemsen }, { 150*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("80"))}, 151*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 152*1c12ee1eSDan Willemsen }, { 153*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8080"))}, 154*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 155*1c12ee1eSDan Willemsen }, { 156*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("808080"))}, 157*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 158*1c12ee1eSDan Willemsen }, { 159*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("80808080"))}, 160*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 161*1c12ee1eSDan Willemsen }, { 162*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8080808080"))}, 163*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 164*1c12ee1eSDan Willemsen }, { 165*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("808080808080"))}, 166*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 167*1c12ee1eSDan Willemsen }, { 168*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("80808080808080"))}, 169*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 170*1c12ee1eSDan Willemsen }, { 171*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8080808080808080"))}, 172*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 173*1c12ee1eSDan Willemsen }, { 174*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("808080808080808080"))}, 175*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: io.ErrUnexpectedEOF}}, 176*1c12ee1eSDan Willemsen }, { 177*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("80808080808080808080"))}, 178*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: errOverflow}}, 179*1c12ee1eSDan Willemsen }, { 180*1c12ee1eSDan Willemsen // Test varints at various boundaries where the length changes. 181*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x0}}, 182*1c12ee1eSDan Willemsen wantRaw: dhex("00"), 183*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0, wantCnt: 1}}, 184*1c12ee1eSDan Willemsen }, { 185*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x1}}, 186*1c12ee1eSDan Willemsen wantRaw: dhex("01"), 187*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 1}}, 188*1c12ee1eSDan Willemsen }, { 189*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7f}}, 190*1c12ee1eSDan Willemsen wantRaw: dhex("7f"), 191*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7f, wantCnt: 1}}, 192*1c12ee1eSDan Willemsen }, { 193*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7f + 1}}, 194*1c12ee1eSDan Willemsen wantRaw: dhex("8001"), 195*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7f + 1, wantCnt: 2}}, 196*1c12ee1eSDan Willemsen }, { 197*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x3fff}}, 198*1c12ee1eSDan Willemsen wantRaw: dhex("ff7f"), 199*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x3fff, wantCnt: 2}}, 200*1c12ee1eSDan Willemsen }, { 201*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x3fff + 1}}, 202*1c12ee1eSDan Willemsen wantRaw: dhex("808001"), 203*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x3fff + 1, wantCnt: 3}}, 204*1c12ee1eSDan Willemsen }, { 205*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x1fffff}}, 206*1c12ee1eSDan Willemsen wantRaw: dhex("ffff7f"), 207*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x1fffff, wantCnt: 3}}, 208*1c12ee1eSDan Willemsen }, { 209*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x1fffff + 1}}, 210*1c12ee1eSDan Willemsen wantRaw: dhex("80808001"), 211*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x1fffff + 1, wantCnt: 4}}, 212*1c12ee1eSDan Willemsen }, { 213*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0xfffffff}}, 214*1c12ee1eSDan Willemsen wantRaw: dhex("ffffff7f"), 215*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0xfffffff, wantCnt: 4}}, 216*1c12ee1eSDan Willemsen }, { 217*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0xfffffff + 1}}, 218*1c12ee1eSDan Willemsen wantRaw: dhex("8080808001"), 219*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0xfffffff + 1, wantCnt: 5}}, 220*1c12ee1eSDan Willemsen }, { 221*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7ffffffff}}, 222*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffff7f"), 223*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7ffffffff, wantCnt: 5}}, 224*1c12ee1eSDan Willemsen }, { 225*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7ffffffff + 1}}, 226*1c12ee1eSDan Willemsen wantRaw: dhex("808080808001"), 227*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7ffffffff + 1, wantCnt: 6}}, 228*1c12ee1eSDan Willemsen }, { 229*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x3ffffffffff}}, 230*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffff7f"), 231*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x3ffffffffff, wantCnt: 6}}, 232*1c12ee1eSDan Willemsen }, { 233*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x3ffffffffff + 1}}, 234*1c12ee1eSDan Willemsen wantRaw: dhex("80808080808001"), 235*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x3ffffffffff + 1, wantCnt: 7}}, 236*1c12ee1eSDan Willemsen }, { 237*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x1ffffffffffff}}, 238*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffffff7f"), 239*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x1ffffffffffff, wantCnt: 7}}, 240*1c12ee1eSDan Willemsen }, { 241*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x1ffffffffffff + 1}}, 242*1c12ee1eSDan Willemsen wantRaw: dhex("8080808080808001"), 243*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x1ffffffffffff + 1, wantCnt: 8}}, 244*1c12ee1eSDan Willemsen }, { 245*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0xffffffffffffff}}, 246*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffffffff7f"), 247*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0xffffffffffffff, wantCnt: 8}}, 248*1c12ee1eSDan Willemsen }, { 249*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0xffffffffffffff + 1}}, 250*1c12ee1eSDan Willemsen wantRaw: dhex("808080808080808001"), 251*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0xffffffffffffff + 1, wantCnt: 9}}, 252*1c12ee1eSDan Willemsen }, { 253*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7fffffffffffffff}}, 254*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffffffffff7f"), 255*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7fffffffffffffff, wantCnt: 9}}, 256*1c12ee1eSDan Willemsen }, { 257*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: 0x7fffffffffffffff + 1}}, 258*1c12ee1eSDan Willemsen wantRaw: dhex("80808080808080808001"), 259*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 0x7fffffffffffffff + 1, wantCnt: 10}}, 260*1c12ee1eSDan Willemsen }, { 261*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{inVal: math.MaxUint64}}, 262*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffffffffffff01"), 263*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: math.MaxUint64, wantCnt: 10}}, 264*1c12ee1eSDan Willemsen }, { 265*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("ffffffffffffffffff02"))}, 266*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: errOverflow}}, 267*1c12ee1eSDan Willemsen }, { 268*1c12ee1eSDan Willemsen // Test denormalized varints; where the encoding, while valid, is 269*1c12ee1eSDan Willemsen // larger than necessary. 270*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("01"))}, 271*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 1}}, 272*1c12ee1eSDan Willemsen }, { 273*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8100"))}, 274*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 2}}, 275*1c12ee1eSDan Willemsen }, { 276*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("818000"))}, 277*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 3}}, 278*1c12ee1eSDan Willemsen }, { 279*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("81808000"))}, 280*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 4}}, 281*1c12ee1eSDan Willemsen }, { 282*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8180808000"))}, 283*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 5}}, 284*1c12ee1eSDan Willemsen }, { 285*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("818080808000"))}, 286*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 6}}, 287*1c12ee1eSDan Willemsen }, { 288*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("81808080808000"))}, 289*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 7}}, 290*1c12ee1eSDan Willemsen }, { 291*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8180808080808000"))}, 292*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 8}}, 293*1c12ee1eSDan Willemsen }, { 294*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("818080808080808000"))}, 295*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 9}}, 296*1c12ee1eSDan Willemsen }, { 297*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("81808080808080808000"))}, 298*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantVal: 1, wantCnt: 10}}, 299*1c12ee1eSDan Willemsen }, { 300*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("8180808080808080808000"))}, 301*1c12ee1eSDan Willemsen consumeOps: ops{consumeVarint{wantErr: errOverflow}}, 302*1c12ee1eSDan Willemsen }}) 303*1c12ee1eSDan Willemsen} 304*1c12ee1eSDan Willemsen 305*1c12ee1eSDan Willemsenfunc TestFixed32(t *testing.T) { 306*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 307*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 308*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed32{wantErr: io.ErrUnexpectedEOF}}, 309*1c12ee1eSDan Willemsen }, { 310*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("000000"))}, 311*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed32{wantErr: io.ErrUnexpectedEOF}}, 312*1c12ee1eSDan Willemsen }, { 313*1c12ee1eSDan Willemsen appendOps: ops{appendFixed32{0}}, 314*1c12ee1eSDan Willemsen wantRaw: dhex("00000000"), 315*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed32{wantVal: 0, wantCnt: 4}}, 316*1c12ee1eSDan Willemsen }, { 317*1c12ee1eSDan Willemsen appendOps: ops{appendFixed32{math.MaxUint32}}, 318*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffff"), 319*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed32{wantVal: math.MaxUint32, wantCnt: 4}}, 320*1c12ee1eSDan Willemsen }, { 321*1c12ee1eSDan Willemsen appendOps: ops{appendFixed32{0xf0e1d2c3}}, 322*1c12ee1eSDan Willemsen wantRaw: dhex("c3d2e1f0"), 323*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed32{wantVal: 0xf0e1d2c3, wantCnt: 4}}, 324*1c12ee1eSDan Willemsen }}) 325*1c12ee1eSDan Willemsen} 326*1c12ee1eSDan Willemsen 327*1c12ee1eSDan Willemsenfunc TestFixed64(t *testing.T) { 328*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 329*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 330*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed64{wantErr: io.ErrUnexpectedEOF}}, 331*1c12ee1eSDan Willemsen }, { 332*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("00000000000000"))}, 333*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed64{wantErr: io.ErrUnexpectedEOF}}, 334*1c12ee1eSDan Willemsen }, { 335*1c12ee1eSDan Willemsen appendOps: ops{appendFixed64{0}}, 336*1c12ee1eSDan Willemsen wantRaw: dhex("0000000000000000"), 337*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed64{wantVal: 0, wantCnt: 8}}, 338*1c12ee1eSDan Willemsen }, { 339*1c12ee1eSDan Willemsen appendOps: ops{appendFixed64{math.MaxUint64}}, 340*1c12ee1eSDan Willemsen wantRaw: dhex("ffffffffffffffff"), 341*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed64{wantVal: math.MaxUint64, wantCnt: 8}}, 342*1c12ee1eSDan Willemsen }, { 343*1c12ee1eSDan Willemsen appendOps: ops{appendFixed64{0xf0e1d2c3b4a59687}}, 344*1c12ee1eSDan Willemsen wantRaw: dhex("8796a5b4c3d2e1f0"), 345*1c12ee1eSDan Willemsen consumeOps: ops{consumeFixed64{wantVal: 0xf0e1d2c3b4a59687, wantCnt: 8}}, 346*1c12ee1eSDan Willemsen }}) 347*1c12ee1eSDan Willemsen} 348*1c12ee1eSDan Willemsen 349*1c12ee1eSDan Willemsenfunc TestBytes(t *testing.T) { 350*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 351*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 352*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantErr: io.ErrUnexpectedEOF}}, 353*1c12ee1eSDan Willemsen }, { 354*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("01"))}, 355*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantErr: io.ErrUnexpectedEOF}}, 356*1c12ee1eSDan Willemsen }, { 357*1c12ee1eSDan Willemsen appendOps: ops{appendVarint{0}, appendRaw("")}, 358*1c12ee1eSDan Willemsen wantRaw: dhex("00"), 359*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantVal: dhex(""), wantCnt: 1}}, 360*1c12ee1eSDan Willemsen }, { 361*1c12ee1eSDan Willemsen appendOps: ops{appendBytes{[]byte("hello")}}, 362*1c12ee1eSDan Willemsen wantRaw: []byte("\x05hello"), 363*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantVal: []byte("hello"), wantCnt: 6}}, 364*1c12ee1eSDan Willemsen }, { 365*1c12ee1eSDan Willemsen appendOps: ops{appendBytes{[]byte(strings.Repeat("hello", 50))}}, 366*1c12ee1eSDan Willemsen wantRaw: []byte("\xfa\x01" + strings.Repeat("hello", 50)), 367*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantVal: []byte(strings.Repeat("hello", 50)), wantCnt: 252}}, 368*1c12ee1eSDan Willemsen }, { 369*1c12ee1eSDan Willemsen appendOps: ops{appendRaw("\x85\x80\x00hello")}, 370*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantVal: []byte("hello"), wantCnt: 8}}, 371*1c12ee1eSDan Willemsen }, { 372*1c12ee1eSDan Willemsen appendOps: ops{appendRaw("\x85\x80\x00hell")}, 373*1c12ee1eSDan Willemsen consumeOps: ops{consumeBytes{wantErr: io.ErrUnexpectedEOF}}, 374*1c12ee1eSDan Willemsen }}) 375*1c12ee1eSDan Willemsen} 376*1c12ee1eSDan Willemsen 377*1c12ee1eSDan Willemsenfunc TestGroup(t *testing.T) { 378*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 379*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 380*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{wantErr: io.ErrUnexpectedEOF}}, 381*1c12ee1eSDan Willemsen }, { 382*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 0, inType: StartGroupType}}, 383*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{inNum: 1, wantErr: errFieldNumber}}, 384*1c12ee1eSDan Willemsen }, { 385*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 2, inType: EndGroupType}}, 386*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{inNum: 1, wantErr: errEndGroup}}, 387*1c12ee1eSDan Willemsen }, { 388*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 1, inType: EndGroupType}}, 389*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{inNum: 1, wantCnt: 1}}, 390*1c12ee1eSDan Willemsen }, { 391*1c12ee1eSDan Willemsen appendOps: ops{ 392*1c12ee1eSDan Willemsen appendTag{inNum: 5, inType: Fixed32Type}, 393*1c12ee1eSDan Willemsen appendFixed32{0xf0e1d2c3}, 394*1c12ee1eSDan Willemsen appendTag{inNum: 5, inType: EndGroupType}, 395*1c12ee1eSDan Willemsen }, 396*1c12ee1eSDan Willemsen wantRaw: dhex("2dc3d2e1f02c"), 397*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{inNum: 5, wantVal: dhex("2dc3d2e1f0"), wantCnt: 6}}, 398*1c12ee1eSDan Willemsen }, { 399*1c12ee1eSDan Willemsen appendOps: ops{ 400*1c12ee1eSDan Willemsen appendTag{inNum: 5, inType: Fixed32Type}, 401*1c12ee1eSDan Willemsen appendFixed32{0xf0e1d2c3}, 402*1c12ee1eSDan Willemsen appendRaw(dhex("ac808000")), 403*1c12ee1eSDan Willemsen }, 404*1c12ee1eSDan Willemsen consumeOps: ops{consumeGroup{inNum: 5, wantVal: dhex("2dc3d2e1f0"), wantCnt: 9}}, 405*1c12ee1eSDan Willemsen }}) 406*1c12ee1eSDan Willemsen} 407*1c12ee1eSDan Willemsen 408*1c12ee1eSDan Willemsenfunc TestField(t *testing.T) { 409*1c12ee1eSDan Willemsen runTests(t, []testOps{{ 410*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex(""))}, 411*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: io.ErrUnexpectedEOF}}, 412*1c12ee1eSDan Willemsen }, { 413*1c12ee1eSDan Willemsen appendOps: ops{ 414*1c12ee1eSDan Willemsen appendTag{inNum: 5000, inType: StartGroupType}, 415*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: VarintType}, 416*1c12ee1eSDan Willemsen appendVarint{123456789}, 417*1c12ee1eSDan Willemsen appendTag{inNum: 12, inType: Fixed32Type}, 418*1c12ee1eSDan Willemsen appendFixed32{123456789}, 419*1c12ee1eSDan Willemsen appendTag{inNum: 123, inType: Fixed64Type}, 420*1c12ee1eSDan Willemsen appendFixed64{123456789}, 421*1c12ee1eSDan Willemsen appendTag{inNum: 1234, inType: BytesType}, 422*1c12ee1eSDan Willemsen appendBytes{[]byte("hello")}, 423*1c12ee1eSDan Willemsen appendTag{inNum: 12345, inType: StartGroupType}, 424*1c12ee1eSDan Willemsen appendTag{inNum: 11, inType: VarintType}, 425*1c12ee1eSDan Willemsen appendVarint{123456789}, 426*1c12ee1eSDan Willemsen appendTag{inNum: 1212, inType: Fixed32Type}, 427*1c12ee1eSDan Willemsen appendFixed32{123456789}, 428*1c12ee1eSDan Willemsen appendTag{inNum: 123123, inType: Fixed64Type}, 429*1c12ee1eSDan Willemsen appendFixed64{123456789}, 430*1c12ee1eSDan Willemsen appendTag{inNum: 12341234, inType: BytesType}, 431*1c12ee1eSDan Willemsen appendBytes{[]byte("goodbye")}, 432*1c12ee1eSDan Willemsen appendTag{inNum: 12345, inType: EndGroupType}, 433*1c12ee1eSDan Willemsen appendTag{inNum: 5000, inType: EndGroupType}, 434*1c12ee1eSDan Willemsen }, 435*1c12ee1eSDan Willemsen wantRaw: dhex("c3b80208959aef3a6515cd5b07d90715cd5b0700000000924d0568656c6c6fcb830658959aef3ae54b15cd5b07998f3c15cd5b070000000092ff892f07676f6f64627965cc8306c4b802"), 436*1c12ee1eSDan Willemsen consumeOps: ops{ 437*1c12ee1eSDan Willemsen consumeTag{wantNum: 5000, wantType: StartGroupType, wantCnt: 3}, 438*1c12ee1eSDan Willemsen consumeTag{wantNum: 1, wantType: VarintType, wantCnt: 1}, 439*1c12ee1eSDan Willemsen consumeVarint{wantVal: 123456789, wantCnt: 4}, 440*1c12ee1eSDan Willemsen consumeTag{wantNum: 12, wantType: Fixed32Type, wantCnt: 1}, 441*1c12ee1eSDan Willemsen consumeFixed32{wantVal: 123456789, wantCnt: 4}, 442*1c12ee1eSDan Willemsen consumeTag{wantNum: 123, wantType: Fixed64Type, wantCnt: 2}, 443*1c12ee1eSDan Willemsen consumeFixed64{wantVal: 123456789, wantCnt: 8}, 444*1c12ee1eSDan Willemsen consumeTag{wantNum: 1234, wantType: BytesType, wantCnt: 2}, 445*1c12ee1eSDan Willemsen consumeBytes{wantVal: []byte("hello"), wantCnt: 6}, 446*1c12ee1eSDan Willemsen consumeTag{wantNum: 12345, wantType: StartGroupType, wantCnt: 3}, 447*1c12ee1eSDan Willemsen consumeTag{wantNum: 11, wantType: VarintType, wantCnt: 1}, 448*1c12ee1eSDan Willemsen consumeVarint{wantVal: 123456789, wantCnt: 4}, 449*1c12ee1eSDan Willemsen consumeTag{wantNum: 1212, wantType: Fixed32Type, wantCnt: 2}, 450*1c12ee1eSDan Willemsen consumeFixed32{wantVal: 123456789, wantCnt: 4}, 451*1c12ee1eSDan Willemsen consumeTag{wantNum: 123123, wantType: Fixed64Type, wantCnt: 3}, 452*1c12ee1eSDan Willemsen consumeFixed64{wantVal: 123456789, wantCnt: 8}, 453*1c12ee1eSDan Willemsen consumeTag{wantNum: 12341234, wantType: BytesType, wantCnt: 4}, 454*1c12ee1eSDan Willemsen consumeBytes{wantVal: []byte("goodbye"), wantCnt: 8}, 455*1c12ee1eSDan Willemsen consumeTag{wantNum: 12345, wantType: EndGroupType, wantCnt: 3}, 456*1c12ee1eSDan Willemsen consumeTag{wantNum: 5000, wantType: EndGroupType, wantCnt: 3}, 457*1c12ee1eSDan Willemsen }, 458*1c12ee1eSDan Willemsen }, { 459*1c12ee1eSDan Willemsen appendOps: ops{appendRaw(dhex("c3b80208959aef3a6515cd5b07d90715cd5b0700000000924d0568656c6c6fcb830658959aef3ae54b15cd5b07998f3c15cd5b070000000092ff892f07676f6f64627965cc8306c4b802"))}, 460*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantNum: 5000, wantType: StartGroupType, wantCnt: 74}}, 461*1c12ee1eSDan Willemsen }, { 462*1c12ee1eSDan Willemsen appendOps: ops{appendTag{inNum: 5, inType: EndGroupType}}, 463*1c12ee1eSDan Willemsen wantRaw: dhex("2c"), 464*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: errEndGroup}}, 465*1c12ee1eSDan Willemsen }, { 466*1c12ee1eSDan Willemsen appendOps: ops{ 467*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 468*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: StartGroupType}, 469*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: StartGroupType}, 470*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: StartGroupType}, 471*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: EndGroupType}, 472*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: EndGroupType}, 473*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: EndGroupType}, 474*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: EndGroupType}, 475*1c12ee1eSDan Willemsen }, 476*1c12ee1eSDan Willemsen wantRaw: dhex("0bb301eb14e39502e49502ec14b4010c"), 477*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantNum: 1, wantType: StartGroupType, wantCnt: 16}}, 478*1c12ee1eSDan Willemsen }, { 479*1c12ee1eSDan Willemsen appendOps: ops{ 480*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 481*1c12ee1eSDan Willemsen appendGroup{inNum: 1, inVal: dhex("b301eb14e39502e49502ec14b401")}, 482*1c12ee1eSDan Willemsen }, 483*1c12ee1eSDan Willemsen wantRaw: dhex("0b" + "b301eb14e39502e49502ec14b401" + "0c"), 484*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantNum: 1, wantType: StartGroupType, wantCnt: 16}}, 485*1c12ee1eSDan Willemsen }, { 486*1c12ee1eSDan Willemsen appendOps: ops{ 487*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 488*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: StartGroupType}, 489*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: StartGroupType}, 490*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: StartGroupType}, 491*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: EndGroupType}, 492*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: EndGroupType}, 493*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: EndGroupType}, 494*1c12ee1eSDan Willemsen }, 495*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: errEndGroup}}, 496*1c12ee1eSDan Willemsen }, { 497*1c12ee1eSDan Willemsen appendOps: ops{ 498*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 499*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: StartGroupType}, 500*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: StartGroupType}, 501*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: StartGroupType}, 502*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: EndGroupType}, 503*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: EndGroupType}, 504*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: EndGroupType}, 505*1c12ee1eSDan Willemsen }, 506*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: io.ErrUnexpectedEOF}}, 507*1c12ee1eSDan Willemsen }, { 508*1c12ee1eSDan Willemsen appendOps: ops{ 509*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 510*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: StartGroupType}, 511*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: StartGroupType}, 512*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: StartGroupType}, 513*1c12ee1eSDan Willemsen appendTag{inNum: 0, inType: VarintType}, 514*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: EndGroupType}, 515*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: EndGroupType}, 516*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: EndGroupType}, 517*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: EndGroupType}, 518*1c12ee1eSDan Willemsen }, 519*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: errFieldNumber}}, 520*1c12ee1eSDan Willemsen }, { 521*1c12ee1eSDan Willemsen appendOps: ops{ 522*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: StartGroupType}, 523*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: StartGroupType}, 524*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: StartGroupType}, 525*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: StartGroupType}, 526*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: 6}, 527*1c12ee1eSDan Willemsen appendTag{inNum: 4444, inType: EndGroupType}, 528*1c12ee1eSDan Willemsen appendTag{inNum: 333, inType: EndGroupType}, 529*1c12ee1eSDan Willemsen appendTag{inNum: 22, inType: EndGroupType}, 530*1c12ee1eSDan Willemsen appendTag{inNum: 1, inType: EndGroupType}, 531*1c12ee1eSDan Willemsen }, 532*1c12ee1eSDan Willemsen consumeOps: ops{consumeField{wantErr: errReserved}}, 533*1c12ee1eSDan Willemsen }}) 534*1c12ee1eSDan Willemsen} 535*1c12ee1eSDan Willemsen 536*1c12ee1eSDan Willemsenfunc runTests(t *testing.T, tests []testOps) { 537*1c12ee1eSDan Willemsen for _, tt := range tests { 538*1c12ee1eSDan Willemsen t.Run("", func(t *testing.T) { 539*1c12ee1eSDan Willemsen var b []byte 540*1c12ee1eSDan Willemsen for _, op := range tt.appendOps { 541*1c12ee1eSDan Willemsen b0 := b 542*1c12ee1eSDan Willemsen switch op := op.(type) { 543*1c12ee1eSDan Willemsen case appendTag: 544*1c12ee1eSDan Willemsen b = AppendTag(b, op.inNum, op.inType) 545*1c12ee1eSDan Willemsen case appendVarint: 546*1c12ee1eSDan Willemsen b = AppendVarint(b, op.inVal) 547*1c12ee1eSDan Willemsen case appendFixed32: 548*1c12ee1eSDan Willemsen b = AppendFixed32(b, op.inVal) 549*1c12ee1eSDan Willemsen case appendFixed64: 550*1c12ee1eSDan Willemsen b = AppendFixed64(b, op.inVal) 551*1c12ee1eSDan Willemsen case appendBytes: 552*1c12ee1eSDan Willemsen b = AppendBytes(b, op.inVal) 553*1c12ee1eSDan Willemsen case appendGroup: 554*1c12ee1eSDan Willemsen b = AppendGroup(b, op.inNum, op.inVal) 555*1c12ee1eSDan Willemsen case appendRaw: 556*1c12ee1eSDan Willemsen b = append(b, op...) 557*1c12ee1eSDan Willemsen } 558*1c12ee1eSDan Willemsen 559*1c12ee1eSDan Willemsen check := func(label string, want int) { 560*1c12ee1eSDan Willemsen t.Helper() 561*1c12ee1eSDan Willemsen if got := len(b) - len(b0); got != want { 562*1c12ee1eSDan Willemsen t.Errorf("len(Append%v) and Size%v mismatch: got %v, want %v", label, label, got, want) 563*1c12ee1eSDan Willemsen } 564*1c12ee1eSDan Willemsen } 565*1c12ee1eSDan Willemsen switch op := op.(type) { 566*1c12ee1eSDan Willemsen case appendTag: 567*1c12ee1eSDan Willemsen check("Tag", SizeTag(op.inNum)) 568*1c12ee1eSDan Willemsen case appendVarint: 569*1c12ee1eSDan Willemsen check("Varint", SizeVarint(op.inVal)) 570*1c12ee1eSDan Willemsen case appendFixed32: 571*1c12ee1eSDan Willemsen check("Fixed32", SizeFixed32()) 572*1c12ee1eSDan Willemsen case appendFixed64: 573*1c12ee1eSDan Willemsen check("Fixed64", SizeFixed64()) 574*1c12ee1eSDan Willemsen case appendBytes: 575*1c12ee1eSDan Willemsen check("Bytes", SizeBytes(len(op.inVal))) 576*1c12ee1eSDan Willemsen case appendGroup: 577*1c12ee1eSDan Willemsen check("Group", SizeGroup(op.inNum, len(op.inVal))) 578*1c12ee1eSDan Willemsen } 579*1c12ee1eSDan Willemsen } 580*1c12ee1eSDan Willemsen 581*1c12ee1eSDan Willemsen if tt.wantRaw != nil && !bytes.Equal(b, tt.wantRaw) { 582*1c12ee1eSDan Willemsen t.Errorf("raw output mismatch:\ngot %x\nwant %x", b, tt.wantRaw) 583*1c12ee1eSDan Willemsen } 584*1c12ee1eSDan Willemsen 585*1c12ee1eSDan Willemsen for _, op := range tt.consumeOps { 586*1c12ee1eSDan Willemsen check := func(label string, gotCnt, wantCnt int, wantErr error) { 587*1c12ee1eSDan Willemsen t.Helper() 588*1c12ee1eSDan Willemsen gotErr := ParseError(gotCnt) 589*1c12ee1eSDan Willemsen if gotCnt < 0 { 590*1c12ee1eSDan Willemsen gotCnt = 0 591*1c12ee1eSDan Willemsen } 592*1c12ee1eSDan Willemsen if gotCnt != wantCnt { 593*1c12ee1eSDan Willemsen t.Errorf("Consume%v(): consumed %d bytes, want %d bytes consumed", label, gotCnt, wantCnt) 594*1c12ee1eSDan Willemsen } 595*1c12ee1eSDan Willemsen if gotErr != wantErr { 596*1c12ee1eSDan Willemsen t.Errorf("Consume%v(): got %v error, want %v error", label, gotErr, wantErr) 597*1c12ee1eSDan Willemsen } 598*1c12ee1eSDan Willemsen b = b[gotCnt:] 599*1c12ee1eSDan Willemsen } 600*1c12ee1eSDan Willemsen switch op := op.(type) { 601*1c12ee1eSDan Willemsen case consumeField: 602*1c12ee1eSDan Willemsen gotNum, gotType, n := ConsumeField(b) 603*1c12ee1eSDan Willemsen if gotNum != op.wantNum || gotType != op.wantType { 604*1c12ee1eSDan Willemsen t.Errorf("ConsumeField() = (%d, %v), want (%d, %v)", gotNum, gotType, op.wantNum, op.wantType) 605*1c12ee1eSDan Willemsen } 606*1c12ee1eSDan Willemsen check("Field", n, op.wantCnt, op.wantErr) 607*1c12ee1eSDan Willemsen case consumeFieldValue: 608*1c12ee1eSDan Willemsen n := ConsumeFieldValue(op.inNum, op.inType, b) 609*1c12ee1eSDan Willemsen check("FieldValue", n, op.wantCnt, op.wantErr) 610*1c12ee1eSDan Willemsen case consumeTag: 611*1c12ee1eSDan Willemsen gotNum, gotType, n := ConsumeTag(b) 612*1c12ee1eSDan Willemsen if gotNum != op.wantNum || gotType != op.wantType { 613*1c12ee1eSDan Willemsen t.Errorf("ConsumeTag() = (%d, %v), want (%d, %v)", gotNum, gotType, op.wantNum, op.wantType) 614*1c12ee1eSDan Willemsen } 615*1c12ee1eSDan Willemsen check("Tag", n, op.wantCnt, op.wantErr) 616*1c12ee1eSDan Willemsen case consumeVarint: 617*1c12ee1eSDan Willemsen gotVal, n := ConsumeVarint(b) 618*1c12ee1eSDan Willemsen if gotVal != op.wantVal { 619*1c12ee1eSDan Willemsen t.Errorf("ConsumeVarint() = %d, want %d", gotVal, op.wantVal) 620*1c12ee1eSDan Willemsen } 621*1c12ee1eSDan Willemsen check("Varint", n, op.wantCnt, op.wantErr) 622*1c12ee1eSDan Willemsen case consumeFixed32: 623*1c12ee1eSDan Willemsen gotVal, n := ConsumeFixed32(b) 624*1c12ee1eSDan Willemsen if gotVal != op.wantVal { 625*1c12ee1eSDan Willemsen t.Errorf("ConsumeFixed32() = %d, want %d", gotVal, op.wantVal) 626*1c12ee1eSDan Willemsen } 627*1c12ee1eSDan Willemsen check("Fixed32", n, op.wantCnt, op.wantErr) 628*1c12ee1eSDan Willemsen case consumeFixed64: 629*1c12ee1eSDan Willemsen gotVal, n := ConsumeFixed64(b) 630*1c12ee1eSDan Willemsen if gotVal != op.wantVal { 631*1c12ee1eSDan Willemsen t.Errorf("ConsumeFixed64() = %d, want %d", gotVal, op.wantVal) 632*1c12ee1eSDan Willemsen } 633*1c12ee1eSDan Willemsen check("Fixed64", n, op.wantCnt, op.wantErr) 634*1c12ee1eSDan Willemsen case consumeBytes: 635*1c12ee1eSDan Willemsen gotVal, n := ConsumeBytes(b) 636*1c12ee1eSDan Willemsen if !bytes.Equal(gotVal, op.wantVal) { 637*1c12ee1eSDan Willemsen t.Errorf("ConsumeBytes() = %x, want %x", gotVal, op.wantVal) 638*1c12ee1eSDan Willemsen } 639*1c12ee1eSDan Willemsen check("Bytes", n, op.wantCnt, op.wantErr) 640*1c12ee1eSDan Willemsen case consumeGroup: 641*1c12ee1eSDan Willemsen gotVal, n := ConsumeGroup(op.inNum, b) 642*1c12ee1eSDan Willemsen if !bytes.Equal(gotVal, op.wantVal) { 643*1c12ee1eSDan Willemsen t.Errorf("ConsumeGroup() = %x, want %x", gotVal, op.wantVal) 644*1c12ee1eSDan Willemsen } 645*1c12ee1eSDan Willemsen check("Group", n, op.wantCnt, op.wantErr) 646*1c12ee1eSDan Willemsen } 647*1c12ee1eSDan Willemsen } 648*1c12ee1eSDan Willemsen }) 649*1c12ee1eSDan Willemsen } 650*1c12ee1eSDan Willemsen} 651*1c12ee1eSDan Willemsen 652*1c12ee1eSDan Willemsenfunc TestZigZag(t *testing.T) { 653*1c12ee1eSDan Willemsen tests := []struct { 654*1c12ee1eSDan Willemsen dec int64 655*1c12ee1eSDan Willemsen enc uint64 656*1c12ee1eSDan Willemsen }{ 657*1c12ee1eSDan Willemsen {math.MinInt64 + 0, math.MaxUint64 - 0}, 658*1c12ee1eSDan Willemsen {math.MinInt64 + 1, math.MaxUint64 - 2}, 659*1c12ee1eSDan Willemsen {math.MinInt64 + 2, math.MaxUint64 - 4}, 660*1c12ee1eSDan Willemsen {-3, 5}, 661*1c12ee1eSDan Willemsen {-2, 3}, 662*1c12ee1eSDan Willemsen {-1, 1}, 663*1c12ee1eSDan Willemsen {0, 0}, 664*1c12ee1eSDan Willemsen {+1, 2}, 665*1c12ee1eSDan Willemsen {+2, 4}, 666*1c12ee1eSDan Willemsen {+3, 6}, 667*1c12ee1eSDan Willemsen {math.MaxInt64 - 2, math.MaxUint64 - 5}, 668*1c12ee1eSDan Willemsen {math.MaxInt64 - 1, math.MaxUint64 - 3}, 669*1c12ee1eSDan Willemsen {math.MaxInt64 - 0, math.MaxUint64 - 1}, 670*1c12ee1eSDan Willemsen } 671*1c12ee1eSDan Willemsen 672*1c12ee1eSDan Willemsen for _, tt := range tests { 673*1c12ee1eSDan Willemsen if enc := EncodeZigZag(tt.dec); enc != tt.enc { 674*1c12ee1eSDan Willemsen t.Errorf("EncodeZigZag(%d) = %d, want %d", tt.dec, enc, tt.enc) 675*1c12ee1eSDan Willemsen } 676*1c12ee1eSDan Willemsen if dec := DecodeZigZag(tt.enc); dec != tt.dec { 677*1c12ee1eSDan Willemsen t.Errorf("DecodeZigZag(%d) = %d, want %d", tt.enc, dec, tt.dec) 678*1c12ee1eSDan Willemsen } 679*1c12ee1eSDan Willemsen } 680*1c12ee1eSDan Willemsen} 681