package org.apache.hadoop.io.simpleseekableformat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.zip.CRC32; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.io.compress.CompressionCodec; import org.apache.hadoop.util.ReflectionUtils; /** * This class holds the data related to a single data segment. */ class DataSegmentReader { // uncompressed data stream private final InputStream uncompressedData; /** * Create a new data segment by reading from an input stream. * @throws EOFException if the underlying data stream is truncated (incomplete DataSegment) */ DataSegmentReader(DataInputStream in) throws IOException, ClassNotFoundException { this(in, new Configuration()); } @SuppressWarnings("unchecked") DataSegmentReader(DataInputStream in, Configuration conf) throws IOException, ClassNotFoundException { // Read from DataInputStream // 1. Read length int length = in.readInt(); // 2. Read codec int codecNameUTF8Length = in.readShort(); byte[] codecNameUTF8 = new byte[codecNameUTF8Length]; in.readFully(codecNameUTF8); String codecName = new String(codecNameUTF8, "UTF-8"); // 3. read CRC32 long crc32Value = in.readLong(); // 4. read data byte[] storedData = new byte[length - 8/*crc32*/ - 2/*codec length*/ - codecNameUTF8Length]; in.readFully(storedData); // Verify the checksum CRC32 crc32 = new CRC32(); crc32.update(storedData); if (crc32.getValue() != crc32Value) { throw new CorruptedDataException("Corrupted data segment with length " + length + " crc32 expected " + crc32Value + " but got " + crc32.getValue()); } // Uncompress the data if needed if (codecName.equals("")) { // no compression uncompressedData = new ByteArrayInputStream(storedData); } else { Class<? extends CompressionCodec> codecClass = (Class<? extends CompressionCodec>)Class.forName(codecName); CompressionCodec codec = ReflectionUtils.newInstance(codecClass, conf); uncompressedData = codec.createInputStream(new ByteArrayInputStream(storedData)); } } InputStream getInputStream() { return uncompressedData; } }