@Override public boolean hasNext() { // hasNext can return true when position == length in the case of a // nullable field trailing a struct. return idx < types.length && src.getPosition() <= src.getLength(); }
@Override public int skip(PositionedByteRange src) { int skipped = src.getRemaining(); src.setPosition(src.getLength()); return skipped; }
@Override public int skip(PositionedByteRange src) { int skipped = src.getRemaining(); src.setPosition(src.getLength()); return skipped; }
/** * Return the position at which {@code term} begins within {@code src}, * or {@code -1} if {@code term} is not found. */ protected int terminatorPosition(PositionedByteRange src) { byte[] a = src.getBytes(); final int offset = src.getOffset(); int i; SKIP: for (i = src.getPosition(); i < src.getLength(); i++) { if (a[offset + i] != term[0]) { continue; } int j; for (j = 1; j < term.length && offset + j < src.getLength(); j++) { if (a[offset + i + j] != term[j]) { continue SKIP; } } if (j == term.length) { return i; // success } } return -1; }
@Override public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } DataType<?> t = types[idx++]; if (src.getPosition() == src.getLength() && t.isNullable()) { return null; } return t.decode(src); }
/** * Bypass the next encoded value. * @return the number of bytes skipped. */ public int skip() { if (!hasNext()) { throw new NoSuchElementException(); } DataType<?> t = types[idx++]; if (src.getPosition() == src.getLength() && t.isNullable()) { return 0; } return t.skip(src); } }
@Override public int encode(PositionedByteRange dst, T val) { if (dst.getRemaining() < length) { throw new IllegalArgumentException("Not enough buffer remaining. dst.offset: " + dst.getOffset() + " dst.length: " + dst.getLength() + " dst.position: " + dst.getPosition() + " max length: " + length); } int written = base.encode(dst, val); if (written > length) { throw new IllegalArgumentException("Length of encoded value (" + written + ") exceeds max length (" + length + ")."); } // TODO: is the zero-padding appropriate? for (; written < length; written++) { dst.put((byte) 0x00); } return written; } }
@Override public String decode(PositionedByteRange src) { if (Order.ASCENDING == this.order) { // avoid unnecessary array copy for ASC case. String val = Bytes.toString(src.getBytes(), src.getOffset() + src.getPosition(), src.getRemaining()); src.setPosition(src.getLength()); return val; } else { byte[] b = new byte[src.getRemaining()]; src.get(b); order.apply(b, 0, b.length); return Bytes.toString(b); } }
@Override public T decode(PositionedByteRange src) { if (src.getRemaining() < length) { throw new IllegalArgumentException("Not enough buffer remaining. src.offset: " + src.getOffset() + " src.length: " + src.getLength() + " src.position: " + src.getPosition() + " max length: " + length); } // create a copy range limited to length bytes. boo. PositionedByteRange b = new SimplePositionedMutableByteRange(length); src.get(b.getBytes()); return base.decode(b); }
@Override public int skip(PositionedByteRange src) { CellProtos.Cell.Builder builder = CellProtos.Cell.newBuilder(); CodedInputStream is = inputStreamFromByteRange(src); is.setSizeLimit(src.getLength()); try { builder.mergeFrom(is); int consumed = is.getTotalBytesRead(); src.setPosition(src.getPosition() + consumed); return consumed; } catch (IOException e) { throw new RuntimeException("Error while skipping type.", e); } }
@Override public CellProtos.Cell decode(PositionedByteRange src) { CellProtos.Cell.Builder builder = CellProtos.Cell.newBuilder(); CodedInputStream is = inputStreamFromByteRange(src); is.setSizeLimit(src.getLength()); try { CellProtos.Cell ret = builder.mergeFrom(is).build(); src.setPosition(src.getPosition() + is.getTotalBytesRead()); return ret; } catch (IOException e) { throw new RuntimeException("Error while decoding type.", e); } }
/** * Return the number of encoded entries remaining in {@code buff}. The * state of {@code buff} is not modified through use of this method. */ public static int length(PositionedByteRange buff) { PositionedByteRange b = new SimplePositionedMutableByteRange(buff.getBytes(), buff.getOffset(), buff.getLength()); b.setPosition(buff.getPosition()); int cnt = 0; for (; isEncodedValue(b); skip(b), cnt++) ; return cnt; } }
@Test public void testReadWrite() { for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) { RawString type = Order.ASCENDING == ord ? RawString.ASCENDING : RawString.DESCENDING; for (String val : VALUES) { PositionedByteRange buff = new SimplePositionedMutableByteRange(Bytes.toBytes(val).length); assertEquals(buff.getLength(), type.encode(buff, val)); byte[] expected = Bytes.toBytes(val); ord.apply(expected); assertArrayEquals(expected, buff.getBytes()); buff.setPosition(0); assertEquals(val, type.decode(buff)); buff.setPosition(0); assertEquals(buff.getLength(), type.skip(buff)); assertEquals(buff.getLength(), buff.getPosition()); } } } }
9, OrderedBytes.encodeFloat64(buf1, vals[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", 9, buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);
5, OrderedBytes.encodeInt32(buf1, vals[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", 5, buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);
2, OrderedBytes.encodeInt8(buf1, vals[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", 2, buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);
3, OrderedBytes.encodeInt16(buf1, vals[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", 3, buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);
9, OrderedBytes.encodeInt64(buf1, vals[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", 9, buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);
assert ret.getPosition() == ret.getLength() : "Allocated unnecessarily large return buffer."; return ret.getBytes();
BD_LENGTHS[i], OrderedBytes.encodeNumeric(buf1, BD_VALS[i], ord)); assertEquals("Broken test: serialization did not consume entire buffer.", buf1.getLength(), buf1.getPosition()); assertEquals("Surprising serialized length.", BD_LENGTHS[i], buf1.getPosition() - 1); assertEquals("Buffer underflow.", 0, a[0]);