protected void readHeader()

in src/main/java/com/hadoop/compression/lzo/LzopInputStream.java [114:210]


  protected void readHeader(InputStream in) throws IOException {
    readFully(in, buf, 0, 9);
    if (!Arrays.equals(buf, LzopCodec.LZO_MAGIC)) {
      throw new IOException("Invalid LZO header");
    }
    Arrays.fill(buf, (byte)0);
    Adler32 adler = new Adler32();
    CRC32 crc32 = new CRC32();
    int hitem = readHeaderItem(in, buf, 2, adler, crc32); // lzop version
    if (hitem > LzopCodec.LZOP_VERSION) {
      LOG.debug("Compressed with later version of lzop: " +
          Integer.toHexString(hitem) + " (expected 0x" +
          Integer.toHexString(LzopCodec.LZOP_VERSION) + ")");
    }
    hitem = readHeaderItem(in, buf, 2, adler, crc32); // lzo library version
    if (hitem < LzoDecompressor.MINIMUM_LZO_VERSION) {
      throw new IOException("Compressed with incompatible lzo version: 0x" +
          Integer.toHexString(hitem) + " (expected at least 0x" +
          Integer.toHexString(LzoDecompressor.MINIMUM_LZO_VERSION) + ")");
    }
    hitem = readHeaderItem(in, buf, 2, adler, crc32); // lzop extract version
    if (hitem > LzopCodec.LZOP_VERSION) {
      throw new IOException("Compressed with incompatible lzop version: 0x" +
          Integer.toHexString(hitem) + " (expected 0x" +
          Integer.toHexString(LzopCodec.LZOP_VERSION) + ")");
    }
    hitem = readHeaderItem(in, buf, 1, adler, crc32); // method
    if (hitem < 1 || hitem > 3) {
      throw new IOException("Invalid strategy: " +
          Integer.toHexString(hitem));
    }
    readHeaderItem(in, buf, 1, adler, crc32); // ignore level

    // flags
    hitem = readHeaderItem(in, buf, 4, adler, crc32);
    try {
      for (DChecksum f : dflags) {
        if (0 == (f.getHeaderMask() & hitem)) {
          dflags.remove(f);
        } else {
          dcheck.put(f, (int)f.getChecksumClass().newInstance().getValue());
        }
      }
      for (CChecksum f : cflags) {
        if (0 == (f.getHeaderMask() & hitem)) {
          cflags.remove(f);
        } else {
          ccheck.put(f, (int)f.getChecksumClass().newInstance().getValue());
        }
      }
    } catch (InstantiationException e) {
      throw new RuntimeException("Internal error", e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException("Internal error", e);
    }
    ((LzopDecompressor)decompressor).initHeaderFlags(dflags, cflags);
    boolean useCRC32 = 0 != (hitem & 0x00001000);   // F_H_CRC32
    boolean extraField = 0 != (hitem & 0x00000040); // F_H_EXTRA_FIELD
    if (0 != (hitem & 0x400)) {                     // F_MULTIPART
      throw new IOException("Multipart lzop not supported");
    }
    if (0 != (hitem & 0x800)) {                     // F_H_FILTER
      throw new IOException("lzop filter not supported");
    }
    if (0 != (hitem & 0x000FC000)) {                // F_RESERVED
      throw new IOException("Unknown flags in header");
    }
    // known !F_H_FILTER, so no optional block

    readHeaderItem(in, buf, 4, adler, crc32); // ignore mode
    readHeaderItem(in, buf, 4, adler, crc32); // ignore mtime
    readHeaderItem(in, buf, 4, adler, crc32); // ignore gmtdiff
    hitem = readHeaderItem(in, buf, 1, adler, crc32); // fn len
    if (hitem > 0) {
      // skip filename
      int filenameLen = Math.max(4, hitem); // buffer must be at least 4 bytes for readHeaderItem to work.
      readHeaderItem(in, new byte[filenameLen], hitem, adler, crc32);
    }
    int checksum = (int)(useCRC32 ? crc32.getValue() : adler.getValue());
    hitem = readHeaderItem(in, buf, 4, adler, crc32); // read checksum
    if (hitem != checksum) {
      throw new IOException("Invalid header checksum: " +
          Long.toHexString(checksum) + " (expected 0x" +
          Integer.toHexString(hitem) + ")");
    }
    if (extraField) { // lzop 1.08 ultimately ignores this
      LOG.debug("Extra header field not processed");
      adler.reset();
      crc32.reset();
      hitem = readHeaderItem(in, buf, 4, adler, crc32);
      readHeaderItem(in, new byte[hitem], hitem, adler, crc32);
      checksum = (int)(useCRC32 ? crc32.getValue() : adler.getValue());
      if (checksum != readHeaderItem(in, buf, 4, adler, crc32)) {
        throw new IOException("Invalid checksum for extra header field");
      }
    }
  }