You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.2 KiB
131 lines
3.2 KiB
//
|
|
// DISCLAIMER
|
|
//
|
|
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// Licensed 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.
|
|
//
|
|
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
// Author Ewout Prangsma
|
|
//
|
|
|
|
package velocypack
|
|
|
|
// builderBuffer is a byte slice used for building slices.
|
|
type builderBuffer []byte
|
|
|
|
const (
|
|
minGrowDelta = 128 // Minimum amount of extra bytes to add to a buffer when growing
|
|
maxGrowDelta = 1024 * 1024 // Maximum amount of extra bytes to add to a buffer when growing
|
|
)
|
|
|
|
// IsEmpty returns 0 if there are no values in the buffer.
|
|
func (b builderBuffer) IsEmpty() bool {
|
|
l := len(b)
|
|
return l == 0
|
|
}
|
|
|
|
// Len returns the length of the buffer.
|
|
func (b builderBuffer) Len() ValueLength {
|
|
l := len(b)
|
|
return ValueLength(l)
|
|
}
|
|
|
|
// Bytes returns the bytes written to the buffer.
|
|
// The returned slice is only valid until the next modification.
|
|
func (b *builderBuffer) Bytes() []byte {
|
|
return *b
|
|
}
|
|
|
|
// WriteByte appends a single byte to the buffer.
|
|
func (b *builderBuffer) WriteByte(v byte) {
|
|
off := len(*b)
|
|
b.growCapacity(1)
|
|
*b = (*b)[:off+1]
|
|
(*b)[off] = v
|
|
}
|
|
|
|
// WriteBytes appends a series of identical bytes to the buffer.
|
|
func (b *builderBuffer) WriteBytes(v byte, count uint) {
|
|
if count == 0 {
|
|
return
|
|
}
|
|
off := uint(len(*b))
|
|
b.growCapacity(count)
|
|
*b = (*b)[:off+count]
|
|
for i := uint(0); i < count; i++ {
|
|
(*b)[off+i] = v
|
|
}
|
|
}
|
|
|
|
// Write appends a series of bytes to the buffer.
|
|
func (b *builderBuffer) Write(v []byte) {
|
|
l := uint(len(v))
|
|
if l > 0 {
|
|
off := uint(len(*b))
|
|
b.growCapacity(l)
|
|
*b = (*b)[:off+l]
|
|
copy((*b)[off:], v)
|
|
}
|
|
}
|
|
|
|
// ReserveSpace ensures that at least n bytes can be added to the buffer without allocating new memory.
|
|
func (b *builderBuffer) ReserveSpace(n uint) {
|
|
if n > 0 {
|
|
b.growCapacity(n)
|
|
}
|
|
}
|
|
|
|
// Shrink reduces the length of the buffer by n elements (removing the last elements).
|
|
func (b *builderBuffer) Shrink(n uint) {
|
|
if n > 0 {
|
|
newLen := uint(len(*b)) - n
|
|
if newLen < 0 {
|
|
newLen = 0
|
|
}
|
|
*b = (*b)[:newLen]
|
|
}
|
|
}
|
|
|
|
// Grow adds n elements to the buffer, returning a slice where the added elements start.
|
|
func (b *builderBuffer) Grow(n uint) []byte {
|
|
l := uint(len(*b))
|
|
if n > 0 {
|
|
b.growCapacity(n)
|
|
*b = (*b)[:l+n]
|
|
}
|
|
return (*b)[l:]
|
|
}
|
|
|
|
// growCapacity ensures that there is enough capacity in the buffer to add n elements.
|
|
func (b *builderBuffer) growCapacity(n uint) {
|
|
_b := *b
|
|
curLen := uint(len(_b))
|
|
curCap := uint(cap(_b))
|
|
newCap := curLen + n
|
|
if newCap <= curCap {
|
|
// No need to do anything
|
|
return
|
|
}
|
|
// Increase the capacity
|
|
extra := newCap // Grow a bit more to avoid copying all the time
|
|
if extra < minGrowDelta {
|
|
extra = minGrowDelta
|
|
} else if extra > maxGrowDelta {
|
|
extra = maxGrowDelta
|
|
}
|
|
newBuffer := make(builderBuffer, curLen, newCap+extra)
|
|
copy(newBuffer, _b)
|
|
*b = newBuffer
|
|
}
|
|
|