{@inheritDoc}

@throws SMBProtocolDecodingException

@see jcifs.internal.smb2.ServerMessageBlock2#readBytesWireFormat(byte[], int)
488854
@Override
    protected int readBytesWireFormat ( byte[] buffer, int bufferIndex ) throws SMBProtocolDecodingException {
        int start = bufferIndex;

        int structureSize = SMBUtil.readInt2(buffer, bufferIndex);
        if ( structureSize != 9 ) {
            throw new SMBProtocolDecodingException("Expected structureSize = 9");
        }

        int bufferOffset = SMBUtil.readInt2(buffer, bufferIndex + 2) + getHeaderStart();
        bufferIndex += 4;
        int len = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;

        int elemStart = bufferOffset;
        FileNotifyInformationImpl i = new FileNotifyInformationImpl();
        bufferIndex += i.decode(buffer, bufferOffset, len);
        this.notifyInformation.add(i);

        while ( i.getNextEntryOffset() > 0 && bufferIndex < bufferOffset + len ) {
            bufferIndex = elemStart + i.getNextEntryOffset();
            elemStart = bufferIndex;

            i = new FileNotifyInformationImpl();
            bufferIndex += i.decode(buffer, bufferIndex, len);
            this.notifyInformation.add(i);
        }

        return bufferIndex - start;
    }
110684
public byte[] readBytes()
        throws IOException
    {
        int tag = is.read();

        if (tag == 'N')
            return null;

        if (tag != 'B')
            throw expect("bytes", tag);

        int b16 = is.read();
        int b8 = is.read();

        int len = (b16 << 8) + b8;

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        for (int i = 0; i < len; i++)
            bos.write(is.read());

        return bos.toByteArray();
    }
1030342
@Override
    public int decode ( byte[] buffer, int bufferIndex, int len ) throws SMBProtocolDecodingException {
        int start = bufferIndex;
        if ( len < 24 ) {
            throw new SMBProtocolDecodingException("Invalid resume key");
        }

        this.resumeKey = new byte[24];
        System.arraycopy(buffer, bufferIndex, this.resumeKey, 0, 24);
        bufferIndex += 24;

        SMBUtil.readInt4(buffer, bufferIndex); // contextLength - reserved
        bufferIndex += 4;

        return bufferIndex - start;
    }
494359
@Override
    protected int writeBytesWireFormat ( byte[] dst, int dstIndex ) {
        int start = dstIndex;
        SMBUtil.writeInt2(36, dst, dstIndex);
        SMBUtil.writeInt2(this.dialects.length, dst, dstIndex + 2);
        dstIndex += 4;

        SMBUtil.writeInt2(this.securityMode, dst, dstIndex);
        SMBUtil.writeInt2(0, dst, dstIndex + 2); // Reserved
        dstIndex += 4;

        SMBUtil.writeInt4(this.capabilities, dst, dstIndex);
        dstIndex += 4;

        System.arraycopy(this.clientGuid, 0, dst, dstIndex, 16);
        dstIndex += 16;

        // if SMB 3.11 support negotiateContextOffset/negotiateContextCount
        int negotitateContextOffsetOffset = 0;
        if ( this.negotiateContexts == null || this.negotiateContexts.length == 0 ) {
            SMBUtil.writeInt8(0, dst, dstIndex);
        }
        else {
            negotitateContextOffsetOffset = dstIndex;
            SMBUtil.writeInt2(this.negotiateContexts.length, dst, dstIndex + 4);
            SMBUtil.writeInt2(0, dst, dstIndex + 6);
        }
        dstIndex += 8;

        for ( int dialect : this.dialects ) {
            SMBUtil.writeInt2(dialect, dst, dstIndex);
            dstIndex += 2;
        }

        dstIndex += pad8(dstIndex);

        if ( this.negotiateContexts != null && this.negotiateContexts.length != 0 ) {
            SMBUtil.writeInt4(dstIndex - getHeaderStart(), dst, negotitateContextOffsetOffset);
            for ( NegotiateContextRequest nc : this.negotiateContexts ) {
                SMBUtil.writeInt2(nc.getContextType(), dst, dstIndex);
                int lenOffset = dstIndex + 2;
                dstIndex += 4;
                SMBUtil.writeInt4(0, dst, dstIndex);
                dstIndex += 4; // Reserved
                int dataLen = size8(nc.encode(dst, dstIndex));
                SMBUtil.writeInt2(dataLen, dst, lenOffset);
                dstIndex += dataLen;
            }
        }
        return dstIndex - start;
    }
