github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/lib/stringlib/packformatreader.go (about)

     1  package stringlib
     2  
     3  import (
     4  	"encoding/binary"
     5  	"math"
     6  )
     7  
     8  type packFormatReader struct {
     9  	format       string           // Specifies the packing format
    10  	i            int              // Current index in the format string
    11  	byteOrder    binary.ByteOrder // Current byteOrder of outputting numbers
    12  	maxAlignment uint             // Current max alignment (used in pack.align())
    13  	err          error            // if non-nil, the error encountered while packing
    14  	optSize      uint             // Value of current option size
    15  	alignOnly    bool             // true after "X" option is parsed
    16  }
    17  
    18  func (p *packFormatReader) hasNext() bool {
    19  	return p.i < len(p.format)
    20  }
    21  
    22  func (p *packFormatReader) nextOption() byte {
    23  	opt := p.format[p.i]
    24  	p.i++
    25  	return opt
    26  }
    27  
    28  func (p *packFormatReader) smallOptSize(defaultSize uint) (ok bool) {
    29  	if p.getOptSize() {
    30  		if ok = p.optSize >= 1 && p.optSize <= 16; !ok {
    31  			p.err = errBadOptionArg
    32  		}
    33  		return
    34  	}
    35  	p.optSize = defaultSize
    36  	if ok = defaultSize != 0; !ok {
    37  		p.err = errMissingSize // TODO: check this condition occurs
    38  	}
    39  	return
    40  }
    41  
    42  const maxDecuplable = math.MaxUint / 10
    43  
    44  func (p *packFormatReader) getOptSize() bool {
    45  	var (
    46  		n  uint
    47  		ok = false
    48  	)
    49  	for ; p.i < len(p.format); p.i++ {
    50  		c := p.format[p.i]
    51  		if c >= '0' && c <= '9' {
    52  			ok = true
    53  			if n > maxDecuplable {
    54  				p.err = errOverflow
    55  				return false
    56  			}
    57  			cc := uint(c - '0')
    58  			n = n*10 + cc
    59  			if n < cc {
    60  				p.err = errOverflow
    61  				return false
    62  			}
    63  		} else {
    64  			break
    65  		}
    66  	}
    67  	p.optSize = n
    68  	return ok
    69  }
    70  
    71  func (p *packFormatReader) mustGetOptSize() bool {
    72  	ok := p.getOptSize()
    73  	if !ok && p.err == nil {
    74  		p.err = errMissingSize
    75  	}
    76  	return ok
    77  }