array_parser.go (2004B)
1 package pgdialect 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "fmt" 7 "io" 8 ) 9 10 type arrayParser struct { 11 *streamParser 12 err error 13 } 14 15 func newArrayParser(b []byte) *arrayParser { 16 p := &arrayParser{ 17 streamParser: newStreamParser(b, 1), 18 } 19 if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' { 20 p.err = fmt.Errorf("bun: can't parse array: %q", b) 21 } 22 return p 23 } 24 25 func (p *arrayParser) NextElem() ([]byte, error) { 26 if p.err != nil { 27 return nil, p.err 28 } 29 30 c, err := p.readByte() 31 if err != nil { 32 return nil, err 33 } 34 35 switch c { 36 case '}': 37 return nil, io.EOF 38 case '"': 39 b, err := p.readSubstring() 40 if err != nil { 41 return nil, err 42 } 43 44 if p.peek() == ',' { 45 p.skipNext() 46 } 47 48 return b, nil 49 default: 50 b := p.readSimple() 51 if bytes.Equal(b, []byte("NULL")) { 52 b = nil 53 } 54 55 if p.peek() == ',' { 56 p.skipNext() 57 } 58 59 return b, nil 60 } 61 } 62 63 func (p *arrayParser) readSimple() []byte { 64 p.unreadByte() 65 66 if i := bytes.IndexByte(p.b[p.i:], ','); i >= 0 { 67 b := p.b[p.i : p.i+i] 68 p.i += i 69 return b 70 } 71 72 b := p.b[p.i : len(p.b)-1] 73 p.i = len(p.b) - 1 74 return b 75 } 76 77 func (p *arrayParser) readSubstring() ([]byte, error) { 78 c, err := p.readByte() 79 if err != nil { 80 return nil, err 81 } 82 83 p.buf = p.buf[:0] 84 for { 85 if c == '"' { 86 break 87 } 88 89 next, err := p.readByte() 90 if err != nil { 91 return nil, err 92 } 93 94 if c == '\\' { 95 switch next { 96 case '\\', '"': 97 p.buf = append(p.buf, next) 98 99 c, err = p.readByte() 100 if err != nil { 101 return nil, err 102 } 103 default: 104 p.buf = append(p.buf, '\\') 105 c = next 106 } 107 continue 108 } 109 if c == '\'' && next == '\'' { 110 p.buf = append(p.buf, next) 111 c, err = p.readByte() 112 if err != nil { 113 return nil, err 114 } 115 continue 116 } 117 118 p.buf = append(p.buf, c) 119 c = next 120 } 121 122 if bytes.HasPrefix(p.buf, []byte("\\x")) && len(p.buf)%2 == 0 { 123 data := p.buf[2:] 124 buf := make([]byte, hex.DecodedLen(len(data))) 125 n, err := hex.Decode(buf, data) 126 if err != nil { 127 return nil, err 128 } 129 return buf[:n], nil 130 } 131 132 return p.buf, nil 133 }