core/src/main/java/com/twitter/elephantbird/mapreduce/input/LzoBinaryB64LineRecordReader.java
@Override
  public boolean nextKeyValue() throws IOException, InterruptedException {
    // Since the lzop codec reads everything in lzo blocks, we can't stop if pos == end.
    // Instead we wait for the next block to be read in, when pos will be > end.
    while (pos_ <= end_) {
      key_.set(pos_);

      int newSize = lineReader_.readLine(line_, maxLineLen);
      if (newSize == 0) {
        return false;
      }
      HadoopCompat.incrementCounter(linesReadCounter, 1);
      pos_ = getLzoFilePos();
      if (line_.getLength() == 0 || line_.charAt(0) == '\n') {
        HadoopCompat.incrementCounter(emptyLinesCounter, 1);
        continue;
      }
      if (line_.getLength() >= maxLineLen) {
        HadoopCompat.incrementCounter(truncatedLinesCounter, 1);
      }

      M protoValue = null;

      errorTracker.incRecords();

      try {
        protoValue = converter_.fromBytes(Base64Codec.decodeFast(line_.getBytes(), line_.getLength()));
      } catch(DecodeException t1) {
        HadoopCompat.incrementCounter(recordErrorsCounter, 1);
        errorTracker.incErrors(t1);
      }

      if (protoValue == null) {
        HadoopCompat.incrementCounter(recordsSkippedCounter, 1);
        continue;
      }

      HadoopCompat.incrementCounter(recordsReadCounter, 1);
      value_.set(protoValue);
      return true;
    }

    return false;
  }
@Override
  public boolean nextKeyValue() throws IOException, InterruptedException {
    // Since the lzop codec reads everything in lzo blocks, we can't stop if pos == end.
    // Instead we wait for the next block to be read in, when pos will be > end.
    while (pos_ <= end_) {
      key_.set(pos_);

      int newSize = lineReader_.readLine(line_, maxLineLen);
      if (newSize == 0) {
        return false;
      }
      HadoopCompat.incrementCounter(linesReadCounter, 1);
      pos_ = getLzoFilePos();
      if (line_.getLength() == 0 || line_.charAt(0) == '\n') {
        HadoopCompat.incrementCounter(emptyLinesCounter, 1);
        continue;
      }
      if (line_.getLength() >= maxLineLen) {
        HadoopCompat.incrementCounter(truncatedLinesCounter, 1);
      }

      M protoValue = null;

      errorTracker.incRecords();

      try {
        protoValue = converter_.fromBytes(Base64Codec.decodeFast(line_.getBytes(), line_.getLength()));
      } catch(DecodeException t1) {
        HadoopCompat.incrementCounter(recordErrorsCounter, 1);
        errorTracker.incErrors(t1);
      }

      if (protoValue == null) {
        HadoopCompat.incrementCounter(recordsSkippedCounter, 1);
        continue;
      }

      HadoopCompat.incrementCounter(recordsReadCounter, 1);
      value_.set(protoValue);
      return true;
    }

    return false;
  }
Read the next key, value pair.
<p>
A small fraction of bad records in input are tolerated.
See  {@link LzoRecordReader} for more information on error handling.

@return true if a key/value pair was read
@throws IOException
@throws InterruptedException