/** Decodes an integer value from the given stream. */ public static int decodeInt(InputStream stream) throws IOException { long r = decodeLong(stream); if (r < 0 || r >= 1L << 32) { throw new IOException("varint overflow " + r); } return (int) r; }
@Override public Long decode(InputStream inStream) throws IOException, CoderException { try { return VarInt.decodeLong(inStream); } catch (EOFException | UTFDataFormatException exn) { // These exceptions correspond to decoding problems, so change // what kind of exception they're branded as. throw new CoderException(exn); } }
@Override public long[] decode(InputStream inStream) throws IOException, CoderException { try { return new long[] {VarInt.decodeLong(inStream)}; } catch (EOFException | UTFDataFormatException exn) { throw new CoderException(exn); } }
@Override public MultiStepAccumulator decode(InputStream inStream) throws CoderException, IOException { return MultiStepAccumulator.of(VarInt.decodeLong(inStream), true); } }
private static long decodeLong(byte[] encoded) throws IOException { ByteArrayInputStream stream = new ByteArrayInputStream(encoded); return VarInt.decodeLong(stream); }
@Override public PaneInfo decode(final InputStream inStream) throws CoderException, IOException { byte keyAndTag = (byte) inStream.read(); PaneInfo base = BYTE_TO_PANE_INFO.get((byte) (keyAndTag & 0x0F)); long index, onTimeIndex; switch (Encoding.fromTag(keyAndTag)) { case FIRST: return base; case ONE_INDEX: index = VarInt.decodeLong(inStream); onTimeIndex = base.timing == Timing.EARLY ? -1 : index; break; case TWO_INDICES: index = VarInt.decodeLong(inStream); onTimeIndex = VarInt.decodeLong(inStream); break; default: throw new CoderException("Unknown encoding " + (keyAndTag & 0xF0)); } return new PaneInfo(base.isFirst, base.isLast, base.timing, index, onTimeIndex); }
@Override public T decode(InputStream inStream) throws CoderException, IOException { long size = VarInt.decodeLong(inStream); return valueCoder.decode(ByteStreams.limit(inStream, size), Context.OUTER); }
@Override public IterableT decode(InputStream inStream) throws IOException, CoderException { DataInputStream dataInStream = new DataInputStream(inStream); int size = dataInStream.readInt(); if (size >= 0) { List<T> elements = new ArrayList<>(size); for (int i = 0; i < size; i++) { elements.add(elementCoder.decode(dataInStream)); } return decodeToIterable(elements); } List<T> elements = new ArrayList<>(); // We don't know the size a priori. Check if we're done with // each block of elements. long count = VarInt.decodeLong(dataInStream); while (count > 0L) { elements.add(elementCoder.decode(dataInStream)); --count; if (count == 0L) { count = VarInt.decodeLong(dataInStream); } } return decodeToIterable(elements); }
@Override public BoundedWindow decode(InputStream inStream) throws IOException { final Instant ts = new Instant(VarInt.decodeLong(inStream)); return new BoundedWindow() { @Override public Instant maxTimestamp() { return ts; } }; } };
@Override public T decode(InputStream inStream, Context context) throws IOException { try { if (!context.isWholeStream) { long limit = VarInt.decodeLong(inStream); inStream = ByteStreams.limit(inStream, limit); } @SuppressWarnings("unchecked") T obj = (T) jaxbUnmarshaller.get().unmarshal(new CloseIgnoringInputStream(inStream)); return obj; } catch (JAXBException e) { throw new CoderException(e); } }
private void verifyValues(List<byte[]> expectedValues, InputStream is) throws Exception { List<byte[]> values = new ArrayList<>(); long count; do { count = VarInt.decodeLong(is); for (int i = 0; i < count; ++i) { values.add(ByteArrayCoder.of().decode(is)); } } while (count > 0); if (expectedValues.isEmpty()) { assertTrue(values.isEmpty()); } else { assertThat(values, IsIterableContainingInOrder.contains(expectedValues.toArray())); } }
@Test public void decodeValues() throws IOException { assertEquals(LONG_VALUES.length, LONG_ENCODED.length); for (int i = 0; i < LONG_ENCODED.length; ++i) { ByteArrayInputStream stream = new ByteArrayInputStream(LONG_ENCODED[i]); long parsed = VarInt.decodeLong(stream); assertEquals(LONG_VALUES[i], parsed); assertEquals(-1, stream.read()); } assertEquals(INT_VALUES.length, INT_ENCODED.length); for (int i = 0; i < INT_ENCODED.length; ++i) { ByteArrayInputStream stream = new ByteArrayInputStream(INT_ENCODED[i]); int parsed = VarInt.decodeInt(stream); assertEquals(INT_VALUES[i], parsed); assertEquals(-1, stream.read()); } }
@Test public void decodeParsesEncodedValues() throws IOException { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); for (int i = 10; i < Integer.MAX_VALUE; i = (int) (i * 1.1)) { VarInt.encode(i, outStream); VarInt.encode(-i, outStream); } for (long i = 10; i < Long.MAX_VALUE; i = (long) (i * 1.1)) { VarInt.encode(i, outStream); VarInt.encode(-i, outStream); } ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); for (int i = 10; i < Integer.MAX_VALUE; i = (int) (i * 1.1)) { assertEquals(i, VarInt.decodeInt(inStream)); assertEquals(-i, VarInt.decodeInt(inStream)); } for (long i = 10; i < Long.MAX_VALUE; i = (long) (i * 1.1)) { assertEquals(i, VarInt.decodeLong(inStream)); assertEquals(-i, VarInt.decodeLong(inStream)); } }