package text
import (
)
func ( *Decoder) () (Token, error) {
:= .in
var []string
for len(.in) > 0 && (.in[0] == '"' || .in[0] == '\'') {
, := .parseString()
if != nil {
return Token{},
}
= append(, )
}
return Token{
kind: Scalar,
attrs: stringValue,
pos: len(.orig) - len(),
raw: [:len()-len(.in)],
str: strings.Join(, ""),
}, nil
}
func ( *Decoder) () (string, error) {
:= .in
if len() == 0 {
return "", ErrUnexpectedEOF
}
:= [0]
= [1:]
:= indexNeedEscapeInBytes()
, := [:], [::]
for len() > 0 {
switch , := utf8.DecodeRune(); {
case == utf8.RuneError && == 1:
return "", .newSyntaxError("invalid UTF-8 detected")
case == 0 || == '\n':
return "", .newSyntaxError("invalid character %q in string", )
case == rune():
= [1:]
.consume(len(.in) - len())
return string(), nil
case == '\\':
if len() < 2 {
return "", ErrUnexpectedEOF
}
switch := [1]; {
case '"', '\'', '\\', '?':
, = [2:], append(, )
case 'a':
, = [2:], append(, '\a')
case 'b':
, = [2:], append(, '\b')
case 'n':
, = [2:], append(, '\n')
case 'r':
, = [2:], append(, '\r')
case 't':
, = [2:], append(, '\t')
case 'v':
, = [2:], append(, '\v')
case 'f':
, = [2:], append(, '\f')
case '0', '1', '2', '3', '4', '5', '6', '7':
:= len([1:]) - len(bytes.TrimLeft([1:], "01234567"))
if > 3 {
= 3
}
, := strconv.ParseUint(string([1:1+]), 8, 8)
if != nil {
return "", .newSyntaxError("invalid octal escape code %q in string", [:1+])
}
, = [1+:], append(, byte())
case 'x':
:= len([2:]) - len(bytes.TrimLeft([2:], "0123456789abcdefABCDEF"))
if > 2 {
= 2
}
, := strconv.ParseUint(string([2:2+]), 16, 8)
if != nil {
return "", .newSyntaxError("invalid hex escape code %q in string", [:2+])
}
, = [2+:], append(, byte())
case 'u', 'U':
:= 6
if == 'U' {
= 10
}
if len() < {
return "", ErrUnexpectedEOF
}
, := strconv.ParseUint(string([2:]), 16, 32)
if utf8.MaxRune < || != nil {
return "", .newSyntaxError("invalid Unicode escape code %q in string", [:])
}
= [:]
:= rune()
if utf16.IsSurrogate() {
if len() < 6 {
return "", ErrUnexpectedEOF
}
, := strconv.ParseUint(string([2:6]), 16, 16)
= utf16.DecodeRune(, rune())
if [0] != '\\' || [1] != 'u' || == unicode.ReplacementChar || != nil {
return "", .newSyntaxError("invalid Unicode escape code %q in string", [:6])
}
= [6:]
}
= append(, string()...)
default:
return "", .newSyntaxError("invalid escape code %q in string", [:2])
}
default:
:= indexNeedEscapeInBytes([:])
, = [+:], append(, [:+]...)
}
}
return "", ErrUnexpectedEOF
}
func ( []byte) int { return indexNeedEscapeInString(strs.UnsafeString()) }
func ( string) (string, error) {
:= NewDecoder([]byte())
return .parseString()
}