57 lines
1.1 KiB
Go
57 lines
1.1 KiB
Go
package playback
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
const stderrTailMaxBytes = 64 * 1024
|
|
|
|
type boundedTailBuffer struct {
|
|
mu sync.Mutex
|
|
max int
|
|
buffer []byte
|
|
}
|
|
|
|
func newBoundedTailBuffer(max int) *boundedTailBuffer {
|
|
if max <= 0 {
|
|
max = stderrTailMaxBytes
|
|
}
|
|
return &boundedTailBuffer{max: max}
|
|
}
|
|
|
|
func (b *boundedTailBuffer) Write(p []byte) (int, error) {
|
|
b.mu.Lock()
|
|
defer b.mu.Unlock()
|
|
|
|
b.buffer = append(b.buffer, p...)
|
|
if overflow := len(b.buffer) - b.max; overflow > 0 {
|
|
b.buffer = append([]byte(nil), b.buffer[overflow:]...)
|
|
}
|
|
return len(p), nil
|
|
}
|
|
|
|
func (b *boundedTailBuffer) Reset() {
|
|
b.mu.Lock()
|
|
b.buffer = b.buffer[:0]
|
|
b.mu.Unlock()
|
|
}
|
|
|
|
func (b *boundedTailBuffer) String() string {
|
|
b.mu.Lock()
|
|
defer b.mu.Unlock()
|
|
return strings.ToValidUTF8(string(b.buffer), "\uFFFD")
|
|
}
|
|
|
|
func truncateUTF8String(value string, maxChars int) (string, bool) {
|
|
if maxChars <= 0 {
|
|
return "", value != ""
|
|
}
|
|
if utf8.RuneCountInString(value) <= maxChars {
|
|
return value, false
|
|
}
|
|
runes := []rune(value)
|
|
return string(runes[:maxChars]), true
|
|
}
|