Exemplo n.º 1
0
        /// <exception cref="System.IO.IOException"/>
        private void ReadTrailingEmptyPacket()
        {
            if (Log.IsTraceEnabled())
            {
                Log.Trace("Reading empty packet at end of read");
            }
            packetReceiver.ReceiveNextPacket(@in);
            PacketHeader trailer = packetReceiver.GetHeader();

            if (!trailer.IsLastPacketInBlock() || trailer.GetDataLen() != 0)
            {
                throw new IOException("Expected empty end-of-read packet! Header: " + trailer);
            }
        }
Exemplo n.º 2
0
 /// <exception cref="System.IO.IOException"/>
 private int ReadChunkImpl(long pos, byte[] buf, int offset, int len, byte[] checksumBuf
                           )
 {
     lock (this)
     {
         // Read one chunk.
         if (eos)
         {
             // Already hit EOF
             return(-1);
         }
         // Read one DATA_CHUNK.
         long chunkOffset = lastChunkOffset;
         if (lastChunkLen > 0)
         {
             chunkOffset += lastChunkLen;
         }
         // pos is relative to the start of the first chunk of the read.
         // chunkOffset is relative to the start of the block.
         // This makes sure that the read passed from FSInputChecker is the
         // for the same chunk we expect to be reading from the DN.
         if ((pos + firstChunkOffset) != chunkOffset)
         {
             throw new IOException("Mismatch in pos : " + pos + " + " + firstChunkOffset + " != "
                                   + chunkOffset);
         }
         // Read next packet if the previous packet has been read completely.
         if (dataLeft <= 0)
         {
             //Read packet headers.
             PacketHeader header = new PacketHeader();
             header.ReadFields(@in);
             if (Log.IsDebugEnabled())
             {
                 Log.Debug("DFSClient readChunk got header " + header);
             }
             // Sanity check the lengths
             if (!header.SanityCheck(lastSeqNo))
             {
                 throw new IOException("BlockReader: error in packet header " + header);
             }
             lastSeqNo = header.GetSeqno();
             dataLeft  = header.GetDataLen();
             AdjustChecksumBytes(header.GetDataLen());
             if (header.GetDataLen() > 0)
             {
                 IOUtils.ReadFully(@in, ((byte[])checksumBytes.Array()), 0, checksumBytes.Limit());
             }
         }
         // Sanity checks
         System.Diagnostics.Debug.Assert(len >= bytesPerChecksum);
         System.Diagnostics.Debug.Assert(checksum != null);
         System.Diagnostics.Debug.Assert(checksumSize == 0 || (checksumBuf.Length % checksumSize
                                                               == 0));
         int checksumsToRead;
         int bytesToRead;
         if (checksumSize > 0)
         {
             // How many chunks left in our packet - this is a ceiling
             // since we may have a partial chunk at the end of the file
             int chunksLeft = (dataLeft - 1) / bytesPerChecksum + 1;
             // How many chunks we can fit in databuffer
             //  - note this is a floor since we always read full chunks
             int chunksCanFit = Math.Min(len / bytesPerChecksum, checksumBuf.Length / checksumSize
                                         );
             // How many chunks should we read
             checksumsToRead = Math.Min(chunksLeft, chunksCanFit);
             // How many bytes should we actually read
             bytesToRead = Math.Min(checksumsToRead * bytesPerChecksum, dataLeft);
         }
         else
         {
             // full chunks
             // in case we have a partial
             // no checksum
             bytesToRead     = Math.Min(dataLeft, len);
             checksumsToRead = 0;
         }
         if (bytesToRead > 0)
         {
             // Assert we have enough space
             System.Diagnostics.Debug.Assert(bytesToRead <= len);
             System.Diagnostics.Debug.Assert(checksumBytes.Remaining() >= checksumSize * checksumsToRead
                                             );
             System.Diagnostics.Debug.Assert(checksumBuf.Length >= checksumSize * checksumsToRead
                                             );
             IOUtils.ReadFully(@in, buf, offset, bytesToRead);
             checksumBytes.Get(checksumBuf, 0, checksumSize * checksumsToRead);
         }
         dataLeft -= bytesToRead;
         System.Diagnostics.Debug.Assert(dataLeft >= 0);
         lastChunkOffset = chunkOffset;
         lastChunkLen    = bytesToRead;
         // If there's no data left in the current packet after satisfying
         // this read, and we have satisfied the client read, we expect
         // an empty packet header from the DN to signify this.
         // Note that pos + bytesToRead may in fact be greater since the
         // DN finishes off the entire last chunk.
         if (dataLeft == 0 && pos + bytesToRead >= bytesNeededToFinish)
         {
             // Read header
             PacketHeader hdr = new PacketHeader();
             hdr.ReadFields(@in);
             if (!hdr.IsLastPacketInBlock() || hdr.GetDataLen() != 0)
             {
                 throw new IOException("Expected empty end-of-read packet! Header: " + hdr);
             }
             eos = true;
         }
         if (bytesToRead == 0)
         {
             return(-1);
         }
         return(bytesToRead);
     }
 }