63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
package parser
|
|
|
|
import (
|
|
"bytes"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// StringBuffer is a string buffer implementation, which is used by the parser
|
|
// to efficiently accumulate runes from the input and eventually turn these
|
|
// into a string, either literal or interpreted.
|
|
type StringBuffer struct {
|
|
buffer bytes.Buffer
|
|
}
|
|
|
|
// Reset resets the string buffer, in order to build a new string.
|
|
func (b *StringBuffer) Reset() *StringBuffer {
|
|
b.buffer.Reset()
|
|
return b
|
|
}
|
|
|
|
// WriteString adds the runes of the input string to the string buffer.
|
|
func (b *StringBuffer) WriteString(s string) *StringBuffer {
|
|
for _, r := range s {
|
|
b.WriteRune(r)
|
|
}
|
|
return b
|
|
}
|
|
|
|
// WriteRune adds a single rune to the string buffer.
|
|
func (b *StringBuffer) WriteRune(r rune) *StringBuffer {
|
|
b.buffer.WriteRune(r)
|
|
return b
|
|
}
|
|
|
|
// AsLiteralString returns the string buffer as a literal string.
|
|
// Literal means that no escape sequences are processed.
|
|
func (b *StringBuffer) AsLiteralString() string {
|
|
return b.buffer.String()
|
|
}
|
|
|
|
// AsInterpretedString returns the string in its interpreted form.
|
|
// Interpreted means that escape sequences are handled in the way that Go would
|
|
// have, had it been inside double quotes. It translates for example escape
|
|
// sequences like "\n", "\t", \uXXXX" and "\UXXXXXXXX" into their string
|
|
// representations.
|
|
// Since the input might contain invalid escape sequences, this method
|
|
// also returns an error. When an error is returned, the returned string will
|
|
// contain the string as far as it could be interpreted.
|
|
func (b *StringBuffer) AsInterpretedString() (string, error) {
|
|
var sb strings.Builder
|
|
tail := b.buffer.String()
|
|
for len(tail) > 0 {
|
|
r, _, newtail, err := strconv.UnquoteChar(tail, '"')
|
|
if err != nil {
|
|
return sb.String(), err
|
|
}
|
|
tail = newtail
|
|
sb.WriteRune(r)
|
|
}
|
|
return sb.String(), nil
|
|
}
|