func BenchmarkDecode(b *testing.B) { for i := 0; i < b.N; i++ { Decode(swrap.New([]byte{10}), 5) Decode(swrap.New([]byte{31, 9}), 5) Decode(swrap.New([]byte{31, 154, 10}), 5) Decode(swrap.New([]byte{31, 161, 141, 183, 1}), 5) } }
// Encode Integer to N bit prefix // Integer Representation // // [Logic] // if I < 2^N - 1, encode I on N bits // else // encode (2^N - 1) on N bits // I = I - (2^N - 1) // while I >= 128 // encode (I % 128 + 128) on 8 bits // I = I / 128 // encode I on 8 bits func Encode(I uint32, N uint8) swrap.SWrap { buf := swrap.New(make([]byte, 0)) if N == 0 { buf.Add(byte(I)) return buf } boundary := uint32(1<<N - 1) // 2^N-1 if I < boundary { // If I < 2^N - 1, encode I on N bits buf.Add(byte(I)) } else { // encode 2^N - 1 on N bits buf.Add(byte(boundary)) // I = I - (2^N - 1) I = I - boundary // While I >= 128 for I >= 128 { // Encode (I % 128 + 128) on 8 bits buf.Add(byte(I%128 + 128)) // I = I / 128 I = I / 128 } // encode (I) on 8 bits buf.Add(byte(I)) } return buf }
func TestDecode(t *testing.T) { testcases := []struct { expected, actual uint32 }{ {Decode(swrap.New([]byte{10}), 5), 10}, {Decode(swrap.New([]byte{31, 9}), 5), 40}, {Decode(swrap.New([]byte{31, 154, 10}), 5), 1337}, {Decode(swrap.New([]byte{31, 161, 141, 183, 1}), 5), 3000000}, } for _, testcase := range testcases { actual := testcase.actual expected := testcase.expected assert.Equal(t, actual, expected) } }
func TestStringLiteralDecode(t *testing.T) { // D.2.1. Literal Header Field with Indexing var indexing Indexing = WITH var name, value string = "custom-key", "custom-header" buf := []byte{ 0x40, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x2d, 0x6b, 0x65, 0x79, 0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, } sw := swrap.New(buf) decoded := DecodeHeader(&sw) frame, ok := decoded.(*StringLiteral) assert.Equal(t, ok, true) expected := NewStringLiteral(indexing, name, value) assert.Equal(t, frame, expected) }
func TestReadPrefixedInteger(t *testing.T) { // 0x1F 0001 1111 // 0x95 1001 0101 // 0x0A 0000 1010 // 0x06 0000 0110 var prefix uint8 = 5 buf := swrap.New([]byte{0x1F, 0x95, 0x0A, 0x06}) expected := []byte{0x1F, 0x95, 0xA} actual := ReadPrefixedInteger(&buf, prefix) assert.Equal(t, actual.Bytes(), expected) }
func TestIndexedHeaderDecode(t *testing.T) { // D.2.4. Indexed Header Field var index uint32 = 2 buf := []byte{0x82} sw := swrap.New(buf) decoded := DecodeHeader(&sw) frame, ok := decoded.(*IndexedHeader) assert.Equal(t, ok, true) assert.Equal(t, frame.Index, index) }
func TestIndexedLiteralDecode(t *testing.T) { // D.2.2. Literal Header Field without Indexing var indexing Indexing = WITHOUT var index uint32 = 4 var value string = "/sample/path" buf := []byte{ 0x04, 0x0c, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x70, 0x61, 0x74, 0x68, } // table size: empty sw := swrap.New(buf) decoded := DecodeHeader(&sw) frame, ok := decoded.(*IndexedLiteral) assert.Equal(t, ok, true) expected := NewIndexedLiteral(indexing, index, value) assert.Equal(t, frame, expected) }
// read prefixed N bytes from buffer // if N bit of first byte is 2^N-1 (ex 1111 in N=4) // read follow byte until it's smaller than 128 func ReadPrefixedInteger(buf *swrap.SWrap, N uint8) swrap.SWrap { boundary := byte(1<<N - 1) // 2^N-1 first := buf.Shift() first = first & boundary // mask N bit prefix := swrap.New([]byte{first}) // if first byte is smaller than boundary // it's end of the prefixed bytes if first < boundary { return prefix } // read bytes while bytes smaller than 128 for { tmp := buf.Shift() prefix.Add(tmp) if tmp < 128 { break } } return prefix }