static NdefRecord[] parse(ByteBuffer buffer,boolean ignoreMbMe) throws FormatException {
  List<NdefRecord> records=new ArrayList<NdefRecord>();
  try {
    byte[] type=null;
    byte[] id=null;
    byte[] payload=null;
    ArrayList<byte[]> chunks=new ArrayList<byte[]>();
    boolean inChunk=false;
    short chunkTnf=-1;
    boolean me=false;
    while (!me) {
      byte flag=buffer.get();
      boolean mb=(flag & NdefRecord.FLAG_MB) != 0;
      me=(flag & NdefRecord.FLAG_ME) != 0;
      boolean cf=(flag & NdefRecord.FLAG_CF) != 0;
      boolean sr=(flag & NdefRecord.FLAG_SR) != 0;
      boolean il=(flag & NdefRecord.FLAG_IL) != 0;
      short tnf=(short)(flag & 0x07);
      if (!mb && records.size() == 0 && !inChunk && !ignoreMbMe) {
        throw new FormatException("expected MB flag");
      }
 else       if (mb && records.size() != 0 && !ignoreMbMe) {
        throw new FormatException("unexpected MB flag");
      }
 else       if (inChunk && il) {
        throw new FormatException("unexpected IL flag in non-leading chunk");
      }
 else       if (cf && me) {
        throw new FormatException("unexpected ME flag in non-trailing chunk");
      }
 else       if (inChunk && tnf != NdefRecord.TNF_UNCHANGED) {
        throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
      }
 else       if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
        throw new FormatException("" + "unexpected TNF_UNCHANGED in first chunk or unchunked record");
      }
      int typeLength=buffer.get() & 0xFF;
      long payloadLength=sr ? (buffer.get() & 0xFF) : (buffer.getInt() & 0xFFFFFFFFL);
      int idLength=il ? (buffer.get() & 0xFF) : 0;
      if (inChunk && typeLength != 0) {
        throw new FormatException("expected zero-length type in non-leading chunk");
      }
      if (!inChunk) {
        type=(typeLength > 0 ? new byte[typeLength] : EMPTY_BYTE_ARRAY);
        id=(idLength > 0 ? new byte[idLength] : EMPTY_BYTE_ARRAY);
        buffer.get(type);
        buffer.get(id);
      }
      ensureSanePayloadSize(payloadLength);
      payload=(payloadLength > 0 ? new byte[(int)payloadLength] : EMPTY_BYTE_ARRAY);
      buffer.get(payload);
      if (cf && !inChunk) {
        chunks.clear();
        chunkTnf=tnf;
      }
      if (cf || inChunk) {
        chunks.add(payload);
      }
      if (!cf && inChunk) {
        payloadLength=0;
        for (        byte[] p : chunks) {
          payloadLength+=p.length;
        }
        ensureSanePayloadSize(payloadLength);
        payload=new byte[(int)payloadLength];
        int i=0;
        for (        byte[] p : chunks) {
          System.arraycopy(p,0,payload,i,p.length);
          i+=p.length;
        }
        tnf=chunkTnf;
      }
      if (cf) {
        inChunk=true;
        continue;
      }
 else {
        inChunk=false;
      }
      String error=validateTnf(tnf,type,id,payload);
      if (error != null) {
        throw new FormatException(error);
      }
      records.add(new NdefRecord(tnf,type,id,payload));
      if (ignoreMbMe) {
        break;
      }
    }
  }
 catch (  BufferUnderflowException e) {
    throw new FormatException("expected more data",e);
  }
  return records.toArray(new NdefRecord[records.size()]);
}

