@Test
  public void testConverMarshallableToTextName() {

    TestMarshallable testMarshallable = new TestMarshallable();
    testMarshallable.setName("hello world");

    Bytes<ByteBuffer> byteBufferBytes = Bytes.elasticByteBuffer();

    ByteBuffer byteBuffer = byteBufferBytes.underlyingObject();
    System.out.println(byteBuffer.getClass());

    Wire textWire = new TextWire(byteBufferBytes);
    textWire.bytes().readPosition();

    textWire.writeDocument(false, d -> d.write(() -> "any-key").marshallable(testMarshallable));

    String value = Wires.fromSizePrefixedBlobs(textWire.bytes());

    // String replace = value.replace("\n", "\\n");

    System.out.println(byteBufferBytes.toHexString());
    System.out.println(value);

    //  Assert.assertTrue(replace.length() > 1);
  }
 @Test
 public void testBytes() {
   Wire wire = createWire();
   byte[] allBytes = new byte[256];
   for (int i = 0; i < 256; i++) allBytes[i] = (byte) i;
   wire.write()
       .bytes(NoBytesStore.NO_BYTES)
       .write()
       .bytes(Bytes.wrap("Hello".getBytes()))
       .write()
       .bytes(Bytes.wrap("quotable, text".getBytes()))
       .write()
       .bytes(allBytes);
   System.out.println(bytes.toDebugString());
   NativeBytes allBytes2 = nativeBytes();
   wire.read()
       .bytes(wi -> assertEquals(0, wi.bytes().readRemaining()))
       .read()
       .bytes(wi -> assertEquals("Hello", wi.bytes().toString()))
       .read()
       .bytes(wi -> assertEquals("quotable, text", wi.bytes().toString()))
       .read()
       .bytes(allBytes2);
   assertEquals(Bytes.wrap(allBytes), allBytes2);
 }
 @Override
 public boolean equals(Object obj) {
   if (!(obj instanceof Bytes)) return false;
   Bytes b2 = (Bytes) obj;
   long remaining = readRemaining();
   return b2.readRemaining() == remaining && equalsBytes(b2, remaining);
 }
 public UncheckedNativeBytes(@NotNull Bytes<Underlying> underlyingBytes)
     throws IllegalStateException {
   underlyingBytes.reserve();
   this.bytesStore = (NativeBytesStore<Underlying>) underlyingBytes.bytesStore();
   assert bytesStore.start() == 0;
   writePosition = underlyingBytes.writePosition();
   writeLimit = underlyingBytes.writeLimit();
   readPosition = underlyingBytes.readPosition();
   capacity = bytesStore.capacity();
 }
  @NotNull
  @Override
  public CharSequence read(Bytes bytes, @Nullable CharSequence ignored) {
    long size = bytes.readStopBit();
    if (size == NULL_LENGTH) return null;
    if (size < 0 || size > Integer.MAX_VALUE)
      throw new IllegalStateException("Invalid length: " + size);
    if (size == 0) return "";

    char[] chars = new char[(int) size];
    int length = bytes.readInt();
    long limit = bytes.readLimit();
    try {
      bytes.readLimit(bytes.readPosition() + length);
      DataInputStream dis =
          new DataInputStream(
              new BufferedInputStream(new InflaterInputStream(bytes.inputStream())));
      for (int i = 0; i < size; i++) chars[i] = (char) (dis.readByte() & 0xff);

    } catch (IOException e) {
      throw new IORuntimeException(e);
    } finally {
      bytes.readPosition(bytes.readLimit());
      bytes.readLimit(limit);
    }
    try {
      return STRING_FACTORY.fromChars(chars);
    } catch (Exception e) {
      throw new AssertionError(e);
    }
  }
 public boolean equalsBytes(@NotNull Bytes b2, long remaining) {
   long i = 0;
   try {
     for (; i < remaining - 7; i++)
       if (readLong(readPosition() + i) != b2.readLong(b2.readPosition() + i)) return false;
     for (; i < remaining; i++)
       if (readByte(readPosition() + i) != b2.readByte(b2.readPosition() + i)) return false;
   } catch (BufferUnderflowException | IORuntimeException e) {
     throw Jvm.rethrow(e);
   }
   return true;
 }
 @Override
 public void write(Bytes out, @NotNull A toWrite) {
   out.writeUtf8(toWrite.str_);
   if (toWrite.list_ != null) {
     int size = toWrite.list_.size();
     out.writeStopBit(size);
     for (int i = 0; i < size; i++) {
       toWrite.list_.get(i).writeMarshallable(out);
     }
   } else {
     out.writeStopBit(-1);
   }
 }
  @Override
  public void write(Bytes out, @NotNull CharSequence s) {
    if (s == null) {
      out.writeStopBit(NULL_LENGTH);
      return;
    } else if (s.length() == 0) {
      out.writeStopBit(0);
      return;
    }
    // write the total length.
    int length = s.length();
    out.writeStopBit(length);

    long position = out.writePosition();
    out.writeInt(0);
    DataOutputStream dos =
        new DataOutputStream(
            new BufferedOutputStream(new DeflaterOutputStream(out.outputStream())));
    try {
      for (int i = 0; i < s.length(); i++) {
        dos.write(s.charAt(i));
      }
      dos.close();
    } catch (IOException e) {
      throw new IORuntimeException(e);
    }
    out.writeInt(position, (int) (out.writePosition() - position - 4));
  }
  @Test
  public void uint16() {
    Wire wire = createWire();
    wire.write().uint16(1);
    wire.write(BWKey.field1).uint16(2);
    wire.write(() -> "Test").uint16(3);
    checkWire(
        wire,
        "[pos: 0, rlim: 16, wlim: 8EiB, cap: 8EiB ] À⒈Æfield1⒉ÄTest⒊",
        "[pos: 0, rlim: 22, wlim: 8EiB, cap: 8EiB ] À¢⒈٠Æfield1¢⒉٠ÄTest¢⒊٠",
        "[pos: 0, rlim: 11, wlim: 8EiB, cap: 8EiB ] À⒈º⒈⒉º²ñ\\u009E⒈⒊",
        "[pos: 0, rlim: 17, wlim: 8EiB, cap: 8EiB ] À¢⒈٠º⒈¢⒉٠º²ñ\\u009E⒈¢⒊٠",
        "[pos: 0, rlim: 3, wlim: 8EiB, cap: 8EiB ] ⒈⒉⒊",
        "[pos: 0, rlim: 9, wlim: 8EiB, cap: 8EiB ] ¢⒈٠¢⒉٠¢⒊٠");
    checkAsText123(wire);

    // ok as blank matches anything
    AtomicInteger i = new AtomicInteger();
    IntStream.rangeClosed(1, 3)
        .forEach(
            e -> {
              wire.read().uint16(i::set);
              assertEquals(e, i.get());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
  @Test
  public void int64() {
    Wire wire = createWire();
    wire.write().int64(1);
    wire.write(BWKey.field1).int64(2);
    wire.write(() -> "Test").int64(3);
    checkWire(
        wire,
        "[pos: 0, rlim: 16, wlim: 8EiB, cap: 8EiB ] À⒈Æfield1⒉ÄTest⒊",
        "[pos: 0, rlim: 40, wlim: 8EiB, cap: 8EiB ] À§⒈٠٠٠٠٠٠٠Æfield1§⒉٠٠٠٠٠٠٠ÄTest§⒊٠٠٠٠٠٠٠",
        "[pos: 0, rlim: 11, wlim: 8EiB, cap: 8EiB ] À⒈º⒈⒉º²ñ\\u009E⒈⒊",
        "[pos: 0, rlim: 35, wlim: 8EiB, cap: 8EiB ] À§⒈٠٠٠٠٠٠٠º⒈§⒉٠٠٠٠٠٠٠º²ñ\\u009E⒈§⒊٠٠٠٠٠٠٠",
        "[pos: 0, rlim: 3, wlim: 8EiB, cap: 8EiB ] ⒈⒉⒊",
        "[pos: 0, rlim: 27, wlim: 8EiB, cap: 8EiB ] §⒈٠٠٠٠٠٠٠§⒉٠٠٠٠٠٠٠§⒊٠٠٠٠٠٠٠");
    checkAsText123(wire);

    // ok as blank matches anything
    AtomicLong i = new AtomicLong();
    LongStream.rangeClosed(1, 3)
        .forEach(
            e -> {
              wire.read().int64(i::set);
              assertEquals(e, i.get());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
  @Test
  public void int8() {
    Wire wire = createWire();
    wire.write().int8((byte) 1);
    wire.write(BWKey.field1).int8((byte) 2);
    wire.write(() -> "Test").int8((byte) 3);
    checkWire(
        wire,
        "[pos: 0, rlim: 16, wlim: 8EiB, cap: 8EiB ] À⒈Æfield1⒉ÄTest⒊",
        "[pos: 0, rlim: 19, wlim: 8EiB, cap: 8EiB ] À¤⒈Æfield1¤⒉ÄTest¤⒊",
        "[pos: 0, rlim: 11, wlim: 8EiB, cap: 8EiB ] À⒈º⒈⒉º²ñ\\u009E⒈⒊",
        "[pos: 0, rlim: 14, wlim: 8EiB, cap: 8EiB ] À¤⒈º⒈¤⒉º²ñ\\u009E⒈¤⒊",
        "[pos: 0, rlim: 3, wlim: 8EiB, cap: 8EiB ] ⒈⒉⒊",
        "[pos: 0, rlim: 6, wlim: 8EiB, cap: 8EiB ] ¤⒈¤⒉¤⒊");
    checkAsText123(wire);

    // ok as blank matches anything
    AtomicInteger i = new AtomicInteger();
    IntStream.rangeClosed(1, 3)
        .forEach(
            e -> {
              wire.read().int8(i::set);
              assertEquals(e, i.get());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
 @Test
 public void testCreateReadAnyFirstFIELDLESS_BINARYWire() throws Exception {
   final Bytes<ByteBuffer> bytes = Bytes.elasticByteBuffer();
   final String expected = "world";
   FIELDLESS_BINARY.apply(bytes).write((() -> "hello")).text(expected);
   Assert.assertEquals(expected, READ_ANY.apply(bytes).read((() -> "hello")).text());
 }
 @Test
 public void testReadAny() throws Exception {
   final Bytes<ByteBuffer> t = Bytes.elasticByteBuffer();
   final Wire wire = TEXT.apply(t);
   wire.write((() -> "hello")).text("world");
   Assert.assertEquals("world", READ_ANY.apply(t).read(() -> "hello").text());
 }
  @Nullable
  public <T> T test(Object source, @NotNull Class<T> destinationType) {

    final BinaryWire wire = new BinaryWire(Bytes.elasticByteBuffer());

    if (source instanceof String) wire.writeValue().text((String) source);
    else if (source instanceof Long) wire.writeValue().int64((Long) source);
    else if (source instanceof Integer) wire.writeValue().int32((Integer) source);
    else if (source instanceof Short) wire.writeValue().int16((Short) source);
    else if (source instanceof Byte) wire.writeValue().int8((Byte) source);
    else if (source instanceof Float) wire.writeValue().float32((Float) source);
    else if (source instanceof Double) wire.writeValue().float64((Double) source);

    if (String.class.isAssignableFrom(destinationType)) return (T) wire.getValueIn().text();

    if (Long.class.isAssignableFrom(destinationType)) return (T) (Long) wire.getValueIn().int64();

    if (Integer.class.isAssignableFrom(destinationType))
      return (T) (Integer) wire.getValueIn().int32();

    if (Short.class.isAssignableFrom(destinationType)) return (T) (Short) wire.getValueIn().int16();

    if (Byte.class.isAssignableFrom(destinationType)) return (T) (Byte) wire.getValueIn().int8();

    if (Float.class.isAssignableFrom(destinationType))
      return (T) (Float) wire.getValueIn().float32();

    if (Double.class.isAssignableFrom(destinationType))
      return (T) (Double) wire.getValueIn().float64();

    throw new UnsupportedOperationException("");
  }
  @Test
  public void testRead2() {
    Wire wire = createWire();
    wire.write();
    wire.write(BWKey.field1);
    String name1 = "Long field name which is more than 32 characters, Bye";
    wire.write(() -> name1);

    // ok as blank matches anything
    StringBuilder name = new StringBuilder();
    wire.read(name);
    assertEquals(0, name.length());

    name.setLength(0);
    wire.read(name);
    assertEquals(numericField ? "1" : fieldLess ? "" : BWKey.field1.name(), name.toString());

    name.setLength(0);
    wire.read(name);
    assertEquals(numericField ? "-1019176629" : fieldLess ? "" : name1, name.toString());

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
  @Test
  public void text() {
    String name = "Long field name which is more than 32 characters, Bye";

    Wire wire = createWire();
    wire.write().text("Hello");
    wire.write(BWKey.field1).text("world");
    wire.write(() -> "Test").text(name);
    checkWire(
        wire,
        "[pos: 0, rlim: 80, wlim: 8EiB, cap: 8EiB ] ÀåHelloÆfield1åworldÄTest¸5" + name,
        "[pos: 0, rlim: 80, wlim: 8EiB, cap: 8EiB ] ÀåHelloÆfield1åworldÄTest¸5" + name,
        "[pos: 0, rlim: 75, wlim: 8EiB, cap: 8EiB ] ÀåHelloº⒈åworldº²ñ\\u009E⒈¸5" + name,
        "[pos: 0, rlim: 75, wlim: 8EiB, cap: 8EiB ] ÀåHelloº⒈åworldº²ñ\\u009E⒈¸5" + name,
        "[pos: 0, rlim: 67, wlim: 8EiB, cap: 8EiB ] åHelloåworld¸5" + name,
        "[pos: 0, rlim: 67, wlim: 8EiB, cap: 8EiB ] åHelloåworld¸5" + name);
    checkAsText(
        wire,
        "\"\": Hello\n" + "field1: world\n" + "Test: \"" + name + "\"\n",
        "\"\": Hello\n" + "1: world\n" + "2603186: \"" + name + "\"\n",
        "Hello\n" + "world\n" + "\"" + name + "\"\n");

    // ok as blank matches anything
    StringBuilder sb = new StringBuilder();
    Stream.of("Hello", "world", name)
        .forEach(
            e -> {
              wire.read().textTo(sb);
              assertEquals(e, sb.toString());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
  @Test
  public void int32() {
    Wire wire = createWire();
    wire.write().int32(1);
    wire.write(BWKey.field1).int32(2);
    wire.write(() -> "Test").int32(3);
    checkWire(
        wire,
        "[pos: 0, rlim: 16, wlim: 8EiB, cap: 8EiB ] À⒈Æfield1⒉ÄTest⒊",
        "[pos: 0, rlim: 28, wlim: 8EiB, cap: 8EiB ] À¦⒈٠٠٠Æfield1¦⒉٠٠٠ÄTest¦⒊٠٠٠",
        "[pos: 0, rlim: 11, wlim: 8EiB, cap: 8EiB ] À⒈º⒈⒉º²ñ\\u009E⒈⒊",
        "[pos: 0, rlim: 23, wlim: 8EiB, cap: 8EiB ] À¦⒈٠٠٠º⒈¦⒉٠٠٠º²ñ\\u009E⒈¦⒊٠٠٠",
        "[pos: 0, rlim: 3, wlim: 8EiB, cap: 8EiB ] ⒈⒉⒊",
        "[pos: 0, rlim: 15, wlim: 8EiB, cap: 8EiB ] ¦⒈٠٠٠¦⒉٠٠٠¦⒊٠٠٠");
    checkAsText123(wire);

    // ok as blank matches anything
    AtomicInteger i = new AtomicInteger();
    IntStream.rangeClosed(1, 3)
        .forEach(
            e -> {
              wire.read().int32(i::set);
              assertEquals(e, i.get());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
  @Test
  public void testFromFile() throws IOException {
    TestMarshallable tm = new TestMarshallable();
    tm.setCount(1);
    tm.setName("name");

    for (WireType wt : WireType.values()) {

      if (wt == WireType.RAW
          || wt == WireType.READ_ANY
          || wt == WireType.CSV
          || wt == WireType.DELTA_BINARY
          || wt == WireType.DEFAULT_ZERO_BINARY) continue;
      String tmp = OS.getTarget() + "/testFromFile-" + System.nanoTime();
      wt.toFile(tmp, tm);
      Object o;
      if (wt == WireType.JSON)
        o =
            wt.apply(Bytes.wrapForRead(IOTools.readFile(tmp)))
                .getValueIn()
                .object(TestMarshallable.class);
      else o = wt.fromFile(tmp);

      assertEquals(tm, o);
    }
  }
  @Test
  public void type() {
    Wire wire = createWire();
    wire.write().type("MyType");
    wire.write(BWKey.field1).type("AlsoMyType");
    String name1 =
        "com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState";
    wire.write(() -> "Test").type(name1);
    checkWire(
        wire,
        "[pos: 0, rlim: 158, wlim: 8EiB, cap: 8EiB ] À¶⒍MyTypeÆfield1¶⒑AlsoMyTypeÄTest¶{" + name1,
        "[pos: 0, rlim: 158, wlim: 8EiB, cap: 8EiB ] À¶⒍MyTypeÆfield1¶⒑AlsoMyTypeÄTest¶{" + name1,
        "[pos: 0, rlim: 153, wlim: 8EiB, cap: 8EiB ] À¶⒍MyTypeº⒈¶⒑AlsoMyTypeº²ñ\\u009E⒈¶{" + name1,
        "[pos: 0, rlim: 153, wlim: 8EiB, cap: 8EiB ] À¶⒍MyTypeº⒈¶⒑AlsoMyTypeº²ñ\\u009E⒈¶{" + name1,
        "[pos: 0, rlim: 145, wlim: 8EiB, cap: 8EiB ] ¶⒍MyType¶⒑AlsoMyType¶{" + name1,
        "[pos: 0, rlim: 145, wlim: 8EiB, cap: 8EiB ] ¶⒍MyType¶⒑AlsoMyType¶{" + name1);
    checkAsText(
        wire,
        "\"\": !MyType field1: !AlsoMyType Test: !" + name1,
        "\"\": !MyType 1: !AlsoMyType 2603186: !" + name1,
        "!MyType !AlsoMyType !" + name1);

    // ok as blank matches anything
    StringBuilder sb = new StringBuilder();
    Stream.of("MyType", "AlsoMyType", name1)
        .forEach(
            e -> {
              wire.read().type(sb);
              assertEquals(e, sb.toString());
            });

    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }
Example #20
0
 public static void writeData(
     @NotNull WireOut wireOut,
     boolean metaData,
     boolean notReady,
     @NotNull WriteMarshallable writer) {
   Bytes bytes = wireOut.bytes();
   long position = bytes.writePosition();
   int metaDataBit = metaData ? Wires.META_DATA : 0;
   bytes.writeOrderedInt(metaDataBit | Wires.NOT_READY | Wires.UNKNOWN_LENGTH);
   writer.writeMarshallable(wireOut);
   int length =
       metaDataBit
           | toIntU30(
               bytes.writePosition() - position - 4,
               "Document length %,d out of 30-bit int range.");
   bytes.writeOrderedInt(position, length | (notReady ? Wires.NOT_READY : 0));
 }
Example #21
0
  public static boolean readData(
      long offset,
      @NotNull WireIn wireIn,
      @Nullable ReadMarshallable metaDataConsumer,
      @Nullable ReadMarshallable dataConsumer) {
    final Bytes bytes = wireIn.bytes();

    long position = bytes.readPosition();
    long limit = bytes.readLimit();
    try {
      bytes.readLimit(bytes.isElastic() ? bytes.capacity() : bytes.realCapacity());
      bytes.readPosition(offset);
      return readData(wireIn, metaDataConsumer, dataConsumer);
    } finally {
      bytes.readLimit(limit);
      bytes.readPosition(position);
    }
  }
Example #22
0
  /**
   * Creates a string from the {@code position} to the {@code limit}, The buffer is not modified by
   * this call
   *
   * @param buffer the buffer to use
   * @return a string contain the text from the {@code position} to the {@code limit}
   */
  static String toString(@NotNull final Bytes<?> buffer) throws BufferUnderflowException {
    if (buffer.readRemaining() == 0) return "";
    return buffer.parseWithLength(
        buffer.readRemaining(),
        b -> {
          final StringBuilder builder = new StringBuilder();
          try {
            while (buffer.readRemaining() > 0) {
              builder.append((char) buffer.readByte());
            }
          } catch (IORuntimeException e) {
            builder.append(' ').append(e);
          }

          // remove the last comma
          return builder.toString();
        });
  }
 private void logYamlToStandardOut(@NotNull WireIn in) {
   if (YamlLogging.showServerReads) {
     try {
       LOG.info("\nServer Receives:\n" + Wires.fromSizePrefixedBlobs(in.bytes()));
     } catch (Exception e) {
       LOG.info("\n\n" + Bytes.toString(in.bytes()));
     }
   }
 }
 private void logToBuffer(@NotNull WireIn in, StringBuilder logBuffer) {
   if (YamlLogging.showServerReads) {
     logBuffer.setLength(0);
     try {
       logBuffer.append("\nServer Receives:\n" + Wires.fromSizePrefixedBlobs(in.bytes()));
     } catch (Exception e) {
       logBuffer.append("\n\n" + Bytes.toString(in.bytes()));
     }
   }
 }
 @NotNull
 @Override
 public B writeByte(long offset, byte i8) throws AssertionError {
   try {
     byte i8a = underlyingBytesStore.readByte(offset);
     if (i8a != i8) {
       try {
         Bytes<Underlying> bytes = underlyingBytesStore.bytesForRead();
         bytes.readPosition(offset);
         throw new AssertionError(
             bytes.toDebugString() + "\nExpected: " + i8a + "\nActual: " + i8);
       } catch (IllegalStateException e) {
         throw new AssertionError(e);
       }
     }
     return (B) this;
   } catch (BufferUnderflowException | IORuntimeException e) {
     throw new AssertionError(e);
   }
 }
  void initSegment() {
    VanillaChronicleHash<?, ?, ?, ?> h = hh.h();

    long segmentBaseAddr = this.tierBaseAddr;
    segmentBS.set(segmentBaseAddr, h.tierSize);
    segmentBytes.clear();

    long freeListOffset = h.tierHashLookupOuterSize + TIER_COUNTERS_AREA_SIZE;
    freeList.setOffset(segmentBaseAddr + freeListOffset);

    entrySpaceOffset = freeListOffset + h.tierFreeListOuterSize + h.tierEntrySpaceInnerOffset;
  }
  @Test
  public void testParseUTF_SB1() throws Exception {
    VanillaBytes bytes = Bytes.allocateElasticDirect();
    byte[] bytes2 = new byte[128];
    Arrays.fill(bytes2, (byte) '?');
    bytes.write(bytes2);

    StringBuilder sb = new StringBuilder();

    BytesInternal.parseUtf8(bytes, sb, 128);
    assertEquals(128, sb.length());
    assertEquals(new String(bytes2, 0), sb.toString());
  }
 @NotNull
 @Override
 public A read(Bytes in, A using) {
   if (using == null) using = new A();
   using.str_ = in.readUtf8();
   int size = (int) in.readStopBit();
   if (size >= 0) {
     if (using.list_ == null) {
       using.list_ = new ArrayList<>(size);
     } else {
       using.list_.clear();
       if (using.list_ instanceof ArrayList) ((ArrayList) using.list_).ensureCapacity(size);
     }
     for (int i = 0; i < size; i++) {
       B b = new B();
       b.readMarshallable(in);
       using.list_.add(b);
     }
   } else {
     assert size == -1;
     using.list_ = null;
   }
   return using;
 }
Example #29
0
 public static void compress(ValueOut out, String compression, Bytes bytes) {
   switch (compression) {
     case "snappy":
       try {
         out.bytes("snappy", Snappy.compress(bytes.toByteArray()));
       } catch (IOException e) {
         throw new AssertionError(e);
       }
       break;
     case "gzip":
       try {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         GZIPOutputStream gos = new GZIPOutputStream(baos);
         bytes.copyTo(gos);
         gos.close();
         out.bytes("gzip", baos.toByteArray());
       } catch (IOException e) {
         throw new AssertionError(e);
       }
       break;
     default:
       throw new IllegalArgumentException("Unknown compression " + compression);
   }
 }
  @Test
  public void testRead() {
    Wire wire = createWire();
    wire.write();
    wire.write(BWKey.field1);
    wire.write(() -> "Test");
    checkAsText(wire, "\"\": field1: Test: ", "\"\": 1: 2603186: ", "");

    wire.read();
    wire.read();
    wire.read();
    assertEquals(0, bytes.readRemaining());
    // check it's safe to read too much.
    wire.read();
  }