github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/json/decode-minified.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  // DecoderMinifed store data to decode data by each method!
    15  type DecoderMinifed 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 *DecoderMinifed) Offset(o int) {
    23  	d.Buf = d.Buf[o:]
    24  }
    25  
    26  // FindEndToken find next end json token
    27  func (d *DecoderMinifed) 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  // ResetToken set d.Token to nil
    50  func (d *DecoderMinifed) ResetToken() {
    51  	d.Token = 0
    52  }
    53  
    54  // CheckToken set d.Token to nil
    55  func (d *DecoderMinifed) CheckToken(t byte) bool {
    56  	if d.Token == t {
    57  		d.ResetToken()
    58  		return true
    59  	}
    60  	return false
    61  }
    62  
    63  // DecodeKey return json key. pass d.Buf start from after {||, and receive from after :
    64  func (d *DecoderMinifed) DecodeKey() string {
    65  	d.Offset(2)
    66  	var loc = bytes.IndexByte(d.Buf, '"')
    67  	var slice []byte = d.Buf[:loc]
    68  	d.Offset(loc + 2) // +2 due to have '":' after key name end!
    69  	return convert.UnsafeByteSliceToString(slice)
    70  }
    71  
    72  // NotFoundKey call in default switch of each decode iteration
    73  func (d *DecoderMinifed) NotFoundKey() (err protocol.Error) {
    74  	d.FindEndToken()
    75  	return
    76  }
    77  
    78  // NotFoundKeyStrict call in default switch of each decode iteration in strict mode.
    79  func (d *DecoderMinifed) NotFoundKeyStrict() protocol.Error {
    80  	return ErrEncodedIncludeNotDeffiendKey
    81  }
    82  
    83  // DecodeBool convert 64bit integer number string to number. pass d.Buf start from after : and receive from after ,
    84  func (d *DecoderMinifed) DecodeBool() (b bool, err protocol.Error) {
    85  	if d.Buf[0] == 't' {
    86  		b = true
    87  		d.Offset(5) // true,
    88  	} else {
    89  		// b = false
    90  		d.Offset(6) // false,
    91  	}
    92  	return
    93  }
    94  
    95  // DecodeUInt8 convert 8bit integer number string to number. pass d.Buf start from number and receive from after ,
    96  func (d *DecoderMinifed) DecodeUInt8() (ui uint8, err protocol.Error) {
    97  	d.FindEndToken()
    98  	ui, err = convert.StringToUint8Base10(convert.UnsafeByteSliceToString(d.LastItem))
    99  	if err != nil {
   100  		err = ErrEncodedIntegerCorrupted
   101  		return
   102  	}
   103  	return
   104  }
   105  
   106  // DecodeUInt16 convert 16bit integer number string to number. pass d.Buf start from number and receive from after ,
   107  func (d *DecoderMinifed) DecodeUInt16() (ui uint16, err protocol.Error) {
   108  	d.FindEndToken()
   109  	ui, err = convert.StringToUint16Base10(convert.UnsafeByteSliceToString(d.LastItem))
   110  	if err != nil {
   111  		err = ErrEncodedIntegerCorrupted
   112  		return
   113  	}
   114  	return
   115  }
   116  
   117  // DecodeUInt32 convert 32bit integer number string to number. pass d.Buf start from number and receive from after ,
   118  func (d *DecoderMinifed) DecodeUInt32() (ui uint32, err protocol.Error) {
   119  	d.FindEndToken()
   120  	ui, err = convert.StringToUint32Base10(convert.UnsafeByteSliceToString(d.LastItem))
   121  	if err != nil {
   122  		err = ErrEncodedIntegerCorrupted
   123  		return
   124  	}
   125  	return
   126  }
   127  
   128  // DecodeUInt64 convert 64bit integer number string to number. pass d.Buf start from number and receive from after ,
   129  func (d *DecoderMinifed) DecodeUInt64() (ui uint64, err protocol.Error) {
   130  	d.FindEndToken()
   131  	ui, err = convert.StringToUint64Base10(convert.UnsafeByteSliceToString(d.LastItem))
   132  	if err != nil {
   133  		err = ErrEncodedIntegerCorrupted
   134  		return
   135  	}
   136  	return
   137  }
   138  
   139  // DecodeInt32 convert 32bit number string to number. pass d.Buf start from number and receive from after end of number
   140  func (d *DecoderUnsafe) DecodeInt32() (i int32, err protocol.Error) {
   141  	d.FindEndToken()
   142  	var goErr error
   143  	var num int64
   144  	num, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 32)
   145  	if goErr != nil {
   146  		return 0, ErrEncodedIntegerCorrupted
   147  	}
   148  	i = int32(num)
   149  	return
   150  }
   151  
   152  // DecodeInt64 convert 64bit number string to number. pass d.Buf start from number and receive from after ,
   153  func (d *DecoderMinifed) DecodeInt64() (i int64, err protocol.Error) {
   154  	d.FindEndToken()
   155  	var goErr error
   156  	i, goErr = strconv.ParseInt(convert.UnsafeByteSliceToString(d.LastItem), 10, 64)
   157  	if goErr != nil {
   158  		return 0, ErrEncodedStringCorrupted
   159  	}
   160  	return
   161  }
   162  
   163  // DecodeFloat64AsNumber convert float64 number string to float64 number. pass d.Buf start from number and receive from ,
   164  func (d *DecoderMinifed) DecodeFloat64AsNumber() (f float64, err protocol.Error) {
   165  	d.FindEndToken()
   166  	var goErr error
   167  	f, goErr = strconv.ParseFloat(convert.UnsafeByteSliceToString(d.LastItem), 64)
   168  	if goErr != nil {
   169  		return 0, ErrEncodedStringCorrupted
   170  	}
   171  	return
   172  }
   173  
   174  // DecodeString return string. pass d.Buf start from after " and receive from from after "
   175  func (d *DecoderMinifed) DecodeString() (s string) {
   176  	var loc int // Coma, Colon, bracket, ... location
   177  	loc = bytes.IndexByte(d.Buf, '"')
   178  	if loc < 0 {
   179  		// Reach last item of d.Buf!
   180  		loc = len(d.Buf) - 1
   181  	}
   182  
   183  	var slice []byte = d.Buf[:loc]
   184  	d.Offset(loc + 1)
   185  	return string(slice)
   186  }
   187  
   188  /*
   189  	Array part
   190  */
   191  
   192  // DecodeByteArrayAsBase64 convert base64 string to [n]byte
   193  func (d *DecoderMinifed) DecodeByteArrayAsBase64(array []byte) (err protocol.Error) {
   194  	d.Offset(1) // due to have " at start
   195  
   196  	var loc = bytes.IndexByte(d.Buf, '"')
   197  	if loc < 0 {
   198  		err = ErrEncodedArrayCorrupted
   199  		return
   200  	}
   201  
   202  	var goErr error
   203  	_, goErr = base64.RawStdEncoding.Decode(array, d.Buf[:loc])
   204  	if goErr != nil {
   205  		return ErrEncodedArrayCorrupted
   206  	}
   207  
   208  	d.Offset(loc + 1)
   209  	return
   210  }
   211  
   212  // DecodeByteArrayAsNumber convert number array to [n]byte
   213  func (d *DecoderMinifed) DecodeByteArrayAsNumber(array []byte) (err protocol.Error) {
   214  	var value uint8
   215  	for i := 0; i < len(array); i++ {
   216  		d.Offset(1) // due to have [ or ,
   217  		value, err = d.DecodeUInt8()
   218  		if err != nil {
   219  			err = ErrEncodedArrayCorrupted
   220  			return
   221  		}
   222  		array[i] = value
   223  	}
   224  	if d.Buf[0] != ']' {
   225  		err = ErrEncodedArrayCorrupted
   226  	}
   227  	d.Offset(1)
   228  	return
   229  }
   230  
   231  /*
   232  	Slice as Number
   233  */
   234  
   235  // DecodeByteSliceAsNumber convert number string slice to []byte. pass buf start from after [ and receive from after ]
   236  func (d *DecoderMinifed) DecodeByteSliceAsNumber() (slice []byte, err protocol.Error) {
   237  	d.Offset(1) // due to have [ at start
   238  	slice = make([]byte, 0, 8) // TODO::: Is cap efficient enough?
   239  
   240  	var num uint8
   241  	for !d.CheckToken(']') {
   242  		num, err = d.DecodeUInt8()
   243  		if err != nil {
   244  			err = ErrEncodedSliceCorrupted
   245  			return
   246  		}
   247  		slice = append(slice, num)
   248  		d.Offset(1)
   249  	}
   250  	return
   251  }
   252  
   253  // DecodeUInt16SliceAsNumber convert uint16 number string slice to []byte. pass buf start from after [ and receive from after ]
   254  func (d *DecoderMinifed) DecodeUInt16SliceAsNumber() (slice []uint16, err protocol.Error) {
   255  	d.Offset(1) // due to have [ at start
   256  	slice = make([]uint16, 0, 8) // TODO::: Is cap efficient enough?
   257  
   258  	var num uint16
   259  	for !d.CheckToken(']') {
   260  		num, err = d.DecodeUInt16()
   261  		if err != nil {
   262  			err = ErrEncodedSliceCorrupted
   263  			return
   264  		}
   265  		slice = append(slice, num)
   266  		d.Offset(1)
   267  	}
   268  	return
   269  }
   270  
   271  // DecodeUInt32SliceAsNumber convert uint32 number string slice to []byte. pass buf start from after [ and receive from after ]
   272  func (d *DecoderMinifed) DecodeUInt32SliceAsNumber() (slice []uint32, err protocol.Error) {
   273  	d.Offset(1) // due to have [ at start
   274  	slice = make([]uint32, 0, 8) // TODO::: Is cap efficient enough?
   275  
   276  	var num uint32
   277  	for !d.CheckToken(']') {
   278  		num, err = d.DecodeUInt32()
   279  		if err != nil {
   280  			err = ErrEncodedSliceCorrupted
   281  			return
   282  		}
   283  		slice = append(slice, num)
   284  		d.Offset(1)
   285  	}
   286  	return
   287  }
   288  
   289  // DecodeUInt64SliceAsNumber convert uint64 number string slice to []byte. pass buf start from after [ and receive from after ]
   290  func (d *DecoderMinifed) DecodeUInt64SliceAsNumber() (slice []uint64, err protocol.Error) {
   291  	d.Offset(1) // due to have [ at start
   292  	slice = make([]uint64, 0, 8) // TODO::: Is cap efficient enough?
   293  
   294  	var num uint64
   295  	for !d.CheckToken(']') {
   296  		num, err = d.DecodeUInt64()
   297  		if err != nil {
   298  			err = ErrEncodedSliceCorrupted
   299  			return
   300  		}
   301  		slice = append(slice, num)
   302  		d.Offset(1)
   303  	}
   304  	return
   305  }
   306  
   307  /*
   308  	Slice as Base64
   309  */
   310  
   311  // DecodeByteSliceAsBase64 convert base64 string to []byte
   312  func (d *DecoderMinifed) DecodeByteSliceAsBase64() (slice []byte, err protocol.Error) {
   313  	d.Offset(1) // due to have " at start
   314  
   315  	// Coma, Colon, bracket, ... location
   316  	var loc int = bytes.IndexByte(d.Buf, '"')
   317  	slice = make([]byte, base64.RawStdEncoding.DecodedLen(len(d.Buf[:loc])))
   318  	var n int
   319  	var goErr error
   320  	n, goErr = base64.RawStdEncoding.Decode(slice, d.Buf[:loc])
   321  	if goErr != nil {
   322  		err = ErrEncodedSliceCorrupted
   323  		return
   324  	}
   325  	slice = slice[:n]
   326  
   327  	d.Offset(loc + 1)
   328  	return
   329  }
   330  
   331  // Decode32ByteArraySliceAsBase64 decode [32]byte base64 string slice. pass buf start from after [ and receive from after ]
   332  func (d *DecoderMinifed) Decode32ByteArraySliceAsBase64() (slice [][32]byte, err protocol.Error) {
   333  	d.Offset(1) // due to have [ at start
   334  
   335  	const base64Len = 43 // base64.RawStdEncoding.EncodedLen(len(32))	>>	(32*8 + 5) / 6
   336  	slice = make([][32]byte, 0, 8)
   337  
   338  	var goErr error
   339  	var array [32]byte
   340  	for d.Buf[1] != ']' {
   341  		d.Offset(2) // due to have `["` || `",`
   342  		_, goErr = base64.RawStdEncoding.Decode(array[:], d.Buf[:base64Len])
   343  		if goErr != nil {
   344  			err = ErrEncodedSliceCorrupted
   345  			return
   346  		}
   347  		slice = append(slice, array)
   348  		d.Buf = d.Buf[base64Len:]
   349  	}
   350  
   351  	d.Offset(2) // due to have	`"]`
   352  	return
   353  }