Compare commits
10 Commits
711b415c61
...
44ebd9249d
Author | SHA1 | Date |
---|---|---|
Charles Iliya Krempeaux | 44ebd9249d | |
Charles Iliya Krempeaux | 32b419923a | |
Charles Iliya Krempeaux | 1f2fc46a71 | |
Charles Iliya Krempeaux | a380cfb0e2 | |
Charles Iliya Krempeaux | 30d0a151c3 | |
Charles Iliya Krempeaux | 5127098a61 | |
Charles Iliya Krempeaux | cc99ea7cf8 | |
Charles Iliya Krempeaux | 068d259699 | |
Charles Iliya Krempeaux | a0e5c6762a | |
Charles Iliya Krempeaux | 06edca9192 |
|
@ -1,16 +1,16 @@
|
||||||
# go-buffers
|
# go-buffers
|
||||||
|
|
||||||
Package **buffers** provides tools for working with byte array, and byte slice buffers.
|
Package **buffers** provides tools for working with byte array, and byte slice buffers, for the Go programming language.
|
||||||
|
|
||||||
## Documention
|
## Documention
|
||||||
|
|
||||||
Online documentation, which includes examples, can be found at: http://godoc.org/github.com/reiver/go-buffers
|
Online documentation, which includes examples, can be found at: http://godoc.org/sourcecode.social/reiver/go-buffers
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/reiver/go-buffers?status.svg)](https://godoc.org/github.com/reiver/go-buffers)
|
[![GoDoc](https://godoc.org/sourcecode.social/reiver/go-buffers?status.svg)](https://godoc.org/sourcecode.social/reiver/go-buffers)
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
```go
|
```go
|
||||||
import "github.com/reiver/go-buffers"
|
import "sourcecode.social/reiver/go-buffers"
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package buffers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"sourcecode.social/reiver/go-opt"
|
||||||
|
"sourcecode.social/reiver/go-utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Buffer is used to store a series of bytes.
|
||||||
|
//
|
||||||
|
// A Buffer can be used as is, without any type of initialization (if not doesn't want the Buffer to have a limit):
|
||||||
|
//
|
||||||
|
// var buffer buffers.Buffer
|
||||||
|
//
|
||||||
|
// But if one wants the Buffer to have a limit, then it should be initialized like the following:
|
||||||
|
//
|
||||||
|
// var buffer buffers.Buffer = buffers.LimitedBuffer(4194304) // 4 MB
|
||||||
|
type Buffer struct {
|
||||||
|
data []byte
|
||||||
|
max opt.Optional[int]
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ io.ByteWriter = &Buffer{}
|
||||||
|
var _ io.ReaderFrom = &Buffer{}
|
||||||
|
var _ io.Writer = &Buffer{}
|
||||||
|
|
||||||
|
// LimitedBuffer returns a Buffer with a maximum size.
|
||||||
|
//
|
||||||
|
// var buffer buffers.Buffer = buffers.LimitedBuffer(4194304) // 4 MB
|
||||||
|
func LimitedBuffer(max int) Buffer {
|
||||||
|
return Buffer {
|
||||||
|
max:opt.Something[int](max),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns how many bytes have been accumulated in Buffer.
|
||||||
|
//
|
||||||
|
// receiver.Len() == len(receiver.String())
|
||||||
|
func (receiver *Buffer) Len() int {
|
||||||
|
if nil == receiver {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(receiver.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFrom reads from the io.Reader. Copying bytes until it gets an io.EOF.
|
||||||
|
func (receiver *Buffer) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
if nil == receiver {
|
||||||
|
return 0, errNilReceiver
|
||||||
|
}
|
||||||
|
if nil == r {
|
||||||
|
return 0, errNilReader
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.Copy(receiver, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the bytes that have been accumulated.
|
||||||
|
func (receiver *Buffer) String() string {
|
||||||
|
if nil == receiver {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil == receiver.data {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return *(*string)(unsafe.Pointer(&receiver.data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (receiver *Buffer) Write(p []byte) (n int, err error) {
|
||||||
|
if nil == receiver {
|
||||||
|
return 0, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
var lenP int
|
||||||
|
{
|
||||||
|
lenP = len(p)
|
||||||
|
if lenP <= 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
max, something := receiver.max.Get()
|
||||||
|
if something {
|
||||||
|
newLen := receiver.Len() + lenP
|
||||||
|
|
||||||
|
if max < newLen {
|
||||||
|
return 0, BufferOverflow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver.data = append(receiver.data, p...)
|
||||||
|
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteByte appends another byte to the Buffer.
|
||||||
|
func (receiver *Buffer) WriteByte(c byte) error {
|
||||||
|
if nil == receiver {
|
||||||
|
return errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
var b [1]byte
|
||||||
|
var p []byte = b[:]
|
||||||
|
b[0] = c
|
||||||
|
|
||||||
|
{
|
||||||
|
n, err := receiver.Write(p)
|
||||||
|
if nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if expected, actual := len(b), n; expected != actual {
|
||||||
|
return errShortWrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteRune appends the UTF-8 encoded rune to the Buffer.
|
||||||
|
func (receiver *Buffer) WriteRune(r rune) (int, error) {
|
||||||
|
if nil == receiver {
|
||||||
|
return 0, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
return utf8.WriteRune(receiver, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteRune appends the string to the Buffer.
|
||||||
|
func (receiver *Buffer) WriteString(s string) (int, error) {
|
||||||
|
if nil == receiver {
|
||||||
|
return 0, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.WriteString(receiver, s)
|
||||||
|
}
|
2
doc.go
2
doc.go
|
@ -5,7 +5,7 @@ Example
|
||||||
|
|
||||||
Here is an example of buffers.Writer being used to provide a io.Writer interface to an byte array, and byte slice:
|
Here is an example of buffers.Writer being used to provide a io.Writer interface to an byte array, and byte slice:
|
||||||
|
|
||||||
import "github.com/reiver/go-buffers"
|
import "sourcecode.social/reiver/go-buffers"
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
|
12
errors.go
12
errors.go
|
@ -1,10 +1,16 @@
|
||||||
package buffers
|
package buffers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"sourcecode.social/reiver/go-erorr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNilDestination = errors.New("buffers: Nil Destination")
|
BufferOverflow = erorr.Error("buffer overflow")
|
||||||
errNilReceiver = errors.New("buffers: Nil Receiver")
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errNilDestination = erorr.Error("nil destination")
|
||||||
|
errNilReader = erorr.Error("nil reader")
|
||||||
|
errNilReceiver = erorr.Error("nil receiver")
|
||||||
|
errShortWrite = erorr.Error("short write")
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package buffers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"sourcecode.social/reiver/go-buffers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleWriter() {
|
||||||
|
|
||||||
|
var buffer [256]byte
|
||||||
|
|
||||||
|
var p []byte = buffer[:]
|
||||||
|
|
||||||
|
writer := buffers.NewWriter(p)
|
||||||
|
|
||||||
|
data := []byte("Hello world!")
|
||||||
|
|
||||||
|
n, err := writer.Write(data)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Printf("ERROR: Problem writing: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Wrote %d bytes to the buffer.\n", n)
|
||||||
|
fmt.Printf("Those %d bytes in the buffer have a value of “%s”.\n", n, buffer)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Wrote 12 bytes to the buffer.
|
||||||
|
|
||||||
|
// Those 12 bytes in the buffer have a value of “Hello world!”.
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
module sourcecode.social/reiver/go-buffers
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
sourcecode.social/reiver/go-erorr v0.0.0-20230922202459-231149d185a1 // indirect
|
||||||
|
sourcecode.social/reiver/go-opt v0.0.0-20230928102119-1f1dfca71dc8 // indirect
|
||||||
|
sourcecode.social/reiver/go-utf8 v0.0.0-20230818133704-d38de8eb477f // indirect
|
||||||
|
)
|
|
@ -0,0 +1,6 @@
|
||||||
|
sourcecode.social/reiver/go-erorr v0.0.0-20230922202459-231149d185a1 h1:wpnz4JicQBLWrgGphYBls7DysIFCcnWgDz/vce/sY8E=
|
||||||
|
sourcecode.social/reiver/go-erorr v0.0.0-20230922202459-231149d185a1/go.mod h1:NFtd7fzEf0r6A6R7JXYZfayRhPaJy0zt/18VWoLzrxA=
|
||||||
|
sourcecode.social/reiver/go-opt v0.0.0-20230928102119-1f1dfca71dc8 h1:9Y+ZZCOU+vCuFq/WP5yjJNp7OedQkdAw1U5OVdX46Mo=
|
||||||
|
sourcecode.social/reiver/go-opt v0.0.0-20230928102119-1f1dfca71dc8/go.mod h1:O6WKM2UcKkheRT/dA6A2b1tW0m+WenSbxdcXE+idxzI=
|
||||||
|
sourcecode.social/reiver/go-utf8 v0.0.0-20230818133704-d38de8eb477f h1:fVoIT3wG97EMKMDpR5KU4b5uwFKLl5e9AOV72o45M0k=
|
||||||
|
sourcecode.social/reiver/go-utf8 v0.0.0-20230818133704-d38de8eb477f/go.mod h1:xZZIkdX6xIkkzalD1YTiM1F3Os9xPaIY7z9s6EBDmCI=
|
|
@ -0,0 +1,414 @@
|
||||||
|
package buffers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"sourcecode.social/reiver/go-buffers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLimitedBuffer_oneByteAtATime(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct{
|
||||||
|
Data string
|
||||||
|
Expected string
|
||||||
|
Limit int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "",
|
||||||
|
Limit: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0",
|
||||||
|
Limit: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01",
|
||||||
|
Limit: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012",
|
||||||
|
Limit: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123",
|
||||||
|
Limit: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01234",
|
||||||
|
Limit: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012345",
|
||||||
|
Limit: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456",
|
||||||
|
Limit: 7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01234567",
|
||||||
|
Limit: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012345678",
|
||||||
|
Limit: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789",
|
||||||
|
Limit: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"A",
|
||||||
|
Limit: 11,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"AB",
|
||||||
|
Limit: 12,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABC",
|
||||||
|
Limit: 13,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCD",
|
||||||
|
Limit: 14,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDE",
|
||||||
|
Limit: 15,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXY",
|
||||||
|
Limit: 35,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||||
|
Limit: 36,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"a",
|
||||||
|
Limit: 37,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"ab",
|
||||||
|
Limit: 38,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abc",
|
||||||
|
Limit: 39,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvw",
|
||||||
|
Limit: 59,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwx",
|
||||||
|
Limit: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxy",
|
||||||
|
Limit: 61,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Limit: 62,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
loop: for testNumber, test := range tests {
|
||||||
|
|
||||||
|
{
|
||||||
|
var buffer buffers.Buffer = buffers.LimitedBuffer(test.Limit)
|
||||||
|
|
||||||
|
var i int
|
||||||
|
for i=0; i<test.Limit; i++ {
|
||||||
|
var b [1]byte
|
||||||
|
var p []byte = b[:]
|
||||||
|
|
||||||
|
b[0] = test.Data[i]
|
||||||
|
|
||||||
|
n, err := buffer.Write(p)
|
||||||
|
if nil != err {
|
||||||
|
t.Errorf("For test #%d, did not expect an error but actually got one,", testNumber)
|
||||||
|
t.Logf("ERROR: (%T) %q", err, err)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
if expected, actual := 1, n; expected != actual {
|
||||||
|
t.Errorf("For test #%d, the actual number of bytes written is not what was expected.", testNumber)
|
||||||
|
t.Logf("EXPECTED: %d", expected)
|
||||||
|
t.Logf("ACTUAL: %d", actual)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var b [1]byte
|
||||||
|
var p []byte = b[:]
|
||||||
|
|
||||||
|
if len(test.Data) < i {
|
||||||
|
b[0] = test.Data[i]
|
||||||
|
} else {
|
||||||
|
b[0] = '?'
|
||||||
|
}
|
||||||
|
n, err := buffer.Write(p)
|
||||||
|
if nil == err {
|
||||||
|
t.Errorf("For test #%d, expected an error but did not actually get one,", testNumber)
|
||||||
|
t.Logf("ERROR: (%T) %q", err, err)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
if buffers.BufferOverflow != err {
|
||||||
|
t.Errorf("For test #%d, expected a buffer-overflow error but actually got a different error.", testNumber)
|
||||||
|
t.Logf("ERROR: (%T) %q", err, err)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
if expected, actual := 0, n; expected != actual {
|
||||||
|
t.Errorf("For test #%d, the actual number of bytes written is not what was expected.", testNumber)
|
||||||
|
t.Logf("EXPECTED: %d", expected)
|
||||||
|
t.Logf("ACTUAL: %d", actual)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var expected string = test.Expected
|
||||||
|
var actual string = buffer.String()
|
||||||
|
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("For test #%d, the actual value in the buffer is not what was expected.", testNumber)
|
||||||
|
t.Logf("EXPECTED: %q", expected)
|
||||||
|
t.Logf("ACTUAL: %q", actual)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLimitedBuffer_all(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct{
|
||||||
|
Data string
|
||||||
|
Expected string
|
||||||
|
Limit int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "",
|
||||||
|
Limit: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0",
|
||||||
|
Limit: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01",
|
||||||
|
Limit: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012",
|
||||||
|
Limit: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123",
|
||||||
|
Limit: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01234",
|
||||||
|
Limit: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012345",
|
||||||
|
Limit: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456",
|
||||||
|
Limit: 7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "01234567",
|
||||||
|
Limit: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "012345678",
|
||||||
|
Limit: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789",
|
||||||
|
Limit: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"A",
|
||||||
|
Limit: 11,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"AB",
|
||||||
|
Limit: 12,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABC",
|
||||||
|
Limit: 13,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCD",
|
||||||
|
Limit: 14,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDE",
|
||||||
|
Limit: 15,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXY",
|
||||||
|
Limit: 35,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||||
|
Limit: 36,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"a",
|
||||||
|
Limit: 37,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"ab",
|
||||||
|
Limit: 38,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abc",
|
||||||
|
Limit: 39,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvw",
|
||||||
|
Limit: 59,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwx",
|
||||||
|
Limit: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxy",
|
||||||
|
Limit: 61,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Expected: "0123456789"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
Limit: 62,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
loop: for testNumber, test := range tests {
|
||||||
|
|
||||||
|
var limit int = len(test.Expected)
|
||||||
|
|
||||||
|
var buffer buffers.Buffer = buffers.LimitedBuffer(limit)
|
||||||
|
|
||||||
|
n, err := buffer.Write([]byte(test.Expected))
|
||||||
|
if nil != err {
|
||||||
|
t.Errorf("For test #%d, did not expect an error but actually got one,", testNumber)
|
||||||
|
t.Logf("ERROR: (%T) %q", err, err)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
t.Logf("ACTUAL-DATA: %q", buffer.String())
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
if expected, actual := limit, n; expected != actual {
|
||||||
|
t.Errorf("For test #%d, the actual number of bytes written is not what was expected.", testNumber)
|
||||||
|
t.Logf("EXPECTED: %d", expected)
|
||||||
|
t.Logf("ACTUAL: %d", actual)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("EXPECTED-DATA: %q", test.Expected)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var expected string = test.Expected
|
||||||
|
var actual string = buffer.String()
|
||||||
|
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("For test #%d, the actual value in the buffer is not what was expected.", testNumber)
|
||||||
|
t.Logf("EXPECTED: %q", expected)
|
||||||
|
t.Logf("ACTUAL: %q", actual)
|
||||||
|
t.Logf("DATA: %q", test.Data)
|
||||||
|
t.Logf("LIMIT: %d", test.Limit)
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
package buffers
|
package buffers
|
||||||
|
|
||||||
|
// Writer provides an io.Writer interface to a byte array, and byte slice.
|
||||||
|
//
|
||||||
|
// This is something that should probably exist in the Go built-in "bytes" library, but doesn't.
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
dst []byte
|
dst []byte
|
||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWriter(dst []byte) Writer {
|
func NewWriter(dst []byte) *Writer {
|
||||||
return Writer{
|
return &Writer{
|
||||||
dst:dst,
|
dst:dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package buffers_test
|
package buffers_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/reiver/go-buffers"
|
"testing"
|
||||||
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"testing"
|
"sourcecode.social/reiver/go-buffers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWriterSingleWrite(t *testing.T) {
|
func TestWriterSingleWrite(t *testing.T) {
|
||||||
|
@ -292,7 +292,7 @@ func TestWriterSingleWrite(t *testing.T) {
|
||||||
|
|
||||||
var buffer []byte = make([]byte, test.BufferLength)
|
var buffer []byte = make([]byte, test.BufferLength)
|
||||||
|
|
||||||
var dst buffers.Writer = buffers.NewWriter(buffer)
|
var dst *buffers.Writer = buffers.NewWriter(buffer)
|
||||||
|
|
||||||
n, err := dst.Write(test.Src)
|
n, err := dst.Write(test.Src)
|
||||||
if _, casted := err.(buffers.TooShort); !casted {
|
if _, casted := err.(buffers.TooShort); !casted {
|
||||||
|
@ -857,7 +857,7 @@ func TestWriterMultipleWrites(t *testing.T) {
|
||||||
|
|
||||||
var buffer []byte = make([]byte, test.BufferLength)
|
var buffer []byte = make([]byte, test.BufferLength)
|
||||||
|
|
||||||
var dst buffers.Writer = buffers.NewWriter(buffer)
|
var dst *buffers.Writer = buffers.NewWriter(buffer)
|
||||||
|
|
||||||
var sum int
|
var sum int
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue