X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=codec%2Fcodec.go;h=21354a1d998c0a7048aabab8c0212cc43fe75b05;hb=5de7f6b85458615fa592a335d45c546397f32c9a;hp=e968a6bd2a8bd525815841147bad254f97efb16f;hpb=ceed73403bdb61387d04be8b47183e9c4a970749;p=govpp.git diff --git a/codec/codec.go b/codec/codec.go index e968a6b..21354a1 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -15,23 +15,43 @@ package codec import ( + "bytes" "encoding/binary" "math" - "reflect" - "unsafe" ) -var order = binary.BigEndian - +// Buffer provides buffer for encoding and decoding data on wire. type Buffer struct { - pos int buf []byte + pos int +} + +// NewBuffer creates new buffer using b as data. +func NewBuffer(b []byte) *Buffer { + return &Buffer{ + buf: b, + } } +// Bytes returns buffer data up to current position. func (b *Buffer) Bytes() []byte { return b.buf[:b.pos] } +func (b *Buffer) EncodeBytes(v []byte, length int) { + if length == 0 { + length = len(v) + } + copy(b.buf[b.pos:b.pos+length], v) + b.pos += length +} + +func (b *Buffer) DecodeBytes(length int) []byte { + v := b.buf[b.pos : b.pos+length] + b.pos += length + return v +} + func (b *Buffer) EncodeBool(v bool) { if v { b.buf[b.pos] = 1 @@ -41,38 +61,131 @@ func (b *Buffer) EncodeBool(v bool) { b.pos += 1 } +func (b *Buffer) DecodeBool() bool { + v := b.buf[b.pos] != 0 + b.pos += 1 + return v +} + func (b *Buffer) EncodeUint8(v uint8) { - b.buf[b.pos] = v + b.buf[b.pos] = byte(v) + b.pos += 1 +} + +func (b *Buffer) DecodeUint8() uint8 { + v := uint8(b.buf[b.pos]) b.pos += 1 + return v } func (b *Buffer) EncodeUint16(v uint16) { - order.PutUint16(b.buf[b.pos:b.pos+2], v) + binary.BigEndian.PutUint16(b.buf[b.pos:b.pos+2], v) + b.pos += 2 +} + +func (b *Buffer) DecodeUint16() uint16 { + v := binary.BigEndian.Uint16(b.buf[b.pos : b.pos+2]) b.pos += 2 + return v } func (b *Buffer) EncodeUint32(v uint32) { - order.PutUint32(b.buf[b.pos:b.pos+4], v) + binary.BigEndian.PutUint32(b.buf[b.pos:b.pos+4], v) b.pos += 4 } +func (b *Buffer) DecodeUint32() uint32 { + v := binary.BigEndian.Uint32(b.buf[b.pos : b.pos+4]) + b.pos += 4 + return v +} + func (b *Buffer) EncodeUint64(v uint64) { - order.PutUint64(b.buf[b.pos:b.pos+8], v) + binary.BigEndian.PutUint64(b.buf[b.pos:b.pos+8], v) + b.pos += 8 +} + +func (b *Buffer) DecodeUint64() uint64 { + v := binary.BigEndian.Uint64(b.buf[b.pos : b.pos+8]) + b.pos += 8 + return v +} + +func (b *Buffer) EncodeInt8(v int8) { + b.buf[b.pos] = byte(v) + b.pos += 1 +} + +func (b *Buffer) DecodeInt8() int8 { + v := int8(b.buf[b.pos]) + b.pos += 1 + return v +} + +func (b *Buffer) EncodeInt16(v int16) { + binary.BigEndian.PutUint16(b.buf[b.pos:b.pos+2], uint16(v)) + b.pos += 2 +} + +func (b *Buffer) DecodeInt16() int16 { + v := int16(binary.BigEndian.Uint16(b.buf[b.pos : b.pos+2])) + b.pos += 2 + return v +} + +func (b *Buffer) EncodeInt32(v int32) { + binary.BigEndian.PutUint32(b.buf[b.pos:b.pos+4], uint32(v)) + b.pos += 4 +} + +func (b *Buffer) DecodeInt32() int32 { + v := int32(binary.BigEndian.Uint32(b.buf[b.pos : b.pos+4])) + b.pos += 4 + return v +} + +func (b *Buffer) EncodeInt64(v int64) { + binary.BigEndian.PutUint64(b.buf[b.pos:b.pos+8], uint64(v)) + b.pos += 8 +} + +func (b *Buffer) DecodeInt64() int64 { + v := int64(binary.BigEndian.Uint64(b.buf[b.pos : b.pos+8])) b.pos += 8 + return v } func (b *Buffer) EncodeFloat64(v float64) { - order.PutUint64(b.buf[b.pos:b.pos+8], math.Float64bits(v)) + binary.LittleEndian.PutUint64(b.buf[b.pos:b.pos+8], math.Float64bits(v)) b.pos += 8 } +func (b *Buffer) DecodeFloat64() float64 { + v := math.Float64frombits(binary.LittleEndian.Uint64(b.buf[b.pos : b.pos+8])) + b.pos += 8 + return v +} + func (b *Buffer) EncodeString(v string, length int) { + if length == 0 { + b.EncodeUint32(uint32(len(v))) + length = len(v) + } copy(b.buf[b.pos:b.pos+length], v) b.pos += length } -func DecodeString(b []byte) string { - sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - stringHeader := reflect.StringHeader{Data: sliceHeader.Data, Len: sliceHeader.Len} - return *(*string)(unsafe.Pointer(&stringHeader)) +func (b *Buffer) DecodeString(length int) string { + var v []byte + if length == 0 { + length = int(b.DecodeUint32()) + v = b.buf[b.pos : b.pos+length] + } else { + v = b.buf[b.pos : b.pos+length] + if nul := bytes.Index(v, []byte{0x00}); nul >= 0 { + v = v[:nul] + } + } + b.pos += length + return string(v) }