/**
  * Method that will parse actual numeric value out of a syntactically valid number value. Type it
  * will parse into depends on whether it is a floating point number, as well as its magnitude:
  * smallest legal type (of ones available) is used for efficiency.
  *
  * @param expType Numeric type that we will immediately need, if any; mostly necessary to optimize
  *     handling of floating point numbers
  */
 protected void _parseNumericValue(int expType) throws IOException, JsonParseException {
   // Int or float?
   if (_currToken == JsonToken.VALUE_NUMBER_INT) {
     char[] buf = _textBuffer.getTextBuffer();
     int offset = _textBuffer.getTextOffset();
     int len = _intLength;
     if (_numberNegative) {
       ++offset;
     }
     if (len <= 9) { // definitely fits in int
       int i = NumberInput.parseInt(buf, offset, len);
       _numberInt = _numberNegative ? -i : i;
       _numTypesValid = NR_INT;
       return;
     }
     if (len <= 18) { // definitely fits AND is easy to parse using 2 int parse calls
       long l = NumberInput.parseLong(buf, offset, len);
       if (_numberNegative) {
         l = -l;
       }
       // [JACKSON-230] Could still fit in int, need to check
       if (len == 10) {
         if (_numberNegative) {
           if (l >= MIN_INT_L) {
             _numberInt = (int) l;
             _numTypesValid = NR_INT;
             return;
           }
         } else {
           if (l <= MAX_INT_L) {
             _numberInt = (int) l;
             _numTypesValid = NR_INT;
             return;
           }
         }
       }
       _numberLong = l;
       _numTypesValid = NR_LONG;
       return;
     }
     _parseSlowIntValue(expType, buf, offset, len);
     return;
   }
   if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
     _parseSlowFloatValue(expType);
     return;
   }
   _reportError(
       "Current token (" + _currToken + ") not numeric, can not use numeric value accessors");
 }
 /**
  * Method called to release internal buffers owned by the base reader. This may be called along
  * with {@link #_closeInput} (for example, when explicitly closing this reader instance), or
  * separately (if need be).
  */
 protected void _releaseBuffers() throws IOException {
   _textBuffer.releaseBuffers();
   char[] buf = _nameCopyBuffer;
   if (buf != null) {
     _nameCopyBuffer = null;
     _ioContext.releaseNameCopyBuffer(buf);
   }
 }
 private final void _parseSlowFloatValue(int expType) throws IOException, JsonParseException {
   /* Nope: floating point. Here we need to be careful to get
    * optimal parsing strategy: choice is between accurate but
    * slow (BigDecimal) and lossy but fast (Double). For now
    * let's only use BD when explicitly requested -- it can
    * still be constructed correctly at any point since we do
    * retain textual representation
    */
   try {
     if (expType == NR_BIGDECIMAL) {
       _numberBigDecimal = _textBuffer.contentsAsDecimal();
       _numTypesValid = NR_BIGDECIMAL;
     } else {
       // Otherwise double has to do
       _numberDouble = _textBuffer.contentsAsDouble();
       _numTypesValid = NR_DOUBLE;
     }
   } catch (NumberFormatException nex) {
     // Can this ever occur? Due to overflow, maybe?
     _wrapError("Malformed numeric value '" + _textBuffer.contentsAsString() + "'", nex);
   }
 }
 private final void _parseSlowIntValue(int expType, char[] buf, int offset, int len)
     throws IOException, JsonParseException {
   String numStr = _textBuffer.contentsAsString();
   try {
     // [JACKSON-230] Some long cases still...
     if (NumberInput.inLongRange(buf, offset, len, _numberNegative)) {
       // Probably faster to construct a String, call parse, than to use BigInteger
       _numberLong = Long.parseLong(numStr);
       _numTypesValid = NR_LONG;
     } else {
       // nope, need the heavy guns... (rare case)
       _numberBigInt = new BigInteger(numStr);
       _numTypesValid = NR_BIGINT;
     }
   } catch (NumberFormatException nex) {
     // Can this ever occur? Due to overflow, maybe?
     _wrapError("Malformed numeric value '" + numStr + "'", nex);
   }
 }
 protected final JsonToken resetAsNaN(String valueStr, double value) {
   _textBuffer.resetWithString(valueStr);
   _numberDouble = value;
   _numTypesValid = NR_DOUBLE;
   return JsonToken.VALUE_NUMBER_FLOAT;
 }