package orm
import (
)
var errEndOfComposite = errors.New("pg: end of composite")
type compositeParser struct {
p parser.StreamingParser
stickyErr error
}
func ( error) *compositeParser {
return &compositeParser{
stickyErr: ,
}
}
func ( types.Reader) *compositeParser {
:= parser.NewStreamingParser()
:= .SkipByte('(')
if != nil {
return newCompositeParserErr()
}
return &compositeParser{
p: ,
}
}
func ( *compositeParser) () ([]byte, error) {
if .stickyErr != nil {
return nil, .stickyErr
}
, := .p.ReadByte()
if != nil {
if == io.EOF {
return nil, errEndOfComposite
}
return nil,
}
switch {
case '"':
return .readQuoted()
case ',':
return nil, nil
case ')':
return nil, errEndOfComposite
default:
_ = .p.UnreadByte()
}
var []byte
for {
, := .p.ReadSlice(',')
if == nil {
if == nil {
=
} else {
= append(, ...)
}
= [:len()-1]
break
}
= append(, ...)
if == bufio.ErrBufferFull {
continue
}
if == io.EOF {
if [len()-1] == ')' {
= [:len()-1]
break
}
}
return nil,
}
if len() == 0 {
return nil, nil
}
return , nil
}
func ( *compositeParser) () ([]byte, error) {
var []byte
, := .p.ReadByte()
if != nil {
return nil,
}
for {
, := .p.ReadByte()
if != nil {
return nil,
}
if == '\\' || == '\'' {
if == {
= append(, )
, = .p.ReadByte()
if != nil {
return nil,
}
} else {
= append(, )
=
}
continue
}
if == '"' {
switch {
case '"':
= append(, '"')
, = .p.ReadByte()
if != nil {
return nil,
}
case ',', ')':
return , nil
default:
return nil, fmt.Errorf("pg: got %q, wanted ',' or ')'", )
}
continue
}
= append(, )
=
}
}