Skip to content

Commit

Permalink
Merge pull request #322 from mattetti/ma-variable-length-quantity
Browse files Browse the repository at this point in the history
new exercise to encode/decode variable length quantity
  • Loading branch information
Katrina Owen authored Oct 2, 2016
2 parents d4aa042 + 3464be9 commit ae98780
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
"word-search",
"connect",
"ledger",
"poker"
"poker",
"variable-length-quantity"
],
"deprecated": [
"accumulate",
Expand Down
56 changes: 56 additions & 0 deletions exercises/variable-length-quantity/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package variablelengthquantity

// EncodeVarint returns the varint encoding of x.
func EncodeVarint(x uint32) []byte {
if x>>7 == 0 {
return []byte{
byte(x),
}
}

if x>>14 == 0 {
return []byte{
byte(0x80 | x>>7),
byte(127 & x),
}
}

if x>>21 == 0 {
return []byte{
byte(0x80 | x>>14),
byte(0x80 | x>>7),
byte(127 & x),
}
}

return []byte{
byte(0x80 | x>>21),
byte(0x80 | x>>14),
byte(0x80 | x>>7),
byte(127 & x),
}
}

// DecodeVarint reads a varint-encoded integer from the slice.
// It returns the integer and the number of bytes consumed, or
// zero if there is not enough.
func DecodeVarint(buf []byte) (x uint32, n int) {
if len(buf) < 1 {
return 0, 0
}

if buf[0] <= 0x80 {
return uint32(buf[0]), 1
}

var b byte
for n, b = range buf {
x = x << 7
x |= uint32(b) & 0x7F
if (b & 0x80) == 0 {
return x, n
}
}

return x, n
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package variablelengthquantity

import (
"bytes"
"testing"
)

func TestEncodeDecodeVarint(t *testing.T) {
testCases := []struct {
input []byte
output uint32
}{
0: {[]byte{0x7F}, 127},
1: {[]byte{0x81, 0x00}, 128},
2: {[]byte{0xC0, 0x00}, 8192},
3: {[]byte{0xFF, 0x7F}, 16383},
4: {[]byte{0x81, 0x80, 0x00}, 16384},
5: {[]byte{0xFF, 0xFF, 0x7F}, 2097151},
6: {[]byte{0x81, 0x80, 0x80, 0x00}, 2097152},
7: {[]byte{0xC0, 0x80, 0x80, 0x00}, 134217728},
8: {[]byte{0xFF, 0xFF, 0xFF, 0x7F}, 268435455},

9: {[]byte{0x82, 0x00}, 256},
10: {[]byte{0x81, 0x10}, 144},
}

for i, tc := range testCases {
t.Logf("test case %d - %#v\n", i, tc.input)
if o, _ := DecodeVarint(tc.input); o != tc.output {
t.Fatalf("expected %d\ngot\n%d\n", tc.output, o)
}
if encoded := EncodeVarint(tc.output); bytes.Compare(encoded, tc.input) != 0 {
t.Fatalf("%d - expected %#v\ngot\n%#v\n", tc.output, tc.input, encoded)
}
}
}

0 comments on commit ae98780

Please sign in to comment.