diff options
-rw-r--r-- | LICENSE | 4 | ||||
-rw-r--r-- | LimitedWriter.go | 39 | ||||
-rw-r--r-- | LimitedWriter_test.go | 33 | ||||
-rw-r--r-- | Nirvana.go | 19 | ||||
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | ReadByte.go | 23 | ||||
-rw-r--r-- | doc.go | 2 | ||||
-rw-r--r-- | strings.go | 35 |
8 files changed, 163 insertions, 0 deletions
@@ -0,0 +1,4 @@ + DO WHATEVER THE FUCK YOU WANT, PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHATEVER THE FUCK YOU WANT.
\ No newline at end of file diff --git a/LimitedWriter.go b/LimitedWriter.go new file mode 100644 index 0000000..4d23322 --- /dev/null +++ b/LimitedWriter.go @@ -0,0 +1,39 @@ +package kagus + +import ( + "errors" + "io" +) + +var ( + WriteLimitReached = errors.New("Write limit reached") +) + +// LimitWriter wraps around a io.Writer and limits the amount of bytes that can be written to it. +type LimitedWriter struct { + W io.Writer + N int64 +} + +// Write writes at most lw.N bytes to LimitWriter. It updates lw.N on sucessful write operations. +// If the limit was reached, the error WriteLimitReached will be returned. +func (lw *LimitedWriter) Write(p []byte) (int, error) { + towrite := int64(len(p)) + if lw.N < towrite { + towrite = lw.N + } + + n, err := lw.W.Write(p[:towrite]) + if err != nil { + lw.N = 0 + return n, err + } + + if n == len(p) { + lw.N -= int64(n) + return n, nil + } + + lw.N = 0 + return n, WriteLimitReached +} diff --git a/LimitedWriter_test.go b/LimitedWriter_test.go new file mode 100644 index 0000000..5af9d71 --- /dev/null +++ b/LimitedWriter_test.go @@ -0,0 +1,33 @@ +package kagus + +import ( + "bytes" + "testing" +) + +func TestLimitedWriting(t *testing.T) { + buf := new(bytes.Buffer) + lw := &LimitedWriter{buf, 10} + + if _, err := lw.Write([]byte{1, 2}); err != nil { + t.Fatalf("lw.Write failed: %s", err) + } + + if lw.N != 8 { + t.Fatalf("lw.N was supposed to be 8, is %d", lw.N) + } + + if !bytes.Equal(buf.Bytes(), []byte{1, 2}) { + t.Errorf("Unexpected content of buf: %v", buf.Bytes()) + } + + n, err := lw.Write([]byte{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}) + if (n != 8) || (err != WriteLimitReached) { + t.Fatalf("lw.Write returned with unexpected n, err: %d, %s", n, err) + } + + n, err = lw.Write([]byte("trololo")) + if (n != 0) || (err != WriteLimitReached) { + t.Fatalf("lw.Write returned with unexpected n, err: %d, %s", n, err) + } +} diff --git a/Nirvana.go b/Nirvana.go new file mode 100644 index 0000000..1aef1f0 --- /dev/null +++ b/Nirvana.go @@ -0,0 +1,19 @@ +package kagus + +// NirvanaWriter implements io.WriteCloser and discards everything written to it +type NirvanaWriter struct{} + +// NewNirvanaWriter returns a new NirvanaWriter +func NewNirvanaWriter() *NirvanaWriter { + return new(NirvanaWriter) +} + +// Write function for the io.Writer interface +func (nw *NirvanaWriter) Write(p []byte) (int, error) { + return len(p), nil +} + +// Close doesn't do anything and returns the error nil +func (nw *NirvanaWriter) Close() error { + return nil +} @@ -0,0 +1,8 @@ +Kevin's Awesome Go Utility Stuff +================================ + +Some utility stuff I use in some of my Go programs / libraries. + +Get it with: + +go get github.com/kagus diff --git a/ReadByte.go b/ReadByte.go new file mode 100644 index 0000000..75f843b --- /dev/null +++ b/ReadByte.go @@ -0,0 +1,23 @@ +package kagus + +import ( + "io" +) + +// ReadByte reads a single byte from a reader +func ReadByte(r io.Reader) (byte, error) { + buf := make([]byte, 1) + + for { + n, err := r.Read(buf) + if n == 1 { + break + } + + if err != nil { + return 0, err + } + } + + return buf[0], nil +} @@ -0,0 +1,2 @@ +// Package kagus (Kevin's Awesome Go Utility Stuff) is a collection of small utility stuff I use in my Go code. +package kagus diff --git a/strings.go b/strings.go new file mode 100644 index 0000000..555f5dd --- /dev/null +++ b/strings.go @@ -0,0 +1,35 @@ +package kagus + +import ( + "strings" + "unicode" +) + +// StringConsistsOf tests, if f returns true for all runes in s +func StringConsistsOf(s string, f func(rune) bool) bool { + for _, r := range s { + if !f(r) { + return false + } + } + return true +} + +// IsASCII tests, if a Rune is in the ASCII set +func IsASCII(r rune) bool { + return (r <= unicode.MaxASCII) +} + +// Indent a string s by prefixing each line with ind. +func Indent(s string, ind string) (rv string) { + ls := strings.Split(s, "\n") + first := true + for _, l := range ls { + if !first { + rv += "\n" + } + rv += ind + l + first = false + } + return +} |