go-parsekit/stringbuf.go

63 lines
1.8 KiB
Go

package parsekit
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
}