code: @Override
      public int read(byte b[], int offset, int length) {
          if (b == null) {
              throw new NullPointerException();
          }
          // avoid int overflow
          if (offset < 0 || offset > b.length || length < 0
                  || length > b.length - offset) {
              throw new IndexOutOfBoundsException();
          }
          // Are there any bytes available?
          if (this.pos >= this.count) {
              return -1;
          }
          if (length == 0) {
              return 0;
          }
  
          int copylen = this.count - pos < length ? this.count - pos : length;
          System.arraycopy(buf, pos, b, offset, copylen);
          pos += copylen;
          return copylen;
      }
docs: Reads at most {@code len} bytes from this stream and stores
  them in byte array {@code b} starting at {@code offset}. This
  implementation reads bytes from the source byte array.
  
  @param b
  the byte array in which to store the bytes read.
  @param offset
  the initial position in {@code b} to store the bytes read from
  this stream.
  @param length
  the maximum number of bytes to store in {@code b}.
  @return the number of bytes actually read or -1 if no bytes were read and
  the end of the stream was encountered.
  @throws IndexOutOfBoundsException
  if {@code offset < 0} or {@code length < 0}, or if
  {@code offset + length} is greater than the size of
  {@code b}.
  @throws NullPointerException
  if {@code b} is {@code null}.