github.com/RevenueMonster/sqlike@v1.0.6/jsonb/reader.go (about)

     1  package jsonb
     2  
     3  import (
     4  	"errors"
     5  )
     6  
     7  var whiteSpaceMap = map[byte]bool{
     8  	' ':  true,
     9  	'\n': true,
    10  	'\t': true,
    11  	'\r': true,
    12  }
    13  
    14  var emptyJSON = []byte(`null`)
    15  
    16  // Reader :
    17  type Reader struct {
    18  	typ   jsonType
    19  	b     []byte
    20  	pos   int
    21  	len   int
    22  	start int
    23  	end   int
    24  }
    25  
    26  // NewReader :
    27  func NewReader(b []byte) *Reader {
    28  	length := len(b)
    29  	copier := make([]byte, length)
    30  	copy(copier, b)
    31  	return &Reader{b: copier, len: length}
    32  }
    33  
    34  func (r *Reader) reset() *Reader {
    35  	r.pos = 0
    36  	return r
    37  }
    38  
    39  // Bytes :
    40  func (r *Reader) Bytes() []byte {
    41  	return r.b
    42  }
    43  
    44  // nextToken : nextToken will skip all whitespace and stop on a char
    45  func (r *Reader) nextToken() byte {
    46  	var c byte
    47  	for i := r.pos; i < r.len; i++ {
    48  		c = r.b[i]
    49  		if _, ok := whiteSpaceMap[c]; ok {
    50  			r.b = append(r.b[:i], r.b[i+1:]...)
    51  			r.len = len(r.b)
    52  			i--
    53  			continue
    54  		}
    55  		r.pos = i + 1
    56  		return c
    57  	}
    58  	return 0
    59  }
    60  
    61  func (r *Reader) prevToken() byte {
    62  	if r.pos > 0 {
    63  		return r.b[r.pos-1]
    64  	}
    65  	return 0
    66  }
    67  
    68  func (r *Reader) peekType() jsonType {
    69  	c := r.nextToken()
    70  	defer r.unreadByte()
    71  	typ := valueMap[c]
    72  	return typ
    73  }
    74  
    75  // IsNull :
    76  func (r *Reader) IsNull() bool {
    77  	offset := r.pos + 4
    78  	if offset > r.len {
    79  		return false
    80  	}
    81  	if string(r.b[r.pos:offset]) == null {
    82  		return true
    83  	}
    84  	return false
    85  }
    86  
    87  func (r *Reader) skipArray() {
    88  	level := 1
    89  	c := r.nextToken()
    90  	if c != '[' {
    91  		return
    92  	}
    93  
    94  	for i := r.pos; i < r.len; i++ {
    95  		switch r.b[i] {
    96  		case '"': // If inside string, skip it
    97  			// iter.head = i + 1
    98  			// iter.skipString()
    99  			// i = iter.head - 1 // it will be i++ soon
   100  		case '[': // If open symbol, increase level
   101  			level++
   102  		case ']': // If close symbol, increase level
   103  			level--
   104  
   105  			// If we have returned to the original level, we're done
   106  			if level <= 0 {
   107  				r.pos = i + 1
   108  				return
   109  			}
   110  		}
   111  	}
   112  }
   113  
   114  // ReadBytes :
   115  func (r *Reader) ReadBytes() ([]byte, error) {
   116  	i := r.pos
   117  	if err := r.skip(); err != nil {
   118  		return nil, err
   119  	}
   120  	return r.b[i:r.pos], nil
   121  }
   122  
   123  // ReadValue :
   124  func (r *Reader) ReadValue() (interface{}, error) {
   125  	typ := r.peekType()
   126  	switch typ {
   127  	case jsonString:
   128  		return r.ReadString()
   129  	case jsonNumber:
   130  		num, err := r.ReadNumber()
   131  		if err != nil {
   132  			return nil, err
   133  		}
   134  		return num.Float64()
   135  	case jsonBoolean:
   136  		return r.ReadBoolean()
   137  	case jsonNull:
   138  		if err := r.ReadNull(); err != nil {
   139  			return nil, err
   140  		}
   141  		return nil, nil
   142  	case jsonArray:
   143  		var v []interface{}
   144  		if err := r.ReadArray(func(it *Reader) error {
   145  			x, err := it.ReadValue()
   146  			if err != nil {
   147  				return err
   148  			}
   149  			v = append(v, x)
   150  			return nil
   151  		}); err != nil {
   152  			return v, err
   153  		}
   154  		return v, nil
   155  	case jsonObject:
   156  		var v map[string]interface{}
   157  		if err := r.ReadObject(func(it *Reader, k string) error {
   158  			if v == nil {
   159  				v = make(map[string]interface{})
   160  			}
   161  			x, err := it.ReadValue()
   162  			if err != nil {
   163  				return err
   164  			}
   165  			v[k] = x
   166  			return nil
   167  		}); err != nil {
   168  			return nil, err
   169  		}
   170  		return v, nil
   171  	default:
   172  		return nil, errors.New("invalid json format")
   173  	}
   174  }
   175  
   176  func (r *Reader) unreadByte() *Reader {
   177  	if r.pos > 0 {
   178  		r.pos--
   179  	}
   180  	return r
   181  }
   182  
   183  // ReadBoolean :
   184  func (r *Reader) ReadBoolean() (bool, error) {
   185  	c := r.nextToken()
   186  	r.unreadByte()
   187  	if c == 'n' {
   188  		if err := r.skipBytes([]byte{'n', 'u', 'l', 'l'}); err != nil {
   189  			return false, err
   190  		}
   191  		return false, nil
   192  	} else if c == 't' {
   193  		if err := r.skipBytes([]byte{'t', 'r', 'u', 'e'}); err != nil {
   194  			return false, err
   195  		}
   196  		return true, nil
   197  	} else if c == 'f' {
   198  		if err := r.skipBytes([]byte{'f', 'a', 'l', 's', 'e'}); err != nil {
   199  			return false, err
   200  		}
   201  		return false, nil
   202  	}
   203  	return false, errors.New("invalid boolean value")
   204  }
   205  
   206  // ReadNull :
   207  func (r *Reader) ReadNull() error {
   208  	c := r.nextToken()
   209  	if c == 'n' {
   210  		return r.skipBytes([]byte{'u', 'l', 'l'})
   211  	}
   212  	return nil
   213  }