-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgax_writers.go
138 lines (115 loc) · 3.78 KB
/
gax_writers.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package gax
import "unicode/utf8"
/*
Short for "non-escaping writer". Mostly for internal use. Similar to
`bytes.Buffer` or `strings.Builder`, but simpler and more flexible,
because it's just a typedef of `[]byte`.
*/
type NonEscWri []byte
// Implement `io.Writer`. Similar to `strings.Builder.Write`.
func (self *NonEscWri) Write(val []byte) (int, error) {
*self = append(*self, val...)
return len(val), nil
}
// Implement `io.StringWriter`. Similar to `strings.Builder.WriteString`.
func (self *NonEscWri) WriteString(val string) (int, error) {
*self = append(*self, val...)
return len(val), nil
}
// Similar to `strings.Builder.WriteRune`.
func (self *NonEscWri) WriteRune(val rune) (int, error) {
if uint32(val) < utf8.RuneSelf {
*self = append(*self, byte(val))
return 1, nil
}
self.grow(utf8.UTFMax)
len := len(*self)
wid := utf8.EncodeRune((*self)[len:len+utf8.UTFMax], val)
*self = (*self)[:len+wid]
return wid, nil
}
// Similar to `strings.Builder.String`. Free cast with no allocation.
func (self NonEscWri) String() string { return bytesString(self) }
// TODO make public.
func (self *NonEscWri) grow(size int) { *self = grow(*self, size) }
/*
Short for "attribute writer". Mostly for internal use. Writes text as if it were
inside an HTML/XML attribute, without enclosing quotes, escaping as necessary.
For escaping rules, see:
https://www.w3.org/TR/html52/syntax.html#escaping-a-string
*/
type AttrWri []byte
/*
Implement `io.Writer`. Similar to `strings.Builder.Write`, but escapes special
chars. Technically not compliant with `io.Writer`: the returned count of
written bytes may exceed the size of the provided chunk.
*/
func (self *AttrWri) Write(val []byte) (int, error) {
return self.WriteString(bytesString(val))
}
// Implement `io.StringWriter`. Similar to `strings.Builder.WriteString`, but
// escapes special chars.
func (self *AttrWri) WriteString(val string) (size int, _ error) {
for _, char := range val {
delta, _ := self.WriteRune(char)
size += delta
}
return
}
// Similar to `strings.Builder.WriteRune`, but escapes special chars.
func (self *AttrWri) WriteRune(val rune) (int, error) {
wri := (*NonEscWri)(self)
switch val {
case '&':
return wri.WriteString(`&`)
case '\u00a0':
return wri.WriteString(` `)
case '"':
return wri.WriteString(`"`)
default:
return wri.WriteRune(val)
}
}
// Similar to `strings.Builder.String`. Free cast with no allocation.
func (self AttrWri) String() string { return bytesString(self) }
/*
Short for "text writer". Mostly for internal use. Writes text as if it were
inside an HTML/XML element, escaping as necessary. For escaping rules, see:
https://www.w3.org/TR/html52/syntax.html#escaping-a-string
*/
type TextWri []byte
/*
Implement `io.Writer`. Similar to `strings.Builder.Write`, but escapes special
chars. Technically not compliant with `io.Writer`: the returned count of
written bytes may exceed the size of the provided chunk.
*/
func (self *TextWri) Write(val []byte) (int, error) {
return self.WriteString(bytesString(val))
}
// Implement `io.StringWriter`. Similar to `strings.Builder.WriteString`, but
// escapes special chars.
func (self *TextWri) WriteString(val string) (size int, _ error) {
for _, char := range val {
delta, _ := self.WriteRune(char)
size += delta
}
return
}
// Similar to `strings.Builder.WriteRune`, but escapes special chars.
func (self *TextWri) WriteRune(val rune) (int, error) {
wri := (*NonEscWri)(self)
switch val {
case '&':
return wri.WriteString(`&`)
case '\u00a0':
return wri.WriteString(` `)
case '<':
return wri.WriteString(`<`)
case '>':
return wri.WriteString(`>`)
default:
return wri.WriteRune(val)
}
}
// Similar to `strings.Builder.String`. Free cast with no allocation.
func (self TextWri) String() string { return bytesString(self) }