blob: 6efdd9c9fd1c84d1a58c9854ebc384b80d77b9f1 [file]
/*
* 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 etch
import "encoding/binary"
import "os"
import "sync"
//import "fmt"
type FlexBuffer struct {
buf []byte
Index int
Length int
mutex *sync.Mutex
}
func NewFlexBuffer() *FlexBuffer {
return &FlexBuffer{make([]byte, 32), 0, 0, new(sync.Mutex)}
}
func (fb *FlexBuffer) Write(p []byte) (n int, err os.Error) {
fb.mutex.Lock()
// Log("Flexbuffer: BeginWrite: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " length " + fmt.Sprint(fb.Length) + " index " + fmt.Sprint(fb.Index) + " datalen " + fmt.Sprint(len(p)) + "\n")
fb.ensureLength(fb.Index + len(p))
// Log("Flexbuffer: MiddleWrite: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " length " + fmt.Sprint(fb.Length) + " index " + fmt.Sprint(fb.Index) + " datalen " + fmt.Sprint(len(p)) + "\n")
copy(fb.buf[fb.Index:fb.Index + len(p)],p)
fb.Index = fb.Index + len(p)
fb.fixLength()
// Log("Flexbuffer: EndWrite: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " length " + fmt.Sprint(fb.Length) + " index " + fmt.Sprint(fb.Index) + " datalen " + fmt.Sprint(len(p)) + "\n")
// Log("Flexbuffer: EndWrite: " + fmt.Sprint(fb.avail()) + "\n")
fb.mutex.Unlock()
return len(p), nil
}
func (fb *FlexBuffer) ensureLength(newLength int) {
if newLength < len(fb.buf) {
return
}
fb.enlargeBuffer(newLength)
}
func (fb *FlexBuffer) enlargeBuffer(desired int) {
l := len(fb.buf)
for l < desired {
l = l * 2
}
// Log("New BUFFER SIZE " + fmt.Sprint(l) + "\n")
newBuf := make([]byte, l)
copy(newBuf, fb.buf)
fb.buf = newBuf
}
func (fb *FlexBuffer) fixLength() {
if(fb.Index > fb.Length) {
fb.Length = fb.Index
}
}
func (fb *FlexBuffer) Avail() int {
return fb.avail()
}
func (fb *FlexBuffer) avail() int {
return fb.Length - fb.Index
}
func (fb *FlexBuffer) Read(p []byte) (n int, err os.Error) {
fb.mutex.Lock()
// Log("Flexbuffer: BeginRead: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " " + fmt.Sprint(fb.Length) + " " + fmt.Sprint(fb.Index) + " " + fmt.Sprint(len(p)) + "\n")
toRead := len(p)
if fb.avail() < toRead {
toRead = fb.avail()
}
// Log("Flexbuffer: MiddleRead: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " " + fmt.Sprint(fb.Length) + " " + fmt.Sprint(fb.Index) + " " + fmt.Sprint(toRead) + "\n")
copy(p, fb.buf[fb.Index:fb.Index+toRead])
fb.Index = fb.Index + toRead
// Log("Flexbuffer: EndRead: " + fmt.Sprint(p) + " " + fmt.Sprint(fb.buf) + " " + fmt.Sprint(fb.Length) + " " + fmt.Sprint(fb.Index) + " " + fmt.Sprint(toRead) + "\n")
fb.mutex.Unlock()
return toRead, nil
}
func (fb *FlexBuffer) PutFromOtherFull(other *FlexBuffer) {
// Log("Flexbuffer.PutFromOtherFull " + fmt.Sprint(other.avail()) + "\n")
fb.PutFromOther(other, int32(other.avail()))
}
func (fb *FlexBuffer) PutFromOther(other *FlexBuffer, l int32) {
// Log("Flexbuffer.PutFromOther " + fmt.Sprint(l) + " " + fmt.Sprint(other) + "\n")
buf := make([]byte, l)
other.Read(buf)
fb.Write(buf)
}
func (fb *FlexBuffer) Put(val interface{}) {
binary.Write(fb, binary.BigEndian, val)
}
func (fb *FlexBuffer) PutByte(b int8) {
binary.Write(fb, binary.BigEndian, b)
}
func (fb *FlexBuffer) PutInt(i int32) {
binary.Write(fb, binary.BigEndian, i)
}
func (fb *FlexBuffer) PutShort(s int16) {
binary.Write(fb, binary.BigEndian, s)
}
func (fb *FlexBuffer) PutLong(l int64) {
binary.Write(fb, binary.BigEndian, l)
}
func (fb *FlexBuffer) PutFloat(f float32) {
binary.Write(fb, binary.BigEndian, f)
}
func (fb *FlexBuffer) PutDouble(d float64) {
binary.Write(fb, binary.BigEndian, d)
}
func (fb *FlexBuffer) PutBytes(bytes []uint8) {
binary.Write(fb, binary.BigEndian, bytes)
}
func (fb *FlexBuffer) PutSBytes(bytes []int8) {
binary.Write(fb, binary.BigEndian, bytes)
}
func (fb *FlexBuffer) ReadByte() int8 {
ret := new(int8)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadInt() int32 {
ret := new(int32)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadShort() int16 {
ret := new(int16)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadLong() int64 {
ret := new(int64)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadFloat() float32 {
ret := new(float32)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadDouble() float64 {
ret := new(float64)
binary.Read(fb, binary.BigEndian, ret)
return *ret
}
func (fb *FlexBuffer) ReadBytes(bytes *[]uint8) {
binary.Read(fb, binary.BigEndian, bytes)
}
func (fb *FlexBuffer) ReadSBytes(bytes *[]int8) {
binary.Read(fb, binary.BigEndian, bytes)
}