1352163
@Override
	public T decode(byte[] bytes) throws IOException {
		if (bytes == null) {
			throw new IOException("byte array is null.");
		}
		CodedInputStream input = CodedInputStream.newInstance(bytes, 0, bytes.length);

		return readFrom(input);
	}
577389
@Override
    protected int writeBytesWireFormat ( byte[] dst, int dstIndex ) {
        int start = dstIndex;
        SMBUtil.writeInt2(33, dst, dstIndex);
        dst[ dstIndex + 2 ] = this.fileInformationClass;
        dst[ dstIndex + 3 ] = this.queryFlags;
        dstIndex += 4;
        SMBUtil.writeInt4(this.fileIndex, dst, dstIndex);
        dstIndex += 4;
        System.arraycopy(this.fileId, 0, dst, dstIndex, 16);
        dstIndex += 16;

        int fnOffsetOffset = dstIndex;
        int fnLengthOffset = dstIndex + 2;
        dstIndex += 4;

        SMBUtil.writeInt4(this.outputBufferLength, dst, dstIndex);
        dstIndex += 4;

        if ( this.fileName == null ) {
            SMBUtil.writeInt2(0, dst, fnOffsetOffset);
            SMBUtil.writeInt2(0, dst, fnLengthOffset);
        }
        else {
            byte[] fnBytes = this.fileName.getBytes(StandardCharsets.UTF_16LE);
            SMBUtil.writeInt2(dstIndex - getHeaderStart(), dst, fnOffsetOffset);
            SMBUtil.writeInt2(fnBytes.length, dst, fnLengthOffset);
            System.arraycopy(fnBytes, 0, dst, dstIndex, fnBytes.length);
            dstIndex += fnBytes.length;
        }
        return dstIndex - start;
    }
52453
@Override
    public int decode ( byte[] buffer, int bufferIndex, int len ) throws SMBProtocolDecodingException {
        if ( this.largeFile ) {
            this.pid = SMBUtil.readInt2(buffer, bufferIndex);
            int boHigh = SMBUtil.readInt4(buffer, bufferIndex + 4);
            int boLow = SMBUtil.readInt4(buffer, bufferIndex + 8);

            this.byteOffset = ( boHigh << 32 ) | boLow;

            int lHigh = SMBUtil.readInt4(buffer, bufferIndex + 12);
            int lLow = SMBUtil.readInt4(buffer, bufferIndex + 16);

            this.lengthInBytes = ( lHigh << 32 ) | lLow;
            return 20;
        }
        this.pid = SMBUtil.readInt2(buffer, bufferIndex);
        this.byteOffset = SMBUtil.readInt4(buffer, bufferIndex + 2);
        this.lengthInBytes = SMBUtil.readInt4(buffer, bufferIndex + 6);
        return 10;
    }
1189032
@Override
    protected int writeBytesWireFormat ( byte[] dst, int dstIndex ) {
        int start = dstIndex;
        SMBUtil.writeInt2(57, dst, dstIndex);
        dstIndex += 4;
        SMBUtil.writeInt4(this.controlCode, dst, dstIndex);
        dstIndex += 4;
        System.arraycopy(this.fileId, 0, dst, dstIndex, 16);
        dstIndex += 16;

        int inputOffsetOffset = dstIndex;
        dstIndex += 4;
        int inputLengthOffset = dstIndex;
        dstIndex += 4;
        SMBUtil.writeInt4(this.maxInputResponse, dst, dstIndex);
        dstIndex += 4;

        int outputOffsetOffset = dstIndex;
        dstIndex += 4;
        int outputLengthOffset = dstIndex;
        dstIndex += 4;
        SMBUtil.writeInt4(this.maxOutputResponse, dst, dstIndex);
        dstIndex += 4;

        SMBUtil.writeInt4(this.flags, dst, dstIndex);
        dstIndex += 4;
        dstIndex += 4; // Reserved2

        if ( this.inputData != null ) {
            SMBUtil.writeInt4(dstIndex - getHeaderStart(), dst, inputOffsetOffset);
            int len = this.inputData.encode(dst, dstIndex);
            SMBUtil.writeInt4(len, dst, inputLengthOffset);
            dstIndex += len;
        }
        else {
            SMBUtil.writeInt4(0, dst, inputOffsetOffset);
            SMBUtil.writeInt4(0, dst, inputLengthOffset);
        }

        if ( this.outputData != null ) {
            SMBUtil.writeInt4(dstIndex - getHeaderStart(), dst, outputOffsetOffset);
            int len = this.outputData.encode(dst, dstIndex);
            SMBUtil.writeInt4(len, dst, outputLengthOffset);
            dstIndex += len;
        }
        else {
            SMBUtil.writeInt4(0, dst, outputOffsetOffset);
            SMBUtil.writeInt4(0, dst, outputLengthOffset);
        }

        return dstIndex - start;
    }
476405
@Override
    protected int readBytesWireFormat ( byte[] buffer, int bufferIndex ) throws SMBProtocolDecodingException {
        int start = bufferIndex;
        int structureSize = SMBUtil.readInt2(buffer, bufferIndex);

        if ( structureSize != 9 ) {
            throw new SMBProtocolDecodingException("Expected structureSize = 9");
        }

        int bufferOffset = SMBUtil.readInt2(buffer, bufferIndex + 2) + getHeaderStart();
        bufferIndex += 4;
        int bufferLength = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;

        // bufferIndex = bufferOffset;

        List<FileEntry> infos = new ArrayList<>();
        do {
            FileBothDirectoryInfo cur = createFileInfo();
            if ( cur == null ) {
                break;
            }
            cur.decode(buffer, bufferIndex, bufferLength);
            infos.add(cur);
            int nextEntryOffset = cur.getNextEntryOffset();
            if ( nextEntryOffset > 0 ) {
                bufferIndex += nextEntryOffset;
            }
            else {
                break;
            }
        }
        while ( bufferIndex < bufferOffset + bufferLength );
        this.results = infos.toArray(new FileEntry[infos.size()]);
        return bufferIndex - start;
    }
1083989
@Override
    public final int read(byte[] pBytes) throws IOException {
        return read(pBytes, 0, pBytes != null ? pBytes.length : 1);
    }
341101
public byte []
readByteArray(int len) throws WireParseException {
	require(len);
	byte [] out = new byte[len];
	byteBuffer.get(out, 0, len);
	return out;
}
1049211
static int readRawVarint32(final DataInput input, final byte firstByte) throws IOException
    {
        int result = firstByte & 0x7f;
        int offset = 7;
        for (; offset < 32; offset += 7)
        {
            final byte b = input.readByte();
            result |= (b & 0x7f) << offset;
            if ((b & 0x80) == 0)
            {
                return result;
            }
        }
        // Keep reading up to 64 bits.
        for (; offset < 64; offset += 7)
        {
            final byte b = input.readByte();
            if ((b & 0x80) == 0)
            {
                return result;
            }
        }
        throw ProtobufException.malformedVarint();
    }
358995
@Override
  public int read(byte []buffer, int offset, int length) throws IOException
  {
    int sublen = getDelegate().read(buffer, offset, length);
    
    if (sublen > 0) {
      logStream().write(buffer, offset, sublen);
    }
    
    return sublen;
  }
