-
Notifications
You must be signed in to change notification settings - Fork 1
/
logattr.go
100 lines (87 loc) · 1.71 KB
/
logattr.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) 2012-2023 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
package mlog
import "fmt"
type Attr struct {
Key string
Value interface{}
}
func A(key string, value interface{}) *Attr {
return &Attr{key, value}
}
func (attr *Attr) writeBuf(w byteSliceWriter) {
if attr == nil {
return
}
// scratch buffer for intermediate writes
buf := bufPool.Get()
defer bufPool.Put(buf)
w.WriteString(attr.Key)
w.WriteString(`="`)
fmt.Fprint(buf, attr.Value)
// pull out byte slice from buff
b := buf.Bytes()
blen := buf.Len()
p := 0
for i := 0; i < blen; i++ {
switch b[i] {
case '"':
w.Write(b[p:i])
w.WriteString(`\"`)
p = i + 1
case '\t':
w.Write(b[p:i])
w.WriteString(`\t`)
p = i + 1
case '\r':
w.Write(b[p:i])
w.WriteString(`\r`)
p = i + 1
case '\n':
w.Write(b[p:i])
w.WriteString(`\n`)
p = i + 1
}
}
if p < blen {
w.Write(b[p:blen])
}
w.WriteByte('"')
// truncate intermediate buf so it is clean for next loop
buf.Truncate(0)
}
func (attr *Attr) String() string {
buf := bufPool.Get()
defer bufPool.Put(buf)
attr.writeBuf(buf)
return buf.String()
}
func attrsWriteBuf(w byteSliceWriter, attrs []*Attr) {
attrsLen := len(attrs)
for i, attr := range filterAttrs(attrs) {
attr.writeBuf(w)
if i != attrsLen-1 {
w.WriteByte(' ')
}
}
}
func filterAttrs(attrs []*Attr) []*Attr {
hasNil := false
for _, attr := range attrs {
if attr == nil {
hasNil = true
break
}
}
if !hasNil {
return attrs
}
filteredAttrs := make([]*Attr, 0, len(attrs))
for _, attr := range attrs {
if attr != nil {
filteredAttrs = append(filteredAttrs, attr)
}
}
return filteredAttrs
}