blob: 24a912845ec9cc98b8e32dc34d37a7fa18ab14c2 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package fury
import (
"encoding/binary"
"fmt"
"io"
)
type ByteBuffer struct {
io.Writer
io.Reader
writerIndex int
readerIndex int
data []byte
}
func NewByteBuffer(data []byte) *ByteBuffer {
return &ByteBuffer{data: data}
}
func (b *ByteBuffer) grow(n int) {
l := b.writerIndex
if l+n < len(b.data) {
return
}
if l+n < cap(b.data) {
b.data = b.data[:cap(b.data)]
} else {
newBuf := make([]byte, 2*(l+n), 2*(l+n))
copy(newBuf, b.data)
b.data = newBuf
}
}
func (b *ByteBuffer) WriteBool(value bool) {
b.grow(1)
if value {
b.data[b.writerIndex] = 1
} else {
b.data[b.writerIndex] = 0
}
b.writerIndex++
}
func (b *ByteBuffer) WriteByte(value byte) error {
b.grow(1)
b.data[b.writerIndex] = value
b.writerIndex++
return nil
}
func (b *ByteBuffer) WriteByte_(value byte) {
b.grow(1)
b.data[b.writerIndex] = value
b.writerIndex++
}
func (b *ByteBuffer) WriteInt8(value int8) {
b.grow(1)
b.data[b.writerIndex] = byte(value)
b.writerIndex++
}
func (b *ByteBuffer) WriteInt16(value int16) {
b.grow(2)
binary.LittleEndian.PutUint16(b.data[b.writerIndex:], uint16(value))
b.writerIndex += 2
}
func (b *ByteBuffer) WriteInt32(value int32) {
b.grow(4)
binary.LittleEndian.PutUint32(b.data[b.writerIndex:], uint32(value))
b.writerIndex += 4
}
func (b *ByteBuffer) WriteLength(value int) {
b.grow(4)
if value >= MaxInt32 {
panic(fmt.Errorf("too long: %d", value))
}
b.WriteVarInt32(int32(value))
}
func (b *ByteBuffer) ReadLength() int {
return int(b.ReadVarInt32())
}
func (b *ByteBuffer) WriteInt64(value int64) {
b.grow(8)
binary.LittleEndian.PutUint64(b.data[b.writerIndex:], uint64(value))
b.writerIndex += 8
}
func (b *ByteBuffer) WriteFloat32(value float32) {
b.grow(4)
binary.LittleEndian.PutUint32(b.data[b.writerIndex:], Float32bits(value))
b.writerIndex += 4
}
func (b *ByteBuffer) WriteFloat64(value float64) {
b.grow(8)
binary.LittleEndian.PutUint64(b.data[b.writerIndex:], Float64bits(value))
b.writerIndex += 8
}
func (b *ByteBuffer) Write(p []byte) (n int, err error) {
b.grow(len(p))
l := copy(b.data[b.writerIndex:], p)
b.writerIndex += len(p)
return l, nil
}
func (b *ByteBuffer) WriteBinary(p []byte) {
b.grow(len(p))
l := copy(b.data[b.writerIndex:], p)
if l != len(p) {
panic(fmt.Errorf("should write %d bytes, but written %d bytes", len(p), l))
}
b.writerIndex += len(p)
}
func (b *ByteBuffer) ReadBool() bool {
v := b.data[b.readerIndex]
b.readerIndex++
if v == 0 {
return false
} else {
return true
}
}
func (b *ByteBuffer) ReadByte_() byte {
v := b.data[b.readerIndex]
b.readerIndex++
return v
}
func (b *ByteBuffer) ReadByte() (byte, error) {
v := b.data[b.readerIndex]
b.readerIndex++
return v, nil
}
func (b *ByteBuffer) ReadInt8() int8 {
i := int8(b.data[b.readerIndex])
b.readerIndex += 1
return i
}
func (b *ByteBuffer) ReadInt16() int16 {
i := int16(binary.LittleEndian.Uint16(b.data[b.readerIndex:]))
b.readerIndex += 2
return i
}
func (b *ByteBuffer) ReadUint32() uint32 {
i := binary.LittleEndian.Uint32(b.data[b.readerIndex:])
b.readerIndex += 4
return i
}
func (b *ByteBuffer) ReadUint64() uint64 {
i := binary.LittleEndian.Uint64(b.data[b.readerIndex:])
b.readerIndex += 8
return i
}
func (b *ByteBuffer) ReadInt32() int32 {
return int32(b.ReadUint32())
}
func (b *ByteBuffer) ReadInt64() int64 {
return int64(b.ReadUint64())
}
func (b *ByteBuffer) ReadFloat32() float32 {
return Float32frombits(b.ReadUint32())
}
func (b *ByteBuffer) ReadFloat64() float64 {
return Float64frombits(b.ReadUint64())
}
func (b *ByteBuffer) Read(p []byte) (n int, err error) {
copied := copy(p, b.data[b.readerIndex:])
b.readerIndex += copied
return copied, nil
}
func (b *ByteBuffer) ReadBinary(length int) []byte {
v := b.data[b.readerIndex : b.readerIndex+length]
b.readerIndex += length
return v
}
func (b *ByteBuffer) GetData() []byte {
return b.data
}
func (b *ByteBuffer) GetByteSlice(start, end int) []byte {
return b.data[start:end]
}
func (b *ByteBuffer) Slice(start, length int) *ByteBuffer {
return NewByteBuffer(b.data[start : start+length])
}
func (b *ByteBuffer) WriterIndex() int {
return b.writerIndex
}
func (b *ByteBuffer) SetWriterIndex(index int) {
b.writerIndex = index
}
func (b *ByteBuffer) ReaderIndex() int {
return b.readerIndex
}
func (b *ByteBuffer) SetReaderIndex(index int) {
b.readerIndex = index
}
func (b *ByteBuffer) Reset() {
b.readerIndex = 0
b.writerIndex = 0
b.data = nil
}
func (b *ByteBuffer) PutInt32(index int, value int32) {
b.grow(4)
binary.LittleEndian.PutUint32(b.data[index:], uint32(value))
}
// WriteVarInt32 WriteVarUint writes a 1-5 byte int, returns the number of bytes written.
func (b *ByteBuffer) WriteVarInt32(value int32) int8 {
if value>>7 == 0 {
b.grow(1)
b.data[b.writerIndex] = byte(value)
b.writerIndex++
return 1
}
if value>>14 == 0 {
b.grow(2)
b.data[b.writerIndex] = byte((value & 0x7F) | 0x80)
b.data[b.writerIndex+1] = byte(value >> 7)
b.writerIndex += 2
return 2
}
if value>>21 == 0 {
b.grow(3)
b.data[b.writerIndex] = byte((value & 0x7F) | 0x80)
b.data[b.writerIndex+1] = byte(value>>7 | 0x80)
b.data[b.writerIndex+2] = byte(value >> 14)
b.writerIndex += 3
return 3
}
if value>>28 == 0 {
b.grow(4)
b.data[b.writerIndex] = byte((value & 0x7F) | 0x80)
b.data[b.writerIndex+1] = byte(value>>7 | 0x80)
b.data[b.writerIndex+2] = byte(value>>14 | 0x80)
b.data[b.writerIndex+3] = byte(value >> 21)
b.writerIndex += 4
return 4
}
b.grow(5)
b.data[b.writerIndex] = byte((value & 0x7F) | 0x80)
b.data[b.writerIndex+1] = byte(value>>7 | 0x80)
b.data[b.writerIndex+2] = byte(value>>14 | 0x80)
b.data[b.writerIndex+3] = byte(value>>21 | 0x80)
b.data[b.writerIndex+4] = byte(value >> 28)
b.writerIndex += 5
return 5
}
// ReadVarInt32 reads the 1-5 byte int part of a varint.
func (b *ByteBuffer) ReadVarInt32() int32 {
readerIndex := b.readerIndex
byte_ := int32(b.data[readerIndex])
readerIndex++
result := byte_ & 0x7F
if (byte_ & 0x80) != 0 {
byte_ = int32(b.data[readerIndex])
readerIndex++
result |= (byte_ & 0x7F) << 7
if (byte_ & 0x80) != 0 {
byte_ = int32(b.data[readerIndex])
readerIndex++
result |= (byte_ & 0x7F) << 14
if (byte_ & 0x80) != 0 {
byte_ = int32(b.data[readerIndex])
readerIndex++
result |= (byte_ & 0x7F) << 21
if (byte_ & 0x80) != 0 {
byte_ = int32(b.data[readerIndex])
readerIndex++
result |= (byte_ & 0x7F) << 28
}
}
}
}
b.readerIndex = readerIndex
return result
}
type BufferObject interface {
TotalBytes() int
WriteTo(buf *ByteBuffer)
ToBuffer() *ByteBuffer
}