741625
@Override
    protected int writeBytesWireFormat ( byte[] dst, int dstIndex ) {
        int start = dstIndex;
        SMBUtil.writeInt2(49, dst, dstIndex);
        dst[ dstIndex + 2 ] = this.padding;
        dst[ dstIndex + 3 ] = this.readFlags;
        dstIndex += 4;
        SMBUtil.writeInt4(this.readLength, dst, dstIndex);
        dstIndex += 4;
        SMBUtil.writeInt8(this.offset, dst, dstIndex);
        dstIndex += 8;
        System.arraycopy(this.fileId, 0, dst, dstIndex, 16);
        dstIndex += 16;
        SMBUtil.writeInt4(this.minimumCount, dst, dstIndex);
        dstIndex += 4;
        SMBUtil.writeInt4(this.channel, dst, dstIndex);
        dstIndex += 4;
        SMBUtil.writeInt4(this.remainingBytes, dst, dstIndex);
        dstIndex += 4;

        // ReadChannelInfo
        SMBUtil.writeInt2(0, dst, dstIndex);
        SMBUtil.writeInt2(0, dst, dstIndex + 2);
        dstIndex += 4;

        // one byte in buffer must be zero
        dst[ dstIndex ] = 0;
        dstIndex += 1;

        return dstIndex - start;
    }
1173407
@Override
  public int read () throws IOException
  {
    // Do we need to get data?
    if (m_nPosition < 0)
    {
      if (m_bEncode)
      {
        final byte [] b3 = new byte [3];
        int numBinaryBytes = 0;
        for (int i = 0; i < 3; i++)
        {
          final int b = in.read ();

          // If end of stream, b is -1.
          if (b < 0)
            break;

          b3[i] = (byte) b;
          numBinaryBytes++;
        }

        if (numBinaryBytes > 0)
        {
          Base64._encode3to4 (b3, 0, numBinaryBytes, m_aBuffer, 0, m_nOptions);
          m_nPosition = 0;
          m_nNumSigBytes = 4;
        }
        else
        {
          return -1; // Must be end of stream
        }
      }
      else
      {
        // Else decoding
        final byte [] b4 = new byte [4];
        int i;
        for (i = 0; i < 4; i++)
        {
          // Read four "meaningful" bytes:
          int b;
          do
          {
            b = in.read ();
          } while (b >= 0 && m_aDecodabet[b & 0x7f] <= Base64.WHITE_SPACE_ENC);

          if (b < 0)
            break; // Reads a -1 if end of stream

          b4[i] = (byte) b;
        }

        if (i == 4)
        {
          m_nNumSigBytes = Base64._decode4to3 (b4, 0, m_aBuffer, 0, m_nOptions);
          m_nPosition = 0;
        }
        else
          if (i == 0)
          {
            return -1;
          }
          else
          {
            // Must have broken out from above.
            throw new IOException ("Improperly padded Base64 input.");
          } // end

      }
    }

    // Got data?
    if (m_nPosition >= 0)
    {
      if ( /* !encode && */m_nPosition >= m_nNumSigBytes)
      {
        return -1;
      }

      if (m_bEncode && m_bBreakLines && m_nLineLength >= Base64.MAX_LINE_LENGTH)
      {
        m_nLineLength = 0;
        return '\n';
      }
      {
        m_nLineLength++; // This isn't important when decoding
        // but throwing an extra "if" seems
        // just as wasteful.

        final int b = m_aBuffer[m_nPosition++];

        if (m_nPosition >= m_nBufferLength)
          m_nPosition = -1;

        return b & 0xFF; // This is how you "cast" a byte that's
                         // intended to be unsigned.
      }
    }

    // Else error
    throw new IOException ("Error in Base64 code reading stream.");
  }
1240757
@Override
    public int read(byte[] b, int byteOffset, int byteLength)
            throws IOException
    {
        int writtenBytes = 0;
        for (; writtenBytes < byteLength; ) {

            if (uncompressedCursor >= uncompressedLimit) {
                if (hasNextChunk()) {
                    continue;
                }
                else {
                    return writtenBytes == 0 ? -1 : writtenBytes;
                }
            }
            int bytesToWrite = Math.min(uncompressedLimit - uncompressedCursor, byteLength - writtenBytes);
            System.arraycopy(uncompressed, uncompressedCursor, b, byteOffset + writtenBytes, bytesToWrite);
            writtenBytes += bytesToWrite;
            uncompressedCursor += bytesToWrite;
        }

        return writtenBytes;
    }
1257935
@Override
    public byte readByte() throws IndexOutOfBoundsException, IOException {
        final int read = internalReadBytes(1);
        if (read == -1) {
            // not sure this is really the right thing to do
            throw new IndexOutOfBoundsException();
        }
        return getByte(this.readerIndex++);
    }