/// <summary>
        /// Read a message from an input stream.  The message will be fully
        /// contained in the first segment
        /// </summary>
        /// <param name="stream"> </param>
        /// <exception cref="IOException"> </exception>

        public virtual void getMessage(CryptoInputStream stream)
        {
            reset();
            int length = stream.readLength();

            if (length > available)
            {
                if (firstSegment != null)
                {
                    firstSegment.zap();
                }

                available = 0;
                extend(length);
            }

            int offset = 0;

            while (offset < length)
            {
                int lengthRead = firstSegment.read(stream, length - offset);

                if (lengthRead == -1)
                {
                    throw new IOException("End of stream reached");
                }

                offset += lengthRead;
            }

            totalLength = length;
        }
            internal virtual int read(CryptoInputStream stream, int len)
            {
                int actualLength = stream.Read(buffer, length, Math.Min(buffer.Length - length, len));

                if (actualLength < 0)
                {
                    throw new IOException("End of stream reached");
                }

                length += actualLength;

                return(actualLength);
            }
        /// <summary>
        /// Create IOStreamPair of
        /// <see cref="Org.Apache.Hadoop.Crypto.CryptoInputStream"/>
        /// and
        /// <see cref="Org.Apache.Hadoop.Crypto.CryptoOutputStream"/>
        /// </summary>
        /// <param name="conf">the configuration</param>
        /// <param name="cipherOption">negotiated cipher option</param>
        /// <param name="out">underlying output stream</param>
        /// <param name="in">underlying input stream</param>
        /// <param name="isServer">is server side</param>
        /// <returns>IOStreamPair the stream pair</returns>
        /// <exception cref="System.IO.IOException">for any error</exception>
        public static IOStreamPair CreateStreamPair(Configuration conf, CipherOption cipherOption
                                                    , OutputStream @out, InputStream @in, bool isServer)
        {
            if (Log.IsDebugEnabled())
            {
                Log.Debug("Creating IOStreamPair of CryptoInputStream and " + "CryptoOutputStream."
                          );
            }
            CryptoCodec codec = CryptoCodec.GetInstance(conf, cipherOption.GetCipherSuite());

            byte[]      inKey  = cipherOption.GetInKey();
            byte[]      inIv   = cipherOption.GetInIv();
            byte[]      outKey = cipherOption.GetOutKey();
            byte[]      outIv  = cipherOption.GetOutIv();
            InputStream cIn    = new CryptoInputStream(@in, codec, isServer ? inKey : outKey, isServer
                                 ? inIv : outIv);
            OutputStream cOut = new CryptoOutputStream(@out, codec, isServer ? outKey : inKey
                                                       , isServer ? outIv : inIv);

            return(new IOStreamPair(cIn, cOut));
        }
 /// <exception cref="System.IO.IOException"/>
 public HdfsDataInputStream(CryptoInputStream @in)
     : base(@in)
 {
     Preconditions.CheckArgument(@in.GetWrappedStream() is DFSInputStream, "CryptoInputStream should wrap a DFSInputStream"
                                 );
 }