grib/src/main/java/ucar/nc2/grib/grib2/Grib2RecordScanner.java
private boolean nextRepeating() throws IOException {
    raf.seek(repeatPos);

    GribNumbers.int4(raf); // skip octets 1-4
    int section = raf.read(); // find out what section this is
    raf.seek(repeatPos); // back to beginning of section

    if (section == 2) {
      repeatRecord.setLus(new Grib2SectionLocalUse(raf));
      repeatRecord.setGdss(new Grib2SectionGridDefinition(raf));
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else if (section == 3) {
      repeatRecord.setGdss(new Grib2SectionGridDefinition(raf));
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else if (section == 4) {
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else {
      if (debugRepeat) logger.debug(" REPEAT Terminate %d%n", section);
      lastPos = repeatPos; // start next scan from here
      repeatPos = -1;
      repeatRecord = null;
      repeatBms = null;
      return false;
    }

    // look for repeating bms
    Grib2SectionBitMap bms = repeatRecord.getBitmapSection();
    if (bms.getBitMapIndicator() == 254) {
      // replace BMS with last good one
      if (repeatBms == null)
        throw new IllegalStateException("No bms in repeating section");
      repeatRecord.setBms(repeatBms, true);
      //debug
      if (debugRepeat) logger.debug("replaced bms %d%n", section);
      repeatRecord.repeat += 1000;

    } else if (bms.getBitMapIndicator() == 0) {
      // track last good bms
      repeatBms = repeatRecord.getBitmapSection();
    }

    // keep only unique gds
    if ((section == 2) || (section == 3)) {
      // look for duplicate gds
      Grib2SectionGridDefinition gds = repeatRecord.getGDSsection();
      long crc = gds.calcCRC();
      Grib2SectionGridDefinition gdsCached = gdsMap.get(crc);
      if (gdsCached != null)
        repeatRecord.setGdss(gdsCached);
      else
        gdsMap.put(crc, gds);
    }

   // check to see if we are at the end
    long pos = raf.getFilePointer();
    long ending = repeatRecord.getIs().getEndPos();
    if (pos+34 < ending) { // give it 30 bytes of slop
      if (debugRepeat) logger.debug(" REPEAT AGAIN %d != %d%n", pos+4, ending);
      repeatPos = pos;
      return true;
    }

    if (debug) logger.debug(" REPEAT read until %d grib ending at %d header ='%s'%n", raf.getFilePointer(), ending, StringUtil2.cleanup(header));

    // check that end section is correct
    raf.seek(ending-4);
    for (int i = 0; i < 4; i++) {
      if (raf.read() != 55) {
        String clean = StringUtil2.cleanup(header);
        if (clean.length() > 40) clean = clean.substring(0,40) + "...";
        logger.warn("  REPEAT Missing End of GRIB message at pos=" + ending + " header= " + clean+" for="+raf.getLocation());
        break;
      }
    }
    lastPos = raf.getFilePointer();

    if (debugRepeat) logger.debug(" REPEAT DONE%n");
    repeatPos = -1; // no more repeats in this record
    return true;
  }
private boolean nextRepeating() throws IOException {
    raf.seek(repeatPos);

    GribNumbers.int4(raf); // skip octets 1-4
    int section = raf.read(); // find out what section this is
    raf.seek(repeatPos); // back to beginning of section

    if (section == 2) {
      repeatRecord.setLus(new Grib2SectionLocalUse(raf));
      repeatRecord.setGdss(new Grib2SectionGridDefinition(raf));
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else if (section == 3) {
      repeatRecord.setGdss(new Grib2SectionGridDefinition(raf));
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else if (section == 4) {
      repeatRecord.setPdss(new Grib2SectionProductDefinition(raf));
      repeatRecord.setDrs(new Grib2SectionDataRepresentation(raf));
      repeatRecord.setBms(new Grib2SectionBitMap(raf), false);
      repeatRecord.setDataSection(new Grib2SectionData(raf));
      repeatRecord.repeat = section;

    } else {
      if (debugRepeat) logger.debug(" REPEAT Terminate %d%n", section);
      lastPos = repeatPos; // start next scan from here
      repeatPos = -1;
      repeatRecord = null;
      repeatBms = null;
      return false;
    }

    // look for repeating bms
    Grib2SectionBitMap bms = repeatRecord.getBitmapSection();
    if (bms.getBitMapIndicator() == 254) {
      // replace BMS with last good one
      if (repeatBms == null)
        throw new IllegalStateException("No bms in repeating section");
      repeatRecord.setBms(repeatBms, true);
      //debug
      if (debugRepeat) logger.debug("replaced bms %d%n", section);
      repeatRecord.repeat += 1000;

    } else if (bms.getBitMapIndicator() == 0) {
      // track last good bms
      repeatBms = repeatRecord.getBitmapSection();
    }

    // keep only unique gds
    if ((section == 2) || (section == 3)) {
      // look for duplicate gds
      Grib2SectionGridDefinition gds = repeatRecord.getGDSsection();
      long crc = gds.calcCRC();
      Grib2SectionGridDefinition gdsCached = gdsMap.get(crc);
      if (gdsCached != null)
        repeatRecord.setGdss(gdsCached);
      else
        gdsMap.put(crc, gds);
    }

   // check to see if we are at the end
    long pos = raf.getFilePointer();
    long ending = repeatRecord.getIs().getEndPos();
    if (pos+34 < ending) { // give it 30 bytes of slop
      if (debugRepeat) logger.debug(" REPEAT AGAIN %d != %d%n", pos+4, ending);
      repeatPos = pos;
      return true;
    }

    if (debug) logger.debug(" REPEAT read until %d grib ending at %d header ='%s'%n", raf.getFilePointer(), ending, StringUtil2.cleanup(header));

    // check that end section is correct
    raf.seek(ending-4);
    for (int i = 0; i < 4; i++) {
      if (raf.read() != 55) {
        String clean = StringUtil2.cleanup(header);
        if (clean.length() > 40) clean = clean.substring(0,40) + "...";
        logger.warn("  REPEAT Missing End of GRIB message at pos=" + ending + " header= " + clean+" for="+raf.getLocation());
        break;
      }
    }
    lastPos = raf.getFilePointer();

    if (debugRepeat) logger.debug(" REPEAT DONE%n");
    repeatPos = -1; // no more repeats in this record
    return true;
  }
private boolean nextRepeating ( ) throws IOException { raf . seek ( repeatPos ) ; GribNumbers . int4 ( raf ) ; // skip octets 1-4
 int section = raf . read ( ) ; // find out what section this is
 raf . seek ( repeatPos ) ; // back to beginning of section
 if ( section == 2 ) { repeatRecord . setLus ( new Grib2SectionLocalUse ( raf ) ) ; repeatRecord . setGdss ( new Grib2SectionGridDefinition ( raf ) ) ; repeatRecord . setPdss ( new Grib2SectionProductDefinition ( raf ) ) ; repeatRecord . setDrs ( new Grib2SectionDataRepresentation ( raf ) ) ; repeatRecord . setBms ( new Grib2SectionBitMap ( raf ) , false ) ; repeatRecord . setDataSection ( new Grib2SectionData ( raf ) ) ; repeatRecord . repeat = section ; } else if ( section == 3 ) { repeatRecord . setGdss ( new Grib2SectionGridDefinition ( raf ) ) ; repeatRecord . setPdss ( new Grib2SectionProductDefinition ( raf ) ) ; repeatRecord . setDrs ( new Grib2SectionDataRepresentation ( raf ) ) ; repeatRecord . setBms ( new Grib2SectionBitMap ( raf ) , false ) ; repeatRecord . setDataSection ( new Grib2SectionData ( raf ) ) ; repeatRecord . repeat = section ; } else if ( section == 4 ) { repeatRecord . setPdss ( new Grib2SectionProductDefinition ( raf ) ) ; repeatRecord . setDrs ( new Grib2SectionDataRepresentation ( raf ) ) ; repeatRecord . setBms ( new Grib2SectionBitMap ( raf ) , false ) ; repeatRecord . setDataSection ( new Grib2SectionData ( raf ) ) ; repeatRecord . repeat = section ; } else { if ( debugRepeat ) logger . debug ( " REPEAT Terminate %d%n" , section ) ; lastPos = repeatPos ; // start next scan from here
 repeatPos = - 1 ; repeatRecord = null ; repeatBms = null ; return false ; } // look for repeating bms
 Grib2SectionBitMap bms = repeatRecord . getBitmapSection ( ) ; if ( bms . getBitMapIndicator ( ) == 254 ) { // replace BMS with last good one
 if ( repeatBms == null ) throw new IllegalStateException ( "No bms in repeating section" ) ; repeatRecord . setBms ( repeatBms , true ) ; //debug
 if ( debugRepeat ) logger . debug ( "replaced bms %d%n" , section ) ; repeatRecord . repeat += 1000 ; } else if ( bms . getBitMapIndicator ( ) == 0 ) { // track last good bms
 repeatBms = repeatRecord . getBitmapSection ( ) ; } // keep only unique gds
 if ( ( section == 2 ) || ( section == 3 ) ) { // look for duplicate gds
 Grib2SectionGridDefinition gds = repeatRecord . getGDSsection ( ) ; long crc = gds . calcCRC ( ) ; Grib2SectionGridDefinition gdsCached = gdsMap . get ( crc ) ; if ( gdsCached != null ) repeatRecord . setGdss ( gdsCached ) ; else gdsMap . put ( crc , gds ) ; } // check to see if we are at the end
 long pos = raf . getFilePointer ( ) ; long ending = repeatRecord . getIs ( ) . getEndPos ( ) ; if ( pos + 34 < ending ) { // give it 30 bytes of slop
 if ( debugRepeat ) logger . debug ( " REPEAT AGAIN %d != %d%n" , pos + 4 , ending ) ; repeatPos = pos ; return true ; } if ( debug ) logger . debug ( " REPEAT read until %d grib ending at %d header ='%s'%n" , raf . getFilePointer ( ) , ending , StringUtil2 . cleanup ( header ) ) ; // check that end section is correct
 raf . seek ( ending - 4 ) ; for ( int i = 0 ; i < 4 ; i ++ ) { if ( raf . read ( ) != 55 ) { String clean = StringUtil2 . cleanup ( header ) ; if ( clean . length ( ) > 40 ) clean = clean . substring ( 0 , 40 ) + "..." ; logger . warn ( "  REPEAT Missing End of GRIB message at pos=" + ending + " header= " + clean + " for=" + raf . getLocation ( ) ) ; break ; } } lastPos = raf . getFilePointer ( ) ; if ( debugRepeat ) logger . debug ( " REPEAT DONE%n" ) ; repeatPos = - 1 ; // no more repeats in this record
 return true ; }
side effect is that the new record is in repeatRecord
side effect is that the new record is in repeatRecord