Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Conditions Of Use
   *
   * This software was developed by employees of the National Institute of
   * Standards and Technology (NIST), an agency of the Federal Government.
   * Pursuant to title 15 Untied States Code Section 105, works of NIST
   * employees are not subject to copyright protection in the United States
   * and are considered to be in the public domain.  As a result, a formal
   * license is not needed to use the software.
  *
  * This software is provided by NIST as a service and is expressly
  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
  * AND DATA ACCURACY.  NIST does not warrant or make any representations
  * regarding the use of the software or the results thereof, including but
  * not limited to the correctness, accuracy, reliability or usefulness of
  * the software.
  *
  * Permission to use this software is contingent upon your acceptance
  * of the terms of this agreement
  *
  * .
  *
  */

Product of NIST/ITL Advanced Networking Technologies Division (ANTD) * /
 
 
 package gov.nist.javax.sip.parser;
 
 
 /*
  * Acknowledgement: 1/12/2007: Yanick Belanger rewrote the parsing loops to make them
  * simpler and quicker.
  */

Parse SIP message and parts of SIP messages such as URI's etc from memory and return a structure. Intended use: UDP message processing. This class is used when you have an entire SIP message or SIPHeader or SIP URL in memory and you want to generate a parsed structure from it. For SIP messages, the payload can be binary or String. If you have a binary payload, use parseSIPMessage(byte[]) else use parseSIPMessage(String) The payload is accessible from the parsed message using the getContent and getContentBytes methods provided by the SIPMessage class. If SDP parsing is enabled using the parseContent method, then the SDP body is also parsed and can be accessed from the message using the getSDPAnnounce method. Currently only eager parsing of the message is supported (i.e. the entire message is parsed in one feld swoop).

Author(s):
M. Ranganathan
Version:
1.2 $Revision: 1.27 $ $Date: 2010-03-15 17:01:21 $
 
 public class StringMsgParser implements MessageParser {
 
     protected boolean readBody;
     protected String rawStringMessage;
     private boolean strict;
 
     protected static boolean computeContentLengthFromMessage = false;

    

Since:
v0.9
 
     public StringMsgParser() {
         super();
          = true;
     }

    
Constructor (given a parse exception handler).

Parameters:
exhandler is the parse exception listener for the message parser.
Since:
1.0
 
     public StringMsgParser(ParseExceptionListener exhandler) {
         this();
          = exhandler;
    }

    
Add a handler for header parsing errors.

Parameters:
pexhandler is a class that implements the ParseExceptionListener interface.
    public void setParseExceptionListener(ParseExceptionListener pexhandler) {
         = pexhandler;
    }

    
Parse a buffer containing a single SIP Message where the body is an array of un-interpreted bytes. This is intended for parsing the message from a memory buffer when the buffer. Incorporates a bug fix for a bug that was noted by Will Sullin of Callcast

Parameters:
msgBuffer a byte buffer containing the messages to be parsed. This can consist of multiple SIP Messages concatenated together.
Returns:
a SIPMessage[] structure (request or response) containing the parsed SIP message.
Throws:
java.text.ParseException is thrown when an illegal message has been encountered (and the rest of the buffer is discarded).
See also:
ParseExceptionListener
    public SIPMessage parseSIPMessage(byte[] msgBufferthrows ParseException {
        if (msgBuffer == null || msgBuffer.length == 0)
            return null;
        int i = 0;
        // Squeeze out any leading control character.
        try {
            while (msgBuffer[i] < 0x20)
                i++;
        }
        catch (ArrayIndexOutOfBoundsException e) {
            // Array contains only control char, return null.
            return null;
        }
        // Iterate thru the request/status line and headers.
        String currentLine = null;
        String currentHeader = null;
        boolean isFirstLine = true;
        SIPMessage message = null;
        do
        {
            int lineStart = i;
            // Find the length of the line.
            try {
                while (msgBuffer[i] != '\r' && msgBuffer[i] != '\n')
                    i++;
            }
            catch (ArrayIndexOutOfBoundsException e) {
                // End of the message.
                break;
            }
            int lineLength = i - lineStart;
            // Make it a String.
            try {
                currentLine = new String(msgBufferlineStartlineLength"UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new ParseException("Bad message encoding!", 0);
            }
            currentLine = trimEndOfLine(currentLine);
            if (currentLine.length() == 0) {
                // Last header line, process the previous buffered header.
                if (currentHeader != null && message != null) {
                     processHeader(currentHeadermessage);
                 }
            }
            else {
                if (isFirstLine) {
                    message = processFirstLine(currentLine);
                } else {
                    char firstChar = currentLine.charAt(0);
                    if (firstChar == '\t' || firstChar == ' ') {
                        if (currentHeader == null)
                            throw new ParseException("Bad header continuation.", 0);
                        // This is a continuation, append it to the previous line.
                        currentHeader += currentLine.substring(1);
                    }
                    else {
                        if (currentHeader != null && message != null) {
                             processHeader(currentHeadermessage);
                         }
                        currentHeader = currentLine;
                    }
                }
            }
            if (msgBuffer[i] == '\r' && msgBuffer.length > i+1 && msgBuffer[i+1] == '\n')
                i++;
            i++;
            isFirstLine = false;
        } while (currentLine.length() > 0); // End do - while
        if (message == nullthrow new ParseException("Bad message", 0);
        message.setSize(i);
        if ( && message.getContentLength() != null &&
                message.getContentLength().getContentLength() != 0) {
            int bodyLength = msgBuffer.length - i;
            byte[] body = new byte[bodyLength];
            System.arraycopy(msgBufferibody, 0, bodyLength);
            message.setMessageContent(body, ,message.getContentLength().getContentLength() );
        }
        return message;
    }

    
Parse a buffer containing one or more SIP Messages and return an array of SIPMessage parsed structures.

Parameters:
msgString a String containing the messages to be parsed. This can consist of multiple SIP Messages concatenated together.
Returns:
a SIPMessage structure (request or response) containing the parsed SIP message.
Throws:
java.text.ParseException is thrown when an illegal message has been encountered (and the rest of the buffer is discarded).
See also:
ParseExceptionListener
    public SIPMessage parseSIPMessage(String msgStringthrows ParseException {
        if (msgString == null || msgString.length() == 0)
            return null;
         = msgString;
        int i = 0;
        // Squeeze out any leading control character.
        try {
            while (msgString.charAt(i) < 0x20)
                i++;
        }
        catch (ArrayIndexOutOfBoundsException e) {
            // Array contains only control char, return null.
            return null;
        } catch (StringIndexOutOfBoundsException ex) {
            return null;
        }
        // Iterate thru the request/status line and headers.
        String currentLine = null;
        String currentHeader = null;
        boolean isFirstLine = true;
        SIPMessage message = null;
        do
        {
            int lineStart = i;
            // Find the length of the line.
            try {
                char c = msgString.charAt(i);
                while (c != '\r' && c != '\n')
                    c = msgString.charAt(++i);
            }
            catch (ArrayIndexOutOfBoundsException e) {
                // End of the message.
                break;
            } catch ( StringIndexOutOfBoundsException ex) {
                break;
            }
            // Make it a String.
            currentLine = msgString.substring(lineStarti);
            currentLine = trimEndOfLine(currentLine);
            if (currentLine.length() == 0) {
                // Last header line, process the previous buffered header.
                if (currentHeader != null) {
                    processHeader(currentHeadermessage);
                }
            }
            else {
                if (isFirstLine) {
                    message = processFirstLine(currentLine);
                } else {
                    char firstChar = currentLine.charAt(0);
                    if (firstChar == '\t' || firstChar == ' ') {
                        if (currentHeader == null)
                            throw new ParseException("Bad header continuation.", 0);
                        // This is a continuation, append it to the previous line.
                        currentHeader += currentLine.substring(1);
                    }
                    else {
                        if (currentHeader != null) {
                            processHeader(currentHeadermessage);
                        }
                        currentHeader = currentLine;
                    }
                }
            }
            if (msgString.charAt(i) == '\r' && msgString.length() > i+1 && msgString.charAt(i+1) == '\n')
                i++;
            i++;
            isFirstLine = false;
        }
        while (currentLine.length() > 0);
        message.setSize(i);
        // Check for content legth header
        if ( && message.getContentLength() != null ) {
            if ( message.getContentLength().getContentLength() != 0) {
                String body = msgString.substring(i);
                message.setMessageContent(body,this.,,message.getContentLength().getContentLength());
             } else if (! && message.getContentLength().getContentLength() == 0 && !msgString.endsWith("\r\n\r\n") ){
                 if (  ) {
                     throw new ParseException("Extraneous characters at the end of the message ",i);
                 }
             } 
        }
        return message;
    }
    protected static String trimEndOfLine(String line) {
        if (line == null)
            return line;
        int i = line.length() - 1;
        while (i >= 0 && line.charAt(i) <= 0x20)
            i--;
        if (i == line.length() - 1)
            return line;
        if (i == -1)
            return "";
        return line.substring(0, i+1);
    }
    private SIPMessage processFirstLine(String firstLinethrows ParseException {
        SIPMessage message;
        if (!firstLine.startsWith(.)) {
            message = new SIPRequest();
            try {
                RequestLine requestLine = new RequestLineParser(firstLine + "\n")
                        .parse();
                ((SIPRequestmessage).setRequestLine(requestLine);
            } catch (ParseException ex) {
                if (this. != null)
                    this..handleException(exmessage,
                            RequestLine.classfirstLine);
                else
                    throw ex;
            }
        } else {
            message = new SIPResponse();
            try {
                StatusLine sl = new StatusLineParser(firstLine + "\n").parse();
                ((SIPResponsemessage).setStatusLine(sl);
            } catch (ParseException ex) {
                if (this. != null) {
                    this..handleException(exmessage,
                            StatusLine.classfirstLine);
                } else
                    throw ex;
            }
        }
        return message;
    }
    protected void processHeader(String headerSIPMessage messagethrows ParseException {
        if (header == null || header.length() == 0)
            return;
        HeaderParser headerParser = null;
        try {
            headerParser = ParserFactory.createParser(header + "\n");
        } catch (ParseException ex) {
            this..handleException(exmessagenull,
                    header);
            return;
        }
        try {
            SIPHeader sipHeader = headerParser.parse();
            message.attachHeader(sipHeaderfalse);
        } catch (ParseException ex) {
            if (this. != null) {
                String headerName = Lexer.getHeaderName(header);
                Class headerClass = NameMap.getClassFromName(headerName);
                if (headerClass == null) {
                    headerClass = ExtensionHeaderImpl.class;
                }
                this..handleException(exmessage,
                        headerClassheader);
            }
        }
    }

    
Parse an address (nameaddr or address spec) and return and address structure.

Parameters:
address is a String containing the address to be parsed.
Returns:
a parsed address structure.
Throws:
java.text.ParseException when the address is badly formatted.
Since:
v1.0
    public AddressImpl parseAddress(String addressthrows ParseException {
        AddressParser addressParser = new AddressParser(address);
        return addressParser.address(true);
    }

    
Parse a host:port and return a parsed structure.

Parameters:
hostport is a String containing the host:port to be parsed
Returns:
a parsed address structure.
Throws:
throws a ParseException when the address is badly formatted. public HostPort parseHostPort(String hostport) throws ParseException { Lexer lexer = new Lexer("charLexer", hostport); return new HostNameParser(lexer).hostPort(); }
Since:
v1.0


    
Parse a host name and return a parsed structure.

Parameters:
host is a String containing the host name to be parsed
Returns:
a parsed address structure.
Throws:
java.text.ParseException a ParseException when the hostname is badly formatted.
Since:
v1.0
    public Host parseHost(String hostthrows ParseException {
        Lexer lexer = new Lexer("charLexer"host);
        return new HostNameParser(lexer).host();
    }

    
Parse a telephone number return a parsed structure.

Parameters:
telephone_number is a String containing the telephone # to be parsed
Returns:
a parsed address structure.
Throws:
java.text.ParseException a ParseException when the address is badly formatted.
Since:
v1.0
    public TelephoneNumber parseTelephoneNumber(String telephone_number)
            throws ParseException {
        // Bug fix contributed by Will Scullin
        return new URLParser(telephone_number).parseTelephoneNumber(true);
    }

    
Parse a SIP url from a string and return a URI structure for it.

Parameters:
url a String containing the URI structure to be parsed.
Returns:
A parsed URI structure
Throws:
java.text.ParseException if there was an error parsing the message.
    public SipUri parseSIPUrl(String urlthrows ParseException {
        try {
            return new URLParser(url).sipURL(true);
        } catch (ClassCastException ex) {
            throw new ParseException(url + " Not a SIP URL ", 0);
        }
    }

    
Parse a uri from a string and return a URI structure for it.

Parameters:
url a String containing the URI structure to be parsed.
Returns:
A parsed URI structure
Throws:
java.text.ParseException if there was an error parsing the message.
    public GenericURI parseUrl(String urlthrows ParseException {
        return new URLParser(url).parse();
    }

    
Parse an individual SIP message header from a string.

Parameters:
header String containing the SIP header.
Returns:
a SIPHeader structure.
Throws:
java.text.ParseException if there was an error parsing the message.
    public SIPHeader parseSIPHeader(String headerthrows ParseException {
        int start = 0;
        int end = header.length() - 1;
        try {
            // Squeeze out any leading control character.
            while (header.charAt(start) <= 0x20)
                start++;
            // Squeeze out any trailing control character.
            while (header.charAt(end) <= 0x20)
                end--;
        }
        catch (ArrayIndexOutOfBoundsException e) {
            // Array contains only control char.
            throw new ParseException("Empty header.", 0);
        }
        StringBuffer buffer = new StringBuffer(end + 1);
        int i = start;
        int lineStart = start;
        boolean endOfLine = false;
        while (i <= end) {
            char c = header.charAt(i);
            if (c == '\r' || c == '\n') {
                if (!endOfLine) {
                    buffer.append(header.substring(lineStarti));
                    endOfLine = true;
                }
            }
            else {
                if (endOfLine) {
                    endOfLine = false;
                    if (c == ' ' || c == '\t') {
                        buffer.append(' ');
                        lineStart = i + 1;
                    }
                    else {
                        lineStart = i;
                    }
                }
            }
            i++;
        }
        buffer.append(header.substring(lineStarti));
        buffer.append('\n');
        HeaderParser hp = ParserFactory.createParser(buffer.toString());
        if (hp == null)
            throw new ParseException("could not create parser", 0);
        return hp.parse();
    }

    
Parse the SIP Request Line

Parameters:
requestLine a String containing the request line to be parsed.
Returns:
a RequestLine structure that has the parsed RequestLine
Throws:
java.text.ParseException if there was an error parsing the requestLine.
    public RequestLine parseSIPRequestLine(String requestLine)
            throws ParseException {
        requestLine += "\n";
        return new RequestLineParser(requestLine).parse();
    }

    
Parse the SIP Response message status line

Parameters:
statusLine a String containing the Status line to be parsed.
Returns:
StatusLine class corresponding to message
Throws:
java.text.ParseException if there was an error parsing
See also:
gov.nist.javax.sip.header.StatusLine
    public StatusLine parseSIPStatusLine(String statusLine)
            throws ParseException {
        statusLine += "\n";
        return new StatusLineParser(statusLine).parse();
    }
    public static void setComputeContentLengthFromMessage(
            boolean computeContentLengthFromMessage) {
        . = computeContentLengthFromMessage;
    }



    
Test code.
    public static void main(String[] argsthrows ParseException {
        String messages[] = {
                "SIP/2.0 200 OK\r\n"
                        + "To: \"The Little Blister\" <sip:LittleGuy@there.com>;tag=469bc066\r\n"
                        + "From: \"The Master Blaster\" <sip:BigGuy@here.com>;tag=11\r\n"
                        + "Via: SIP/2.0/UDP 139.10.134.246:5060;branch=z9hG4bK8b0a86f6_1030c7d18e0_17;received=139.10.134.246\r\n"
                        + "Call-ID: 1030c7d18ae_a97b0b_b@8b0a86f6\r\n"
                        + "CSeq: 1 SUBSCRIBE\r\n"
                        + "Contact: <sip:172.16.11.162:5070>\r\n"
                        + "Content-Length: 0\r\n\r\n",
                "SIP/2.0 180 Ringing\r\n"
                        + "Via: SIP/2.0/UDP 172.18.1.29:5060;branch=z9hG4bK43fc10fb4446d55fc5c8f969607991f4\r\n"
                        + "To: \"0440\" <sip:0440@212.209.220.131>;tag=2600\r\n"
                        + "From: \"Andreas\" <sip:andreas@e-horizon.se>;tag=8524\r\n"
                        + "Call-ID: f51a1851c5f570606140f14c8eb64fd3@172.18.1.29\r\n"
                        + "CSeq: 1 INVITE\r\n" + "Max-Forwards: 70\r\n"
                        + "Record-Route: <sip:212.209.220.131:5060>\r\n"
                        + "Content-Length: 0\r\n\r\n",
                "REGISTER sip:nist.gov SIP/2.0\r\n"
                        + "Via: SIP/2.0/UDP 129.6.55.182:14826\r\n"
                        + "Max-Forwards: 70\r\n"
                        + "From: <sip:mranga@nist.gov>;tag=6fcd5c7ace8b4a45acf0f0cd539b168b;epid=0d4c418ddf\r\n"
                        + "To: <sip:mranga@nist.gov>\r\n"
                        + "Call-ID: c5679907eb954a8da9f9dceb282d7230@129.6.55.182\r\n"
                        + "CSeq: 1 REGISTER\r\n"
                        + "Contact: <sip:129.6.55.182:14826>;methods=\"INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER\"\r\n"
                        + "User-Agent: RTC/(Microsoft RTC)\r\n"
                        + "Event:  registration\r\n"
                        + "Allow-Events: presence\r\n"
                        + "Content-Length: 0\r\n\r\n"
                        + "INVITE sip:littleguy@there.com:5060 SIP/2.0\r\n"
                        + "Via: SIP/2.0/UDP 65.243.118.100:5050\r\n"
                        + "From: M. Ranganathan  <sip:M.Ranganathan@sipbakeoff.com>;tag=1234\r\n"
                        + "To: \"littleguy@there.com\" <sip:littleguy@there.com:5060> \r\n"
                        + "Call-ID: Q2AboBsaGn9!?x6@sipbakeoff.com \r\n"
                        + "CSeq: 1 INVITE \r\n"
                        + "Content-Length: 247\r\n\r\n"
                        + "v=0\r\n"
                        + "o=4855 13760799956958020 13760799956958020 IN IP4  129.6.55.78\r\n"
                        + "s=mysession session\r\n" + "p=+46 8 52018010\r\n"
                        + "c=IN IP4  129.6.55.78\r\n" + "t=0 0\r\n"
                        + "m=audio 6022 RTP/AVP 0 4 18\r\n"
                        + "a=rtpmap:0 PCMU/8000\r\n"
                        + "a=rtpmap:4 G723/8000\r\n"
                        + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n" };
        class ParserThread implements Runnable {
            String[] messages;
            public ParserThread(String[] messagesToParse) {
                this. = messagesToParse;
            }
            public void run() {
                for (int i = 0; i < .i++) {
                    StringMsgParser smp = new StringMsgParser();
                    try {
                        SIPMessage sipMessage = smp
                                .parseSIPMessage([i]);
                        ..println(" i = " + i + " branchId = "
                                + sipMessage.getTopmostVia().getBranch());
                        // System.out.println("encoded " +
                        // sipMessage.toString());
                    } catch (ParseException ex) {
                    }
                    // System.out.println("dialog id = " +
                    // sipMessage.getDialogId(false));
                }
            }
        }
        for (int i = 0; i < 20; i++) {
            new Thread(new ParserThread(messages)).start();
        }
    }
    public void setStrict(boolean strict) {
       this. = strict;
        
    }
	public void setReadBody(boolean readBody) {
		this. = readBody;
	}
New to GrepCode? Check out our FAQ X