gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

parser.go (2109B)


      1 package parser
      2 
      3 import (
      4 	"bytes"
      5 	"strconv"
      6 
      7 	"github.com/uptrace/bun/internal"
      8 )
      9 
     10 type Parser struct {
     11 	b []byte
     12 	i int
     13 }
     14 
     15 func New(b []byte) *Parser {
     16 	return &Parser{
     17 		b: b,
     18 	}
     19 }
     20 
     21 func NewString(s string) *Parser {
     22 	return New(internal.Bytes(s))
     23 }
     24 
     25 func (p *Parser) Valid() bool {
     26 	return p.i < len(p.b)
     27 }
     28 
     29 func (p *Parser) Bytes() []byte {
     30 	return p.b[p.i:]
     31 }
     32 
     33 func (p *Parser) Read() byte {
     34 	if p.Valid() {
     35 		c := p.b[p.i]
     36 		p.Advance()
     37 		return c
     38 	}
     39 	return 0
     40 }
     41 
     42 func (p *Parser) Peek() byte {
     43 	if p.Valid() {
     44 		return p.b[p.i]
     45 	}
     46 	return 0
     47 }
     48 
     49 func (p *Parser) Advance() {
     50 	p.i++
     51 }
     52 
     53 func (p *Parser) Skip(skip byte) bool {
     54 	if p.Peek() == skip {
     55 		p.Advance()
     56 		return true
     57 	}
     58 	return false
     59 }
     60 
     61 func (p *Parser) SkipBytes(skip []byte) bool {
     62 	if len(skip) > len(p.b[p.i:]) {
     63 		return false
     64 	}
     65 	if !bytes.Equal(p.b[p.i:p.i+len(skip)], skip) {
     66 		return false
     67 	}
     68 	p.i += len(skip)
     69 	return true
     70 }
     71 
     72 func (p *Parser) ReadSep(sep byte) ([]byte, bool) {
     73 	ind := bytes.IndexByte(p.b[p.i:], sep)
     74 	if ind == -1 {
     75 		b := p.b[p.i:]
     76 		p.i = len(p.b)
     77 		return b, false
     78 	}
     79 
     80 	b := p.b[p.i : p.i+ind]
     81 	p.i += ind + 1
     82 	return b, true
     83 }
     84 
     85 func (p *Parser) ReadIdentifier() (string, bool) {
     86 	if p.i < len(p.b) && p.b[p.i] == '(' {
     87 		s := p.i + 1
     88 		if ind := bytes.IndexByte(p.b[s:], ')'); ind != -1 {
     89 			b := p.b[s : s+ind]
     90 			p.i = s + ind + 1
     91 			return internal.String(b), false
     92 		}
     93 	}
     94 
     95 	ind := len(p.b) - p.i
     96 	var alpha bool
     97 	for i, c := range p.b[p.i:] {
     98 		if isNum(c) {
     99 			continue
    100 		}
    101 		if isAlpha(c) || (i > 0 && alpha && c == '_') {
    102 			alpha = true
    103 			continue
    104 		}
    105 		ind = i
    106 		break
    107 	}
    108 	if ind == 0 {
    109 		return "", false
    110 	}
    111 	b := p.b[p.i : p.i+ind]
    112 	p.i += ind
    113 	return internal.String(b), !alpha
    114 }
    115 
    116 func (p *Parser) ReadNumber() int {
    117 	ind := len(p.b) - p.i
    118 	for i, c := range p.b[p.i:] {
    119 		if !isNum(c) {
    120 			ind = i
    121 			break
    122 		}
    123 	}
    124 	if ind == 0 {
    125 		return 0
    126 	}
    127 	n, err := strconv.Atoi(string(p.b[p.i : p.i+ind]))
    128 	if err != nil {
    129 		panic(err)
    130 	}
    131 	p.i += ind
    132 	return n
    133 }
    134 
    135 func isNum(c byte) bool {
    136 	return c >= '0' && c <= '9'
    137 }
    138 
    139 func isAlpha(c byte) bool {
    140 	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
    141 }