-
Notifications
You must be signed in to change notification settings - Fork 0
/
bounded.go
56 lines (49 loc) · 1.32 KB
/
bounded.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package htmllog
// Copyright 2016 Ernest Micklei. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.
import (
"bytes"
"fmt"
)
const (
endOfBuffer = "EOB"
)
type limitedBuffer struct {
*bytes.Buffer
// keep track of how many bytes have been written
written int
// maximum number of bytes that can be written
max int
}
// Write will attempt to write all bytes of p. If the write limit is reached then panic.
func (b *limitedBuffer) Write(p []byte) (n int, err error) {
if b.written+len(p) > b.max {
b.Buffer.Write(p[:b.max-b.written])
// limit reached; no need to update written field
panic(endOfBuffer)
}
n, err = b.Buffer.Write(p)
b.written += n
return
}
// sprintf is recoverable call to fmt.Fprintf
func (b *limitedBuffer) sprintf(format string, args ...interface{}) {
defer func() {
if err := recover(); err == endOfBuffer {
return
}
}()
fmt.Fprintf(b, format, args...)
}
// LimitedSprintf returns the result of fmt.Sprintf limited to a number of bytes.
// Use this function to protect against printing recursive structures.
func LimitedSprintf(limit int, format string, args ...interface{}) string {
w := &limitedBuffer{
Buffer: new(bytes.Buffer),
written: 0,
max: limit,
}
w.sprintf(format, args...)
return w.Buffer.String()
}