github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/json/decode.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package json
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/base64"
     8  	"strconv"
     9  
    10  	"../convert"
    11  	"../protocol"
    12  )
    13  
    14  // Decoder store data to decode data by each method!
    15  type Decoder struct {
    16  	Buf      []byte
    17  	Token    byte
    18  	LastItem []byte
    19  }
    20  
    21  // Offset make d.Buf to start of given offset
    22  func (d *Decoder) Offset(o int) {
    23  	d.Buf = d.Buf[o:]
    24  }
    25  
    26  // FindEndToken find next end json token
    27  func (d *Decoder) FindEndToken() {
    28  	for i, c := range d.Buf {
    29  		switch c {
    30  		case ',':
    31  			d.Token = ','
    32  			d.LastItem = d.Buf[:i]
    33  			d.Buf = d.Buf[i:]
    34  			return
    35  		case ']':
    36  			d.Token = ']'
    37  			d.LastItem = d.Buf[:i]
    38  			d.Buf = d.Buf[i:]
    39  			return
    40  		case '}':
    41  			d.Token = '}'
    42  			d.LastItem = d.Buf[:i]
    43  			d.Buf = d.Buf[i:]
    44  			return
    45  		}
    46  	}
    47  }
    48  
    49  // TrimToDigit remove any data and set Buf to first charecter as number
    50  func (d *Decoder) TrimToDigit() {
    51  	for i, c := range d.Buf {
    52  		if '0' <= c && c <= '9' {
    53  			d.Buf = d.Buf[i:]
    54  			return
    55  		}
    56  	}
    57  }
    58  
    59  // TrimSpaces remove any spaces from Buf
    60  func (d *Decoder) TrimSpaces() {
    61  	for i, c := range d.Buf {
    62  		if c != ' ' {
    63  			d.Buf = d.Buf[i:]
    64  			return
    65  		}
    66  	}
    67  }
    68  
    69  // TrimToStringStart remove any data from Buf to first charecter after quotation mark as '"'
    70  func (d *Decoder) TrimToStringStart() {
    71  	for i, c := range d.Buf {
    72  		if c == '"' {
    73  			d.Buf = d.Buf[i+1:] // remove any byte before " due to don't need them
    74  			return
    75  		}
    76  	}
    77  }
    78  
    79  // CheckNullValue check if null exist as value. pass d.Buf start from after : and receive from from after , if null exist
    80  func (d *Decoder) CheckNullValue() (null bool) {
    81  	for i, c := range d.Buf {
    82  		switch c {
    83  		case 'n':
    84  			if bytes.Equal(d.Buf[i:i+4], []byte("null")) {
    85  				null = true
    86  			}
    87  		case '"':
    88  			return false
    89  		case ',':
    90  			return
    91  		}
    92  	}
    93  	return
    94  }
    95  
    96  // ResetToken set d.Token to nil
    97  func (d *Decoder) ResetToken() {
    98  	d.Token = 0
    99  }
   100  
   101  // CheckToken set d.Token to nil
   102  func (d *Decoder) CheckToken(t byte) bool {
   103  	if d.Token == t {
   104  		d.ResetToken()
   105  		return true
   106  	}
   107  	return false
   108  }
   109  
   110  // DecodeKey return key very safe for each decode iteration. pass d.Buf start from any where and receive from after :
   111  func (d *Decoder) DecodeKey() string {
   112  	d.TrimToStringStart()
   113  	var loc = bytes.IndexByte(d.Buf, '"')
   114  	if loc < 0 {
   115  		return ""
   116  	}
   117  
   118  	var key []byte = d.Buf[:loc]
   119  
   120  	d.Buf = d.Buf[loc+1:] // remove any byte before last " due to don't need them
   121  	loc = bytes.IndexByte(d.Buf, ':')
   122  	d.Buf = d.Buf[loc+1:]
   123  	return convert.UnsafeByteSliceToString(key)
   124  }
   125  
   126  // NotFoundKey call in default switch of each decode iteration
   127  func (d *Decoder) NotFoundKey() (err protocol.Error) {
   128  	d.FindEndToken()
   129  	return
   130  }
   131  
   132  // NotFoundKeyStrict call in default switch of each decode iteration in strict mode.
   133  func (d *Decoder) NotFoundKeyStrict() protocol.Error {
   134  	return ErrEncodedIncludeNotDeffiendKey
   135  }
   136  
   137  // DecodeBool convert string base boolean to bool. pass d.Buf start from after : and receive from after ,
   138  func (d *Decoder) DecodeBool() (b bool, err protocol.Error) {
   139  	d.TrimSpaces()
   140  	if d.Buf[0] == 't' {
   141  		b = true
   142  		d.Offset(5) // true,
   143  	} else {
   144  		// b = false
   145  		d.Offset(6) // false,
   146  	}
   147  	return
   148  }
   149  
   150  // DecodeUInt8 convert 8bit integer number string to number. pass d.Buf start from number and receive from after ,
   151  func (d *Decoder) DecodeUInt8() (ui uint8, err protocol.Error) {
   152  	d.TrimToDigit()
   153  	d.FindEndToken()
   154  	ui, err = convert.StringToUint8Base10(convert.UnsafeByteSliceToString(d.LastItem))
   155  	if err != nil {
   156  		err = ErrEncodedIntegerCorrupted
   157  		return
   158  	}
   159  	return
   160  }
   161  
   162  // DecodeUInt16 convert 16bit integer number string to number. pass d.Buf start from number and receive from after ,
   163  func (d *Decoder) DecodeUInt16() (ui uint16, err protocol.Error) {
   164  	d.TrimToDigit()
   165  	d.FindEndToken()
   166  	ui, err = convert.StringToUint16Base10(convert.UnsafeByteSliceToString(d.LastItem))
   167  	if err != nil {
   168  		err = ErrEncodedIntegerCorrupted
   169  		return
   170  	}
   171  	return
   172  }
   173  
   174  // DecodeUInt32 convert 32bit integer number string to number. pass d.Buf start from number and receive from after ,
   175  func (d *Decoder) DecodeUInt32() (ui uint32, err protocol.Error) {
   176  	d.TrimToDigit()
   177  	d.FindEndToken()
   178  	ui, err = convert.StringToUint32Base10(convert.UnsafeByteSliceToString(d.LastItem))
   179  	if err != nil {
   180  		err = ErrEncodedIntegerCorrupted
   181  		return
   182  	}
   183  	return
   184  }
   185  
   186  // DecodeUInt64 convert 64bit integer number string to number. pass d.Buf start from after : and receive from after ,
   187  func (d *Decoder) DecodeUInt64() (ui uint64, err protocol.Error) {
   188  	d.TrimToDigit()
   189  	d.FindEndToken()
   190  	ui, err = convert.StringToUint64Base10(convert.UnsafeByteSliceToString(d.LastItem))
   191  	if err != nil {
   192  		err = ErrEncodedIntegerCorrupted
   193  		return
   194  	}
   195  	return
   196  }
   197  
   198  // DecodeInt64 convert 64bit number string to number. pass d.Buf start from number and receive from after ,
   199  func (d *Decoder) DecodeInt64() (i int64, err protocol.Error) {
   200  	d.TrimToDigit()
   201  	d.FindEndToken()
   202  	var goErr error
   203  	i, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 64)
   204  	if goErr != nil {
   205  		return 0, ErrEncodedIntegerCorrupted
   206  	}
   207  	return
   208  }
   209  
   210  // DecodeFloat64AsNumber convert float64 number string to float64 number. pass d.Buf start from after : and receive from ,
   211  func (d *Decoder) DecodeFloat64AsNumber() (f float64, err protocol.Error) {
   212  	d.TrimToDigit()
   213  	d.FindEndToken()
   214  	var goErr error
   215  	f, goErr = strconv.ParseFloat(convert.UnsafeByteSliceToString(d.LastItem), 64)
   216  	if goErr != nil {
   217  		return 0, ErrEncodedIntegerCorrupted
   218  	}
   219  	return
   220  }
   221  
   222  // DecodeString return string. pass d.Buf start from after : and receive from from after "
   223  func (d *Decoder) DecodeString() (s string, err protocol.Error) {
   224  	if d.CheckNullValue() {
   225  		return
   226  	}
   227  
   228  	d.TrimToStringStart()
   229  	var loc = bytes.IndexByte(d.Buf, '"')
   230  	if loc < 0 {
   231  		err = ErrEncodedStringCorrupted
   232  		return
   233  	}
   234  
   235  	var slice []byte = d.Buf[:loc]
   236  
   237  	d.Offset(loc + 1)
   238  	s = string(slice)
   239  	return
   240  }
   241  
   242  /*
   243  	Array part
   244  */
   245  
   246  // DecodeByteArrayAsBase64 convert base64 string to [n]byte
   247  func (d *Decoder) DecodeByteArrayAsBase64(array []byte) (err protocol.Error) {
   248  	if d.CheckNullValue() {
   249  		return
   250  	}
   251  
   252  	d.TrimToStringStart()
   253  	var loc = bytes.IndexByte(d.Buf, '"')
   254  	if loc < 0 {
   255  		err = ErrEncodedArrayCorrupted
   256  		return
   257  	}
   258  
   259  	var goErr error
   260  	_, goErr = base64.RawStdEncoding.Decode(array, d.Buf[:loc])
   261  	if goErr != nil {
   262  		return ErrEncodedArrayCorrupted
   263  	}
   264  
   265  	d.FindEndToken()
   266  	return
   267  }
   268  
   269  // DecodeByteArrayAsNumber convert number array to [n]byte
   270  func (d *Decoder) DecodeByteArrayAsNumber(array []byte) (err protocol.Error) {
   271  	if d.CheckNullValue() {
   272  		return
   273  	}
   274  
   275  	var value uint8
   276  	for i := 0; i < len(array); i++ {
   277  		value, err = d.DecodeUInt8()
   278  		if err != nil {
   279  			err = ErrEncodedArrayCorrupted
   280  			return
   281  		}
   282  		array[i] = value
   283  		d.FindEndToken()
   284  	}
   285  	if d.Token != ']' {
   286  		err = ErrEncodedArrayCorrupted
   287  	}
   288  	return
   289  }
   290  
   291  /*
   292  	Slice as Number
   293  */
   294  
   295  // DecodeByteSliceAsNumber convert number string slice to []byte. pass buf start from after [ and receive from after ]
   296  func (d *Decoder) DecodeByteSliceAsNumber() (slice []byte, err protocol.Error) {
   297  	slice = make([]byte, 0, 8) // TODO::: Is cap efficient enough?
   298  
   299  	var num uint8
   300  	for !d.CheckToken(']') {
   301  		num, err = d.DecodeUInt8()
   302  		if err != nil {
   303  			err = ErrEncodedSliceCorrupted
   304  			return
   305  		}
   306  		slice = append(slice, num)
   307  
   308  		d.FindEndToken()
   309  	}
   310  	return
   311  }
   312  
   313  // DecodeUInt16SliceAsNumber convert uint16 number string slice to []byte. pass buf start from after [ and receive from after ]
   314  func (d *Decoder) DecodeUInt16SliceAsNumber() (slice []uint16, err protocol.Error) {
   315  	slice = make([]uint16, 0, 8) // TODO::: Is cap efficient enough?
   316  
   317  	var num uint16
   318  	for !d.CheckToken(']') {
   319  		num, err = d.DecodeUInt16()
   320  		if err != nil {
   321  			err = ErrEncodedSliceCorrupted
   322  			return
   323  		}
   324  		slice = append(slice, num)
   325  
   326  		d.FindEndToken()
   327  	}
   328  	return
   329  }
   330  
   331  // DecodeUInt32SliceAsNumber convert uint32 number string slice to []byte. pass buf start from after [ and receive from after ]
   332  func (d *Decoder) DecodeUInt32SliceAsNumber() (slice []uint32, err protocol.Error) {
   333  	slice = make([]uint32, 0, 8) // TODO::: Is cap efficient enough?
   334  
   335  	var num uint32
   336  	for !d.CheckToken(']') {
   337  		num, err = d.DecodeUInt32()
   338  		if err != nil {
   339  			err = ErrEncodedSliceCorrupted
   340  			return
   341  		}
   342  		slice = append(slice, num)
   343  
   344  		d.FindEndToken()
   345  	}
   346  	return
   347  }
   348  
   349  // DecodeUInt64SliceAsNumber convert uint64 number string slice to []byte. pass buf start from after [ and receive from after ]
   350  func (d *Decoder) DecodeUInt64SliceAsNumber() (slice []uint64, err protocol.Error) {
   351  	slice = make([]uint64, 0, 8) // TODO::: Is cap efficient enough?
   352  
   353  	var num uint64
   354  	for !d.CheckToken(']') {
   355  		num, err = d.DecodeUInt64()
   356  		if err != nil {
   357  			err = ErrEncodedSliceCorrupted
   358  			return
   359  		}
   360  		slice = append(slice, num)
   361  
   362  		d.FindEndToken()
   363  	}
   364  	return
   365  }
   366  
   367  /*
   368  	Slice as Base64
   369  */
   370  
   371  // DecodeByteSliceAsBase64 convert base64 string to []byte
   372  func (d *Decoder) DecodeByteSliceAsBase64() (slice []byte, err protocol.Error) {
   373  	d.TrimToStringStart()
   374  	var loc = bytes.IndexByte(d.Buf, '"')
   375  	if loc < 0 {
   376  		err = ErrEncodedSliceCorrupted
   377  		return
   378  	}
   379  
   380  	slice = make([]byte, base64.RawStdEncoding.DecodedLen(len(d.Buf[:loc])))
   381  	var n int
   382  	var goErr error
   383  	n, goErr = base64.RawStdEncoding.Decode(slice, d.Buf[:loc])
   384  	if goErr != nil {
   385  		return slice, ErrEncodedSliceCorrupted
   386  	}
   387  	slice = slice[:n]
   388  
   389  	d.FindEndToken()
   390  	return
   391  }
   392  
   393  // Decode32ByteArraySliceAsBase64 decode [32]byte base64 string slice. pass buf start from after [ and receive from after ]
   394  func (d *Decoder) Decode32ByteArraySliceAsBase64() (slice [][32]byte, err protocol.Error) {
   395  	const base64Len = 43 // base64.RawStdEncoding.EncodedLen(len(32))	>>	(32*8 + 5) / 6
   396  	slice = make([][32]byte, 0, 8)
   397  
   398  	var openBracketLoc = bytes.IndexByte(d.Buf, '[')
   399  	if openBracketLoc < 0 {
   400  		err = ErrEncodedSliceCorrupted
   401  		return
   402  	}
   403  	d.Buf = d.Buf[openBracketLoc+1:]
   404  	var goErr error
   405  	var array [32]byte
   406  	for !d.CheckToken(']') {
   407  		d.TrimToStringStart()
   408  		_, goErr = base64.RawStdEncoding.Decode(array[:], d.Buf[:base64Len])
   409  		if goErr != nil {
   410  			err = ErrEncodedSliceCorrupted
   411  			return
   412  		}
   413  		slice = append(slice, array)
   414  		d.Buf = d.Buf[base64Len:]
   415  		d.FindEndToken()
   416  	}
   417  	return
   418  }