@Override public long read(Buffer sink, long byteCount) throws IOException { if (bytesLeft == -1L) throw new IllegalStateException("closed"); if (bytesLeft == 0L) return -1L; if (byteCount > Integer.MAX_VALUE) byteCount = Integer.MAX_VALUE; if (byteCount > bytesLeft) byteCount = bytesLeft; // Random is most efficient when computing 32 bits of randomness. Start with that. int ints = (int) (byteCount / 4); for (int i = 0; i < ints; i++) { sink.writeInt(random.nextInt()); } // If we need 1, 2, or 3 bytes more, keep going. We'll discard 24, 16 or 8 random bits! int bytes = (int) (byteCount - ints * 4); if (bytes > 0) { int bits = random.nextInt(); for (int i = 0; i < bytes; i++) { sink.writeByte(bits & 0xff); bits >>>= 8; } } bytesLeft -= byteCount; return byteCount; }
@Test public void gunzipWhenCRCIncorrect() { Buffer gzipped = new Buffer(); gzipped.write(gzipHeader); gzipped.write(deflated); gzipped.writeInt(TestUtil.reverseBytes(0x1234567)); // wrong CRC gzipped.write(gzipTrailer.toByteArray(), 3, 4); try { gunzip(gzipped); fail(); } catch (IOException e) { assertEquals("CRC: actual 0x37ad8f8d != expected 0x01234567", e.getMessage()); } }
@Test public void gunzipWhenLengthIncorrect() { Buffer gzipped = new Buffer(); gzipped.write(gzipHeader); gzipped.write(deflated); gzipped.write(gzipTrailer.toByteArray(), 0, 4); gzipped.writeInt(TestUtil.reverseBytes(0x123456)); // wrong length try { gunzip(gzipped); fail(); } catch (IOException e) { assertEquals("ISIZE: actual 0x00000020 != expected 0x00123456", e.getMessage()); } }
@Override public BufferedSink writeInt(int i) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeInt(i); return emitCompleteSegments(); }
@Override public Buffer writeIntLe(int i) { return writeInt(Util.reverseBytesInt(i)); }
private void writeHeader() { // Write the Gzip header directly into the buffer for the sink to avoid handling IOException. Buffer buffer = this.sink.buffer(); buffer.writeShort(0x1f8b); // Two-byte Gzip ID. buffer.writeByte(0x08); // 8 == Deflate compression method. buffer.writeByte(0x00); // No flags. buffer.writeInt(0x00); // No modification time. buffer.writeByte(0x00); // No extra flags. buffer.writeByte(0x00); // No OS. }
break; case I32: buffer.writeInt(Integer.parseInt(number)); break; case I64: