public static SipHeader nextHeader ( final Buffer buffer ) throws SipParseException { try { final int startIndex = buffer . getReaderIndex ( ) ; int nameIndex = 0 ; while ( buffer . hasReadableBytes ( ) && nameIndex == 0 ) { if ( isNext ( buffer , SP ) || isNext ( buffer , HTAB ) || isNext ( buffer , COLON ) ) { nameIndex = buffer . getReaderIndex ( ) ; } else { buffer . readByte ( ) ; } } // Bad header! No HCOLON found! (or beginning thereof anyway) if ( nameIndex == 0 ) { // probably ran out of bytes to read so lets just return null return null ; } final Buffer name = buffer . slice ( startIndex , nameIndex ) ; expectHCOLON ( buffer ) ; // Note, we are framing headers from a sip request or response which // is why we safely can assume that there will ALWAYS be a CRLF // after each line Buffer valueBuffer = buffer . readLine ( ) ; // Folded lines are rare so try and avoid the bulk of // the work if possible. if ( isNext ( buffer , SP ) || isNext ( buffer , HTAB ) ) { List < Buffer > foldedLines = null ; boolean done = false ; while ( ! done ) { if ( isNext ( buffer , SP ) || isNext ( buffer , HTAB ) ) { consumeWS ( buffer ) ; if ( foldedLines == null ) { foldedLines = new ArrayList < Buffer > ( 2 ) ; } foldedLines . add ( buffer . readLine ( ) ) ; } else { done = true ; } } if ( foldedLines != null ) { // even though stupid, folded lines are not that common // so optimize if this ever becomes a problem. String stupid = valueBuffer . toString ( ) ; for ( final Buffer line : foldedLines ) { stupid += " " + line . toString ( ) ; } valueBuffer = Buffers . wrap ( stupid . getBytes ( Charset . forName ( "UTF-8" ) ) ) ; consumeWS ( valueBuffer ) ; } } return new SipHeaderImpl ( name , valueBuffer ) ; } catch ( final IOException e ) { throw new SipParseException ( buffer . getReaderIndex ( ) , UNABLE_TO_READ_FROM_STREAM , e ) ; } }
Get the next header which may actually be returning multiple if there are multiple headers on the same line .