static NdefRecord [ ] parse ( ByteBuffer buffer , boolean ignoreMbMe ) throws FormatException { List < NdefRecord > records = new ArrayList < NdefRecord > ( ) ; try { byte [ ] type = null ; byte [ ] id = null ; byte [ ] payload = null ; ArrayList < byte [ ] > chunks = new ArrayList < byte [ ] > ( ) ; boolean inChunk = false ; short chunkTnf = - 1 ; boolean me = false ; while ( ! me ) { byte flag = buffer . get ( ) ; boolean mb = ( flag & NdefRecord . FLAG_MB ) != 0 ; me = ( flag & NdefRecord . FLAG_ME ) != 0 ; boolean cf = ( flag & NdefRecord . FLAG_CF ) != 0 ; boolean sr = ( flag & NdefRecord . FLAG_SR ) != 0 ; boolean il = ( flag & NdefRecord . FLAG_IL ) != 0 ; short tnf = ( short ) ( flag & 0x07 ) ; if ( ! mb && records . size ( ) == 0 && ! inChunk && ! ignoreMbMe ) { throw new FormatException ( "expected MB flag" ) ; } else if ( mb && records . size ( ) != 0 && ! ignoreMbMe ) { throw new FormatException ( "unexpected MB flag" ) ; } else if ( inChunk && il ) { throw new FormatException ( "unexpected IL flag in non-leading chunk" ) ; } else if ( cf && me ) { throw new FormatException ( "unexpected ME flag in non-trailing chunk" ) ; } else if ( inChunk && tnf != NdefRecord . TNF_UNCHANGED ) { throw new FormatException ( "expected TNF_UNCHANGED in non-leading chunk" ) ; } else if ( ! inChunk && tnf == NdefRecord . TNF_UNCHANGED ) { throw new FormatException ( "" + "unexpected TNF_UNCHANGED in first chunk or unchunked record" ) ; } int typeLength = buffer . get ( ) & 0xFF ; long payloadLength = sr ? ( buffer . get ( ) & 0xFF ) : ( buffer . getInt ( ) & 0xFFFFFFFFL ) ; int idLength = il ? ( buffer . get ( ) & 0xFF ) : 0 ; if ( inChunk && typeLength != 0 ) { throw new FormatException ( "expected zero-length type in non-leading chunk" ) ; } if ( ! inChunk ) { type = ( typeLength > 0 ? new byte [ typeLength ] : EMPTY_BYTE_ARRAY ) ; id = ( idLength > 0 ? new byte [ idLength ] : EMPTY_BYTE_ARRAY ) ; buffer . get ( type ) ; buffer . get ( id ) ; } ensureSanePayloadSize ( payloadLength ) ; payload = ( payloadLength > 0 ? new byte [ ( int ) payloadLength ] : EMPTY_BYTE_ARRAY ) ; buffer . get ( payload ) ; if ( cf && ! inChunk ) { chunks . clear ( ) ; chunkTnf = tnf ; } if ( cf || inChunk ) { chunks . add ( payload ) ; } if ( ! cf && inChunk ) { payloadLength = 0 ; for ( byte [ ] p : chunks ) { payloadLength += p . length ; } ensureSanePayloadSize ( payloadLength ) ; payload = new byte [ ( int ) payloadLength ] ; int i = 0 ; for ( byte [ ] p : chunks ) { System . arraycopy ( p , 0 , payload , i , p . length ) ; i += p . length ; } tnf = chunkTnf ; } if ( cf ) { inChunk = true ; continue ; } else { inChunk = false ; } String error = validateTnf ( tnf , type , id , payload ) ; if ( error != null ) { throw new FormatException ( error ) ; } records . add ( new NdefRecord ( tnf , type , id , payload ) ) ; if ( ignoreMbMe ) { break ; } } } catch ( BufferUnderflowException e ) { throw new FormatException ( "expected more data" , e ) ; } return records . toArray ( new NdefRecord [ records . size ( ) ] ) ; }
main record parsing method . < p > expects ndefmessage to begin immediately , allows trailing data . < p > currently has strict validation of all fields as per ndef 1 . 0 specification section 2 . 5 . we will attempt to keep this as strict as possible to encourage well - formatted ndef . < p > always returns 1 or more ndefrecord ' s , or throws formatexception .
