private final void load_scalar_value()

in src/com/amazon/ion/impl/IonReaderBinarySystemX.java [148:274]


    private final void load_scalar_value() throws IOException
    {
        // make sure we're trying to load a scalar value here
        switch(_value_type) {
        case NULL:
        case BOOL:
        case INT:
        case FLOAT:
        case DECIMAL:
        case TIMESTAMP:
        case SYMBOL:
        case STRING:
            break;
        default:
            return;
        }

        // this will be true when the value_type is null as
        // well as when we encounter a null of any other type
        if (_value_is_null) {
            _v.setValueToNull(_value_type);
            _v.setAuthoritativeType(AS_TYPE.null_value);
            return;
        }

        switch (_value_type) {
        default:
            return;
        case BOOL:
            _v.setValue(_value_is_true);
            _v.setAuthoritativeType(AS_TYPE.boolean_value);
            break;
        case INT:
            boolean is_negative = _value_tid == _Private_IonConstants.tidNegInt;

            if (_value_len == 0) {
                if (is_negative) {
                    throwIllegalNegativeZeroException();
                }
                int v = 0;
                _v.setValue(v);
                _v.setAuthoritativeType(AS_TYPE.int_value);
            }
            else if (_value_len <= MAX_BINARY_LENGTH_LONG) {
                long v = readULong(_value_len);

                if (v < 0) {
                    // we probably can't fit this magnitude properly into a Java long
                    int signum = !is_negative ? 1 : -1;
                    BigInteger big = IonBinary.unsignedLongToBigInteger(signum, v);
                    _v.setValue(big);
                    // boundary condition
                    if (big.compareTo(MIN_LONG_VALUE) < 0 || big.compareTo(MAX_LONG_VALUE) > 0) {
                        _v.setAuthoritativeType(AS_TYPE.bigInteger_value);
                    } else {
                        // fits in long
                        _v.addValue(big.longValue()); // keep the BigInteger value set in case the user wants to resurrect it as such
                        _v.setAuthoritativeType(AS_TYPE.long_value);
                    }
                }
                else {
                    if (is_negative) {
                        if(v == 0) {
                            throwIllegalNegativeZeroException();
                        }
                        v = -v;
                    }
                    if (v < Integer.MIN_VALUE || v > Integer.MAX_VALUE) {
                        _v.setValue(v);
                        _v.setAuthoritativeType(AS_TYPE.long_value);
                    } else {
                        _v.setValue((int)v);
                        _v.setAuthoritativeType(AS_TYPE.int_value);
                    }
                }
            }
            else {
                BigInteger v = readBigInteger(_value_len, is_negative);
                _v.setValue(v);
                _v.setAuthoritativeType(AS_TYPE.bigInteger_value);
            }
            break;
        case FLOAT:
            double d;
            if (_value_len == 0) {
                d = 0.0;
            }
            else {
                d = readFloat(_value_len);
            }
            _v.setValue(d);
            _v.setAuthoritativeType(AS_TYPE.double_value);
            break;
        case DECIMAL:
            Decimal dec = readDecimal(_value_len);
            _v.setValue(dec);
            _v.setAuthoritativeType(AS_TYPE.decimal_value);
            break;
        case TIMESTAMP:
            // TODO: it looks like a 0 length return a null timestamp - is that right?
            Timestamp t = readTimestamp(_value_len);
            _v.setValue(t);
            _v.setAuthoritativeType(AS_TYPE.timestamp_value);
            break;
        case SYMBOL:
            long sid = readULong(_value_len);
            if (sid < 0 || sid > Integer.MAX_VALUE) {
                String message = "symbol id ["
                               + sid
                               + "] out of range "
                               + "(1-"
                               + Integer.MAX_VALUE
                               + ")";
                throwErrorAt(message);
            }
            // TODO: is treating this as an int too misleading?
            _v.setValue((int)sid);
            _v.setAuthoritativeType(AS_TYPE.int_value);
            break;
        case STRING:
            String s = readString(_value_len);
            _v.setValue(s);
            _v.setAuthoritativeType(AS_TYPE.string_value);
            break;
        }
        _state = State.S_AFTER_VALUE;
    }