use of com.amazon.ion.Timestamp in project ion-java by amzn.
the class IonReaderBinaryRawX method readTimestamp.
/**
* @see IonBinary.Reader#readTimestampValue
*/
protected final Timestamp readTimestamp(int len) throws IOException {
if (len < 1) {
// nothing to do here - and the timestamp will be NULL
return null;
}
int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
BigDecimal frac = null;
long save_limit = NO_LIMIT;
if (_local_remaining != NO_LIMIT) {
save_limit = _local_remaining - len;
}
// > 0
_local_remaining = len;
// first up is the offset, which requires a special int reader
// to return the -0 as a null Integer
Integer offset = readVarInteger();
// now we'll read the struct values from the input stream
// year is from 0001 to 9999
// or 0x1 to 0x270F or 14 bits - 1 or 2 bytes
year = readVarUInt();
// our lowest significant option
Precision p = Precision.YEAR;
// now we look for months
if (_local_remaining > 0) {
month = readVarUInt();
p = Precision.MONTH;
// now we look for days
if (_local_remaining > 0) {
day = readVarUInt();
// our lowest significant option
p = Precision.DAY;
// now we look for hours and minutes
if (_local_remaining > 0) {
hour = readVarUInt();
minute = readVarUInt();
p = Precision.MINUTE;
if (_local_remaining > 0) {
second = readVarUInt();
p = Precision.SECOND;
if (_local_remaining > 0) {
// now we read in our actual "milliseconds since the epoch"
frac = readDecimal((int) _local_remaining);
if (frac.compareTo(BigDecimal.ZERO) < 0 || frac.compareTo(BigDecimal.ONE) >= 0) {
throwErrorAt("The fractional seconds value in a timestamp must be greater than or " + "equal to zero and less than one.");
}
}
}
}
}
}
// restore out outer limit(s)
_local_remaining = save_limit;
// now we let timestamp put it all together
try {
Timestamp val = Timestamp.createFromUtcFields(p, year, month, day, hour, minute, second, frac, offset);
return val;
} catch (IllegalArgumentException e) {
// Rewrap to the expected type.
throw newErrorAt("Invalid timestamp encoding: " + e.getMessage());
}
}
use of com.amazon.ion.Timestamp in project ion-java by amzn.
the class IonReaderBinarySystemX method load_scalar_value.
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;
}
// 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((int) _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
// keep the BigInteger value set in case the user wants to resurrect it as such
_v.addValue(big.longValue());
_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((int) _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((int) _value_len);
}
_v.setValue(d);
_v.setAuthoritativeType(AS_TYPE.double_value);
break;
case DECIMAL:
Decimal dec = readDecimal((int) _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((int) _value_len);
_v.setValue(t);
_v.setAuthoritativeType(AS_TYPE.timestamp_value);
break;
case SYMBOL:
long sid = readULong((int) _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((int) _value_len);
_v.setValue(s);
_v.setAuthoritativeType(AS_TYPE.string_value);
break;
}
_state = State.S_AFTER_VALUE;
}
use of com.amazon.ion.Timestamp in project ion-java by amzn.
the class IonReaderBinaryIncremental method timestampValue.
@Override
public Timestamp timestampValue() {
requireType(IonType.TIMESTAMP);
if (isNullValue()) {
return null;
}
peekIndex = valueStartPosition;
int firstByte = buffer.peek(peekIndex++);
Integer offset = null;
if (firstByte != VAR_INT_NEGATIVE_ZERO) {
offset = readVarInt(firstByte);
}
int year = readVarUInt();
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
BigDecimal fractionalSecond = null;
Timestamp.Precision precision = Timestamp.Precision.YEAR;
if (peekIndex < valueEndPosition) {
month = readVarUInt();
precision = Timestamp.Precision.MONTH;
if (peekIndex < valueEndPosition) {
day = readVarUInt();
precision = Timestamp.Precision.DAY;
if (peekIndex < valueEndPosition) {
hour = readVarUInt();
if (peekIndex >= valueEndPosition) {
throw new IonException("Timestamps may not specify hour without specifying minute.");
}
minute = readVarUInt();
precision = Timestamp.Precision.MINUTE;
if (peekIndex < valueEndPosition) {
second = readVarUInt();
precision = Timestamp.Precision.SECOND;
if (peekIndex < valueEndPosition) {
fractionalSecond = readBigDecimal();
if (fractionalSecond.signum() < 0 || fractionalSecond.compareTo(BigDecimal.ONE) >= 0) {
throw new IonException("The fractional seconds value in a timestamp must be greater" + "than or equal to zero and less than one.");
}
}
}
}
}
}
try {
return Timestamp.createFromUtcFields(precision, year, month, day, hour, minute, second, fractionalSecond, offset);
} catch (IllegalArgumentException e) {
throw new IonException("Illegal timestamp encoding. ", e);
}
}
use of com.amazon.ion.Timestamp in project ion-java by amzn.
the class IonReaderBinaryRawLargeStreamTest method readLargeContainer.
@Test
public void readLargeContainer() throws Exception {
final Timestamp timestamp = Timestamp.forDay(2000, 1, 1);
byte[] data = testData(timestamp);
// 32768 makes the value exceed Integer.MAX_VALUE by an arbitrary amount.
final int totalNumberOfBatches = (Integer.MAX_VALUE / data.length) + 32768;
ByteArrayOutputStream header = new ByteArrayOutputStream();
header.write(BINARY_VERSION_MARKER_1_0);
// List with length subfield.
header.write(0xBE);
// Length
IonBinary.writeVarUInt(header, (long) data.length * totalNumberOfBatches);
InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream(header.toByteArray()), // This will provide the data 'totalNumberOfBatches' times
new RepeatInputStream(data, totalNumberOfBatches - 1));
IonReader reader = IonReaderBuilder.standard().build(inputStream);
assertEquals(IonType.LIST, reader.next());
reader.stepIn();
int batchesRead = 0;
while (reader.next() != null) {
// Materializing on every iteration makes the tests take too long. Do it on every 100.
boolean materializeValues = (batchesRead % 100) == 0;
assertEquals(IonType.STRING, reader.getType());
if (materializeValues) {
assertEquals("foo", reader.stringValue());
}
assertEquals(IonType.DECIMAL, reader.next());
if (materializeValues) {
assertEquals(BigDecimal.TEN, reader.decimalValue());
}
assertEquals(IonType.TIMESTAMP, reader.next());
if (materializeValues) {
assertEquals(timestamp, reader.timestampValue());
}
batchesRead++;
}
assertNull(reader.next());
reader.stepOut();
assertNull(reader.next());
assertEquals(totalNumberOfBatches, batchesRead);
}
use of com.amazon.ion.Timestamp in project ion-java by amzn.
the class IonReaderBinaryRawLargeStreamTest method skipLargeContainer.
@Test
public void skipLargeContainer() throws Exception {
final Timestamp timestamp = Timestamp.forDay(2000, 1, 1);
byte[] data = testData(timestamp);
// 17 makes the value exceed Integer.MAX_VALUE by an arbitrary amount.
final int totalNumberOfBatches = (Integer.MAX_VALUE / data.length) + 17;
ByteArrayOutputStream header = new ByteArrayOutputStream();
header.write(BINARY_VERSION_MARKER_1_0);
// S-exp with length subfield.
header.write(0xCE);
// Length
IonBinary.writeVarUInt(header, (long) data.length * totalNumberOfBatches);
InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream(header.toByteArray()), new SequenceInputStream(// This will provide the data 'totalNumberOfBatches' times
new RepeatInputStream(data, totalNumberOfBatches - 1), // The string "bar"
new ByteArrayInputStream(new byte[] { (byte) 0x83, 'b', 'a', 'r' })));
IonReader reader = IonReaderBuilder.standard().build(inputStream);
assertEquals(IonType.SEXP, reader.next());
assertEquals(IonType.STRING, reader.next());
assertEquals("bar", reader.stringValue());
assertNull(reader.next());
}
Aggregations