90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
package serial
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
const bufferCapacityIncrement = 1024 * 1024
|
|
|
|
// ByteStore is implementing a ReadWriteSeeker storing data in memory.
|
|
type ByteStore struct {
|
|
data []byte
|
|
offset int
|
|
}
|
|
|
|
// NewByteStore returns a new byte store instance.
|
|
func NewByteStore() *ByteStore {
|
|
return NewByteStoreFromData(make([]byte, 0, bufferCapacityIncrement))
|
|
}
|
|
|
|
// NewByteStoreFromData returns a new ByteStore instance wrapping the provided data.
|
|
func NewByteStoreFromData(data []byte) *ByteStore {
|
|
store := &ByteStore{
|
|
data: data,
|
|
offset: 0,
|
|
}
|
|
|
|
return store
|
|
}
|
|
|
|
// Data returns the current data buffer.
|
|
func (store *ByteStore) Data() []byte {
|
|
return store.data
|
|
}
|
|
|
|
// Seek implements the Seeker interface.
|
|
func (store *ByteStore) Seek(offset int64, whence int) (int64, error) {
|
|
switch whence {
|
|
case 0:
|
|
store.offset = int(offset)
|
|
case 1:
|
|
store.offset += int(offset)
|
|
case 2:
|
|
store.offset = len(store.data) + int(offset)
|
|
}
|
|
|
|
return int64(store.offset), nil
|
|
}
|
|
|
|
// Read implements the Reader interface.
|
|
func (store *ByteStore) Read(p []byte) (n int, err error) {
|
|
size := len(p)
|
|
n = len(store.data) - store.offset
|
|
if n > size {
|
|
n = size
|
|
}
|
|
if n < size && size > 0 {
|
|
err = io.EOF
|
|
}
|
|
copy(p, store.data[store.offset:store.offset+n])
|
|
store.offset += n
|
|
|
|
return
|
|
}
|
|
|
|
// Write implements the Writer interface.
|
|
func (store *ByteStore) Write(p []byte) (n int, err error) {
|
|
size := len(p)
|
|
store.ensureAvailable(size)
|
|
copy(store.data[store.offset:], p)
|
|
store.offset += size
|
|
|
|
return size, nil
|
|
}
|
|
|
|
func (store *ByteStore) ensureAvailable(size int) {
|
|
expected := store.offset + size
|
|
available := len(store.data)
|
|
|
|
if expected > available {
|
|
if expected > cap(store.data) {
|
|
old := store.data
|
|
|
|
store.data = make([]byte, expected, expected+bufferCapacityIncrement)
|
|
copy(store.data, old)
|
|
} else {
|
|
store.data = append(store.data, make([]byte, expected-available)...)
|
|
}
|
|
}
|
|
}
|