docs: public int read() throws IOException {
      if (this.bytesRead == this.length) {
        // All chunks and final additional chunk are read.
        // This means we have reached EOF.
        return -1;
      }
  
      try {
        // Read a chunk from given input stream when
        // it is first chunk or all bytes in chunk body is read
        if (this.streamBytesRead == 0 || this.chunkPos == this.chunkBody.length) {
          // Check if there are data available to read from given input stream.
          if (this.streamBytesRead != this.streamSize) {
            // Send all data chunks.
            int chunkSize = CHUNK_SIZE;
            if (this.streamBytesRead + chunkSize > this.streamSize) {
              chunkSize = this.streamSize - this.streamBytesRead;
            }
  
            if (readChunk(chunkSize) < 0) {
              return -1;
            }
  
            this.streamBytesRead += chunkSize;
          } else {
            // Send final additional chunk to complete chunk upload.
            byte[] chunk = new byte[0];
            createChunkBody(chunk);
          }
        }
  
        this.bytesRead++;
        // Value must be between 0 to 255.
        int value = this.chunkBody[this.chunkPos] & 0xFF;
        this.chunkPos++;
        return value;
      } catch (NoSuchAlgorithmException | InvalidKeyException | InsufficientDataException | InternalException e) {
        throw new IOException(e.getCause());
      }
    }