PJSIP开发手册之解析器(四)

来源:互联网 发布:log4j2 打印sql 编辑:程序博客网 时间:2024/05/02 04:58

第四章 解析器

下面PJSIP解析器的一些特征:

1. 它是自顶而下,手写的解析器。它使用了PJLIB的扫描器,此scanner速度很快,并减轻了解析器的复杂性。这样增加解析器可读性。

2. 如上所述,执行速度很快。在一台P412.6GHz机器上,1秒钟可以解析68k800bytesSIP消息或860k个80bytesde 的URIs。

3. 它是可重入的。这使它在多处理器的机器上具有扩展性。

4. 它具有可扩展性。可以使用模块向解析器插入新的URI或头部域。

解析器采用了许多可以想到的技巧来获取最高性能:

1. 它对所有消息元素使用零拷贝。即当一个元素(如pvalue解析后,解析器并不会拷贝pvalue的内容到消息中的相应字段,而只是将指针和长度存放到消息中相应的字段中。这样做,是因为PJSIP在整个库中使用pj_str_t类型,不需要字符串以NULL结尾。

2. 它使用PJSIP的内存池(pj_pool_t)来为消息结构的内存分配。这比传统的malloc()函数快了好几倍。

3. 它使用零同步。解析器是可以重入的,因此不需要同步功能。

4. 它使用PJLIBtry/catch异常框架。这不仅大大简化了解析器的错误检查。使用异常框架,只需要在解析器的最顶部安装一个异常处理器即可。

PJSIP没有实现的一个特征是懒解析”。在早期的设计阶段,我们决定不实现它的原因如下:

1. 它会使事情变复杂,特别是错误处理。使用懒解析后,在后期阶段程序需要访问特定的消息元素时,如果解析器解析失败,基本上程序的各个部分都要准备处理错误情况。

2. 后来,我们相信PJSIP解析器很快而且不需要懒解析。尽管这样说,PJSIP解析器对一些应用,有一些可以打开的开关,用来忽略对一些头部域的解析(如代理服务器它不需要检查一些头部域类型)。

函数

PJSIP主要的解析器在<pjsip/sip_parser.h>中声明,在<pjsip/sip_parser.c>中定义。库的其它部分可能提供其它解析功能和扩展解析器(如<pjsip/sip_tel_uri.c>提供了解析TELURI的函数,并把这个函数注册到主解析器)

 

消息解析


检查缓存buf中到来的包是否包含一个合法的SIP消息。当一个合法的SIP消息被检测到,将消息的大小存到msg_size中。如果指定了is_datagram,则这个函数将一直返回PJ_SUCCESS

注意,此函数期望的缓存是以NULL结尾。


解析一个缓存到SIP消息。解析器要等到至少SIP请求/状态行已经被成功解析之后,才返回消息。如果err_list参数不为NULL,解析过程中遇到错误将会放入err_list参数中。

注意,此函数期望的缓存是以NULL结尾。


解析一个缓存到SIP消息。解析器要等到至少SIP请求/状态行已经被成功解析之后,才返回消息。除此之外,这个函数更新rdata中的msg_info中的头部域指针。

注意,此函数期望的缓存是以NULL结尾。

URI解析


 

解析一个缓存到SIP URI。如果option设置为PJSIP_PARSER_URI_AS_NAMEADDRESS,这个函数将包装成命名地址。如果option设置为PJSIP_PARSER_URI_IN_FROM_TO_HDR,且URI没有包含在括号内,函数将不会解析URI之后的参数(它将被认为是头部域参数,而不是URI参数)

此函数可以解析任何PJSIP库可以识别的URI类型,并根据模式可以返回正确的URI实例。

注意,此函数期望的缓存是以NULL结尾。

头部域解析

根据头部域类型hname,以行的方式解析头部域内容(即冒号后面的头部域部分)。它返回正确的头部域实例。

注意,此函数期望的缓存是以NULL结尾。


解析在input缓存中的找到的多个头部域,并把结果放入hdr_list中。此函数期望头部域以换行符(如在SIP消息)或以’&‘分隔符(如在URI中)来分隔。最后一个头部域的分隔符是可选的。

注意,此函数期望的缓存是以NULL结尾。

扩展解析

解析器可以注册新的函数指针来解析新的类型的头部域或新的类型的URI


注册新的函数来解析一个新的类型的SIP消息头部域。





1 0