github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/iterator_float32.go (about)

     1  package jzon
     2  
     3  import (
     4  	"io"
     5  	"strconv"
     6  )
     7  
     8  // ReadFloat32 reads a float32 value
     9  func (it *Iterator) ReadFloat32() (float32, error) {
    10  	c, err := it.nextToken()
    11  	if err != nil {
    12  		return 0, err
    13  	}
    14  	it.head++
    15  	if c == '-' {
    16  		c, err = it.nextByte()
    17  		if err != nil {
    18  			return 0, err
    19  		}
    20  		it.head++
    21  		f, buf, err := it.readPositiveFloat32(c, it.tmpBuffer[:0])
    22  		it.tmpBuffer = buf
    23  		return -f, err
    24  	}
    25  	f, buf, err := it.readPositiveFloat32(c, it.tmpBuffer[:0])
    26  	it.tmpBuffer = buf
    27  	return f, err
    28  }
    29  
    30  func (it *Iterator) parseFloat32(buf []byte) (ret float32, err error) {
    31  	f, err := strconv.ParseFloat(localByteToString(buf), 32)
    32  	return float32(f), err
    33  }
    34  
    35  func (it *Iterator) readFloat32ExponentPart(buf []byte) (ret float32, _ []byte, err error) {
    36  	c, err := it.nextByte()
    37  	if err != nil {
    38  		return 0, buf, err
    39  	}
    40  	it.head++
    41  	if c == '+' || c == '-' {
    42  		buf = append(buf, c)
    43  		c, err = it.nextByte()
    44  		if err != nil {
    45  			return 0, buf, err
    46  		}
    47  		it.head++
    48  	}
    49  	if intDigits[c] == invalidDigit {
    50  		return 0, buf, InvalidFloatError{c: c}
    51  	}
    52  	buf = append(buf, c)
    53  	for {
    54  		i := it.head
    55  		for ; i < it.tail; i++ {
    56  			c = it.buffer[i]
    57  			digit := intDigits[c]
    58  			if digit == invalidDigit {
    59  				buf = append(buf, it.buffer[it.head:i]...)
    60  				it.head = i
    61  				ret, err = it.parseFloat32(buf)
    62  				return ret, buf, err
    63  			}
    64  		}
    65  		// i == it.tail
    66  		buf = append(buf, it.buffer[it.head:i]...)
    67  		it.head = i
    68  		if err = it.readMore(); err != nil {
    69  			if err == io.EOF {
    70  				ret, err = it.parseFloat32(buf)
    71  				return ret, buf, err
    72  			}
    73  			return 0, buf, err
    74  		}
    75  	}
    76  }
    77  
    78  func (it *Iterator) readFloat32FractionPart(buf []byte) (ret float32, _ []byte, err error) {
    79  	c, err := it.nextByte()
    80  	if err != nil {
    81  		return 0, buf, err
    82  	}
    83  	if intDigits[c] == invalidDigit {
    84  		return 0, buf, InvalidFloatError{c: c}
    85  	}
    86  	it.head++
    87  	buf = append(buf, c)
    88  	for {
    89  		i := it.head
    90  		for ; i < it.tail; i++ {
    91  			c = it.buffer[i]
    92  			digit := floatDigits[c]
    93  			if digit < 0 {
    94  				switch digit {
    95  				case expInNumber:
    96  					buf = append(buf, it.buffer[it.head:i+1]...)
    97  					it.head = i + 1
    98  					return it.readFloat32ExponentPart(buf)
    99  				default:
   100  					buf = append(buf, it.buffer[it.head:i]...)
   101  					it.head = i
   102  					ret, err = it.parseFloat32(buf)
   103  					return ret, buf, err
   104  				}
   105  			}
   106  		}
   107  		// i == it.tail
   108  		buf = append(buf, it.buffer[it.head:i]...)
   109  		it.head = i
   110  		if err = it.readMore(); err != nil {
   111  			if err == io.EOF {
   112  				ret, err = it.parseFloat32(buf)
   113  				return ret, buf, err
   114  			}
   115  			return 0, buf, err
   116  		}
   117  	}
   118  }
   119  
   120  func (it *Iterator) readPositiveFloat32(c byte, buf []byte) (ret float32, _ []byte, err error) {
   121  	u := intDigits[c]
   122  	if u == invalidDigit {
   123  		return 0, buf, InvalidFloatError{c: c}
   124  	}
   125  
   126  	buf = append(buf, c)
   127  	if u == 0 {
   128  		if it.head == it.tail {
   129  			if err = it.readMore(); err != nil {
   130  				if err == io.EOF {
   131  					return 0, buf, nil
   132  				}
   133  				return 0, buf, err
   134  			}
   135  		}
   136  		switch floatDigits[it.buffer[it.head]] {
   137  		case dotInNumber:
   138  			it.head++
   139  			buf = append(buf, '.')
   140  			return it.readFloat32FractionPart(buf)
   141  		case expInNumber:
   142  			it.head++
   143  			buf = append(buf, 'e')
   144  			return it.readFloat32ExponentPart(buf)
   145  		default:
   146  			return 0, buf, nil
   147  		}
   148  	} else {
   149  		for {
   150  			i := it.head
   151  			for ; i < it.tail; i++ {
   152  				c = it.buffer[i]
   153  				digit := floatDigits[c]
   154  				if digit < 0 {
   155  					switch digit {
   156  					case dotInNumber:
   157  						buf = append(buf, it.buffer[it.head:i+1]...)
   158  						it.head = i + 1
   159  						return it.readFloat32FractionPart(buf)
   160  					case expInNumber:
   161  						buf = append(buf, it.buffer[it.head:i+1]...)
   162  						it.head = i + 1
   163  						return it.readFloat32ExponentPart(buf)
   164  					default:
   165  						buf = append(buf, it.buffer[it.head:i]...)
   166  						it.head = i
   167  						ret, err = it.parseFloat32(buf)
   168  						return ret, buf, err
   169  					}
   170  				}
   171  			}
   172  			// i == it.tail
   173  			buf = append(buf, it.buffer[it.head:i]...)
   174  			it.head = i
   175  			if err = it.readMore(); err != nil {
   176  				if err == io.EOF {
   177  					ret, err = it.parseFloat32(buf)
   178  					return ret, buf, err
   179  				}
   180  				return 0, buf, err
   181  			}
   182  		}
   183  	}
   184  }