this byte ordering what the fuck

master
Jordan Orelli 8 years ago
parent 3b8ff04f04
commit bce9de8d19

@ -40,11 +40,11 @@ func (r *Reader) ReadBits(bits uint) (n uint64) {
r.err = err
return 0
}
r.n <<= 8
r.n |= uint64(b)
r.n |= uint64(b) << r.bits
r.bits += 8
}
n = (r.n >> (r.bits - bits)) & ((1 << bits) - 1)
n = r.n & (1<<bits - 1)
r.n >>= bits
r.bits -= bits
return
}
@ -77,20 +77,20 @@ func (r *Reader) Read(buf []byte) (int, error) {
// by the 4 least-significant bits, then a variable number of most-significant
// bits based on the prefix.
//
// 00 - 0
// 01 - 4
// 10 - 8
// 11 - 28
// 00 - 4
// 01 - 8
// 10 - 12 (why 12? this really baffles me)
// 11 - 32
func (r *Reader) ReadUBitVar() uint64 {
switch prefix := r.ReadBits(2); prefix {
switch b := r.ReadBits(6); b >> 4 {
case 0:
return r.ReadBits(4)
return b & 0xf
case 1:
return r.ReadBits(4) | r.ReadBits(4)<<4
return b&0xf | r.ReadBits(4)<<4
case 2:
return r.ReadBits(4) | r.ReadBits(8)<<4
return b&0xf | r.ReadBits(8)<<4
case 3:
return r.ReadBits(4) | r.ReadBits(28)<<4
return b&0xf | r.ReadBits(28)<<4
default:
panic("not reached")
}

@ -10,8 +10,8 @@ var (
// 1000 1011 1010 1101 1111 0000 0000 1101
badFood = []byte{0x8b, 0xad, 0xf0, 0x0d}
// 0000 1110 0001 1110 1110 0111 1011 1110 1110 1111
eLeetBeef = []byte{0x0e, 0x1e, 0xe7, 0xbe, 0xef}
// 1110 1100 0111 0000 1100 0000 0000 0001 1110 0010
ectoCooler = []byte{0xec, 0x70, 0xc0, 0x01, 0xe2}
)
// test the bit-level reads
@ -32,28 +32,30 @@ func TestReadBits(t *testing.T) {
r = NewBytesReader(badFood)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^
// ^
assert.Equal(uint64(0x01), r.ReadBits(1))
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^-^
assert.Equal(uint64(0), r.ReadBits(3))
// ^-^
assert.Equal(uint64(0x5), r.ReadBits(3))
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^--^
assert.Equal(uint64(0xb), r.ReadBits(4))
// ^--^
assert.Equal(uint64(0x8), r.ReadBits(4))
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^----^
assert.Equal(uint64(0x15), r.ReadBits(5))
// ^----^
assert.Equal(uint64(0xd), r.ReadBits(5))
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^----+----^
assert.Equal(uint64(0x17c), r.ReadBits(9))
// ^-^.........^-----^
// data bits: 1 1000 0101
assert.Equal(uint64(0x185), r.ReadBits(9))
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^----+----+^
assert.Equal(uint64(0xd), r.ReadBits(10))
// ^^........^-------^
// data bits: 00 0011 0111
assert.Equal(uint64(0x37), r.ReadBits(10))
}
// test the Read calls, satisfying io.Reader
@ -74,16 +76,18 @@ func TestRead(t *testing.T) {
assert.Equal(badFood, buf)
r = NewBytesReader(badFood)
// 1000 1011 1010 1101 1111 0000 0000 1101
r.ReadBits(1)
// 0001 0111 0101 1011 1110 0000 0001 101
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^------^..........^ : 1100 0101
// ^------^..........^ : 0101 0110
// ^------^..........^ : 1111 1000
buf = make([]byte, 3)
n, err = r.Read(buf)
assert.NoError(err)
assert.Equal(3, n)
expected := []byte{0x17, 0x5b, 0xe0}
expected := []byte{0xc5, 0x56, 0xf8}
assert.Equal(expected, buf)
}
@ -95,38 +99,61 @@ func TestUbitVar(t *testing.T) {
)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ||^---^ : data (0101)
// ^^ : prefix (00)
r = NewBytesReader(badFood)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^
r.ReadBits(1)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^^ : prefix 00
// ^---^ : data 0101
u = r.ReadUBitVar()
assert.Equal(uint64(5), u)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^.................^
r.ReadBits(2)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ||| | ^--^ : msb (1111)
// ||^---^ : lsb (0110)
// ^^ : prefix (01)
// ^^ : prefix 01
// ^...............^-^ : msb 0001
// ^---^ : lsb 0110
u = r.ReadUBitVar()
assert.Equal(uint64(0xf6), u)
assert.Equal(uint64(0x16), u)
// 1000 1011 1010 1101 1111 0000 0000 1101
r = NewBytesReader(badFood)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ||| |^----+---^ : msb (1110 1011)
// ||^---^ : lsb (0010)
// ^^ : prefix (10)
// ^^
r.ReadBits(2)
// 1000 1011 1010 1101 1111 0000 0000 1101
// ^^ : prefix 10
// ^-------^ : msb 1010 1101
// ^---^ : lsb 0010
u = r.ReadUBitVar()
assert.Equal(uint64(0xeb2), u)
r = NewBytesReader(eLeetBeef)
r.ReadBits(4)
// 0000 1110 0001 1110 1110 0111 1011 1110 1110 1111
// ||| |^----+----+----+----+----+----+---^ : msb (0111 1011 1001 1110
// ||| | 1111 1011 1011)
// ||^---^ : lsb (1000)
// ^^ : prefix (11)
assert.Equal(uint64(0xad2), u)
// 1110 1100 0111 0000 1100 0000 0000 0001 1110 0010
r = NewBytesReader(ectoCooler)
// 1110 1100 0111 0000 1100 0000 0000 0001 1110 0010
// ^^
r.ReadBits(2)
// 1110 1100 0111 0000 1100 0000 0000 0001 1110 0010
// ^^ : prefix 11
// ^--^ : msb 0010
// ^-------^ : 0000 0001
// ^-------^ : 1110 0000
// ^-------^ : 0111 0000
// ^---^ : lsb 1011
// data bits:
// 0010 0000 0001 1110 0000 0111 0000 1011
u = r.ReadUBitVar()
assert.Equal(uint64(0x7b9efbb8), u)
assert.Equal(uint64(0x201c070b), u)
}
func TestVarInt(t *testing.T) {
@ -139,7 +166,7 @@ func TestVarInt(t *testing.T) {
r = NewBytesReader(badFood)
r.ReadBits(24)
// 1000 1011 1010 1101 1111 0000 0000 1101
// |^------^ : data
// ^------^ : data
// ^ : stop
u = r.ReadVarInt()
assert.Equal(uint64(0xd), u)
@ -147,9 +174,9 @@ func TestVarInt(t *testing.T) {
r = NewBytesReader(badFood)
r.ReadBits(16)
// 1000 1011 1010 1101 1111 0000 0000 1101
// || | |^------^ : msb
// || | ^ : stop
// |^------^ : lsb
// ^------^ : msb
// ^ : stop
// ^------^ : lsb
// ^ : continue
// data bits:
// 0000 0110 1111 0000
@ -159,13 +186,13 @@ func TestVarInt(t *testing.T) {
r = NewBytesReader(badFood)
// 1000 1011 1010 1101 1111 0000 0000 1101
// || | || | || | |^------^ : msb (000 1101)
// || | || | || | ^ : stop
// || | || | |^------^ : data (111 0000)
// || | || | ^ : continue
// || | |^------^ : data (010 1101)
// || | ^ : continue
// |^------^ : lsb (000 1011)
// ^------^ : msb 000 1101
// ^ : stop
// ^------^ : data 111 0000
// ^ : continue
// ^------^ : data 010 1101
// ^ : continue
// ^------^ : lsb 000 1011
// ^ : continue
// data bits:
// 0001 1011 1100 0001 0110 1000 1011

6
glide.lock generated

@ -1,5 +1,5 @@
hash: 3f7fbcf64c0749e5f78dc8188c594871ab368257d8a05f238cb2ff901d76f8f8
updated: 2016-08-01T20:29:43.617478897-04:00
hash: c605c7633cdbedcf0368949ea8ca09a624ed544c8f66d64b516c2cec557c1de6
updated: 2016-08-02T09:04:53.517211263-04:00
imports:
- name: github.com/golang/protobuf
version: c3cefd437628a0b7d31b34fe44b3a7a540e98527
@ -9,7 +9,7 @@ imports:
- name: github.com/golang/snappy
version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
- name: github.com/stretchr/testify
version: f390dcf405f7b83c997eac1b06768bb9f44dec18
version: d77da356e56a7428ad25149ca77381849a6a5232
subpackages:
- assert
testImports:

@ -3,4 +3,3 @@ import:
- package: github.com/golang/protobuf
- package: github.com/golang/snappy
- package: github.com/stretchr/testify
version: ^1.1.3

@ -5,6 +5,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/golang/snappy"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
@ -22,6 +23,19 @@ func (m message) String() string {
return fmt.Sprintf("{cmd: %v tick: %v compressed: %t size: %d body: %q}", m.cmd, m.tick, m.compressed, len(m.body), m.body)
}
type entity struct {
t uint32
size uint32
body []byte
}
func (e entity) String() string {
if len(e.body) < 32 {
return fmt.Sprintf("{%v %v %x}", e.t, e.size, e.body)
}
return fmt.Sprintf("{%v %v %x...}", e.t, e.size, e.body[:32])
}
func (m *message) check(dump bool) error {
if m.cmd != dota.EDemoCommands_DEM_Packet {
return fmt.Errorf("wrong command type in openPacket: %v", m.cmd)
@ -42,7 +56,18 @@ func (m *message) check(dump bool) error {
}
if dump {
fmt.Println("I broke packet dumping.")
br := bit.NewBytesReader(packet.GetData())
for {
t := br.ReadUBitVar()
s := br.ReadVarInt()
b := make([]byte, s)
br.Read(b)
if br.Err() != nil {
break
}
e := entity{t: uint32(t), size: uint32(s), body: b}
fmt.Printf("\t%v\n", e)
}
}
return nil
}

Loading…
Cancel
Save