Skip to content

Commit e2531a8

Browse files
author
Dean Karn
committed
Initial commit
0 parents  commit e2531a8

File tree

8 files changed

+226
-0
lines changed

8 files changed

+226
-0
lines changed

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Go template
3+
# Binaries for programs and plugins
4+
*.exe
5+
*.exe~
6+
*.dll
7+
*.so
8+
*.dylib
9+
10+
# Test binary, build with `go test -c`
11+
*.test
12+
13+
# Output of the go coverage tool, specifically when used with LiteIDE
14+
*.out
15+

.travis.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
language: go
2+
go:
3+
- 1.12.4
4+
- tip
5+
matrix:
6+
allow_failures:
7+
- go: tip
8+
9+
notifications:
10+
email:
11+
recipients: [email protected]
12+
on_success: change
13+
on_failure: always
14+
15+
before_install:
16+
- go get -u github.com/go-playground/overalls
17+
- go get -u github.com/mattn/goveralls
18+
- go get -u golang.org/x/tools/cmd/cover
19+
20+
before_script:
21+
- go get -t ./...
22+
23+
script:
24+
- make test
25+
26+
after_success: |
27+
[ $TRAVIS_GO_VERSION = 1.11.4 ] &&
28+
overalls -project="github.com/go-playground/pkg" -covermode=count -ignore=.git,_examples,testdata -debug &&
29+
goveralls -coverprofile=overalls.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Dean Karn
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
GOCMD=GO111MODULE=on go
2+
3+
linters-install:
4+
@golangci-lint --version >/dev/null 2>&1 || { \
5+
echo "installing linting tools..."; \
6+
$(GOCMD) get github.com/golangci/golangci-lint/cmd/golangci-lint; \
7+
}
8+
9+
lint: linters-install
10+
golangci-lint run
11+
12+
test:
13+
$(GOCMD) test -cover -race ./...
14+
15+
bench:
16+
$(GOCMD) test -bench=. -benchmem ./...
17+
18+
.PHONY: linters-install lint test bench

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# pkg
2+
======
3+
![Project status](https://img.shields.io/badge/version-1.0.0-green.svg)
4+
![License](https://img.shields.io/dub/l/vibe-d.svg)
5+
6+
pkg extends the core go packages with missing or additional functionality built in. All packages correspond to the std go package name with an additional suffix of `util` to avoid naming conflicts.
7+
8+
Motivation
9+
----------
10+
This is a place to put comman reusable code that is not quite a library but extends upon the core library or it's failings.
11+
12+
How to Contribute
13+
------
14+
15+
Make a pull request... can't guarantee it will be added, going to strictly vet what goes in.
16+
17+
License
18+
------
19+
Distributed under MIT License, please see license file within the code for more details.

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/go-playground/pkg
2+
3+
go 1.11

io/limit_reader.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ioutil
2+
3+
import (
4+
"errors"
5+
"io"
6+
)
7+
8+
var (
9+
// LimitedReaderEOF is an error returned by LimitedReader to give feedback to the fact that we did not hit an
10+
// EOF of the Reader but hit the limit imposed by the LimitedReader.
11+
LimitedReaderEOF = errors.New("LimitedReader EOF: limit reached")
12+
)
13+
14+
// LimitReader returns a Reader that reads from r
15+
// but stops with LimitedReaderEOF after n bytes.
16+
// The underlying implementation is a *LimitedReader.
17+
func LimitReader(r io.Reader, n int64) io.Reader {
18+
return &LimitedReader{R: r, N: n}
19+
}
20+
21+
// A LimitedReader reads from R but limits the amount of
22+
// data returned to just N bytes. Each call to Read
23+
// updates N to reflect the new amount remaining.
24+
// Read returns LimitedReaderEOF when N <= 0 or when the underlying R returns EOF.
25+
// Unlike the std io.LimitedReader this provides feedback
26+
// that the limit was reached through the returned error.
27+
type LimitedReader struct {
28+
R io.Reader
29+
N int64 // bytes alloted
30+
}
31+
32+
func (l *LimitedReader) Read(p []byte) (n int, err error) {
33+
if int64(len(p)) > l.N {
34+
p = p[0 : l.N+1]
35+
}
36+
n, err = l.R.Read(p)
37+
if err == io.EOF {
38+
return
39+
}
40+
l.N -= int64(n)
41+
if l.N < 0 {
42+
return len(p), LimitedReaderEOF
43+
}
44+
return
45+
}

io/limit_reader_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package ioutil
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestLimitedReader_Read(t *testing.T) {
9+
eofLimited := LimitReader(strings.NewReader("all"), 5).(*LimitedReader)
10+
11+
type args struct {
12+
p []byte
13+
}
14+
tests := []struct {
15+
name string
16+
l *LimitedReader
17+
args args
18+
wantN int
19+
wantErr bool
20+
}{
21+
{
22+
name: "not-limited",
23+
l: LimitReader(strings.NewReader("all"), 3).(*LimitedReader),
24+
args: args{p: make([]byte, 4)},
25+
wantN: 3,
26+
wantErr: false,
27+
},
28+
{
29+
name: "not-limited-exact",
30+
l: LimitReader(strings.NewReader("all"), 3).(*LimitedReader),
31+
args: args{p: make([]byte, 3)},
32+
wantN: 3,
33+
wantErr: false,
34+
},
35+
{
36+
name: "not-limited-EOF-OK",
37+
l: eofLimited,
38+
args: args{p: make([]byte, 4)},
39+
wantN: 3,
40+
wantErr: false,
41+
},
42+
{
43+
name: "not-limited-EOF",
44+
l: eofLimited,
45+
args: args{p: make([]byte, 4)},
46+
wantN: 0,
47+
wantErr: true,
48+
},
49+
{
50+
name: "limited",
51+
l: LimitReader(strings.NewReader("limited"), 1).(*LimitedReader),
52+
args: args{p: make([]byte, 3)},
53+
wantN: 2, // need to read one past to know we're past
54+
wantErr: true,
55+
},
56+
{
57+
name: "limited-buff-under-N",
58+
l: LimitReader(strings.NewReader("limited"), 0).(*LimitedReader),
59+
args: args{p: make([]byte, 1)},
60+
wantN: 1,
61+
wantErr: true,
62+
},
63+
}
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
gotN, err := tt.l.Read(tt.args.p)
67+
if (err != nil) != tt.wantErr {
68+
t.Errorf("LimitedReader.Read() error = %v, wantErr %v", err, tt.wantErr)
69+
return
70+
}
71+
if gotN != tt.wantN {
72+
t.Errorf("LimitedReader.Read() = %v, want %v", gotN, tt.wantN)
73+
}
74+
})
75+
}
76+
}

0 commit comments

Comments
 (0)