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 }