Class: OverSIP::SIP::MessageParser
- Inherits:
-
Object
- Object
- OverSIP::SIP::MessageParser
- Defined in:
- ext/sip_parser/sip_parser_ruby.c
Class Method Summary collapse
-
.OverSIP::SIP::MessageParser.headarize ⇒ String
Tries to lookup the header name in a list of well-known headers.
- .OverSIP::SIP::MessageParser.parse_uri(string) ⇒ OverSIP::SIP::Uri
Instance Method Summary collapse
-
#duplicated_core_header? ⇒ Boolean
In case a core header is duplicated its name is returned as string.
-
#error ⇒ String
Returns a String showing the error by enclosing the exact wrong char between }}.
-
#error? ⇒ Boolean
Tells you whether the parser is in an error state.
- #execute(buffer, start) ⇒ Integer
-
#finish ⇒ Object
Finishes a parser early which could put in a “good” or bad state.
-
#finished? ⇒ Boolean
Tells you whether the parser is finished or not and in a good state.
-
#new ⇒ Object
constructor
Creates a new parser.
-
#missing_core_header? ⇒ Boolean
In case a core header is missing its name is returned as string.
-
#nread ⇒ Integer
Returns the amount of data processed so far during this processing cycle.
-
#parsed ⇒ OverSIP::Request, ...
Returns the parsed object.
- #post_parsing ⇒ Object
-
#reset ⇒ nil
Resets the parser to it’s initial state so that you can reuse it rather than making new ones.
Constructor Details
#new ⇒ Object
Creates a new parser.
842 843 844 845 846 847 848 849 850 851 852 853 854 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 842
VALUE SipMessageParser_init(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
sip_message_parser_init(parser);
/* NOTE: This allows the C struct to access to the VALUE element of the Ruby
MessageParser instance. */
parser->ruby_sip_parser = self;
return self;
}
|
Class Method Details
.OverSIP::SIP::MessageParser.headarize ⇒ String
Tries to lookup the header name in a list of well-known headers. If so, returns the retrieved VALUE. It also works for short headers. In case the header is unknown, it normalizes it (by capitalizing the first letter and each letter under a “-” or “_” symbol).
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1158
VALUE SipMessageParser_Class_headerize(VALUE self, VALUE string)
{
TRACE();
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
if ((RSTRING_LEN(string)) == 0)
rb_str_new(RSTRING_PTR(string), RSTRING_LEN(string));
return(headerize(RSTRING_PTR(string), RSTRING_LEN(string)));
}
|
.OverSIP::SIP::MessageParser.parse_uri(string) ⇒ OverSIP::SIP::Uri
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1175
VALUE SipMessageParser_Class_parse_uri(VALUE self, VALUE string, VALUE allow_name_addr)
{
TRACE();
char *dptr = NULL;
long dlen = 0;
sip_uri_parser *parser;
VALUE parsed;
int int_allow_name_addr;
/* Initialize the global SIP URI parser if not set yet. */
if (global_sip_uri_parser == NULL) {
/* Asign functions to the pointers of global_sip_uri_parser struct. */
global_sip_uri_parser = ALLOC(sip_uri_parser);
global_sip_uri_parser->uri.full = uri_full;
global_sip_uri_parser->uri.scheme = uri_scheme;
global_sip_uri_parser->uri.user = uri_user;
global_sip_uri_parser->uri.host = uri_host;
global_sip_uri_parser->uri.port = uri_port;
global_sip_uri_parser->uri.param = uri_param;
global_sip_uri_parser->uri.known_param = uri_known_param;
global_sip_uri_parser->uri.has_param = uri_has_param;
global_sip_uri_parser->uri.headers = uri_headers;
global_sip_uri_parser->uri.display_name = uri_display_name;
}
REQUIRE_TYPE(string, T_STRING);
/* NOTE: We need to pass a \0 terminated string to the URI parser. StringValueCStr() gives
* exactly that. So also increment dlen in 1. */
dptr = StringValueCStr(string);
dlen = RSTRING_LEN(string) + 1;
if (TYPE(allow_name_addr) == T_TRUE) {
parsed = rb_obj_alloc(cNameAddr);
int_allow_name_addr = 1;
}
else {
parsed = rb_obj_alloc(cUri);
int_allow_name_addr = 0;
}
if (sip_uri_parser_execute(global_sip_uri_parser, dptr, dlen, parsed, int_allow_name_addr) == 0)
return parsed;
else
return Qfalse;
}
|
Instance Method Details
#duplicated_core_header? ⇒ Boolean
In case a core header is duplicated its name is returned as string. False otherwise.
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1081
VALUE SipMessageParser_has_duplicated_core_header(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
/* NOTE: Good moment for counting the num of Via values and store it. */
rb_ivar_set(parser->parsed, id_num_vias, INT2FIX(parser->num_via));
if (parser->num_from > 1)
return string_From;
else if (parser->num_to > 1)
return string_To;
else if (parser->num_cseq > 1)
return string_CSeq;
else if (parser->num_call_id > 1)
return string_Call_ID;
else if (parser->num_max_forwards > 1)
return string_Max_Forwards;
else if (parser->num_content_length > 1)
return string_Content_Length;
return Qfalse;
}
|
#error ⇒ String
Returns a String showing the error by enclosing the exact wrong char between }}.
949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 949
VALUE SipMessageParser_error(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
if(sip_message_parser_has_error(parser)) {
char *parsing_error_str;
int parsing_error_str_len;
int i;
int j;
VALUE rb_error_str;
/* Duplicate error string length so '\r' and '\n' are displayed as CR and LF.
Let 6 chars more for allocating {{{ and }}}. */
parsing_error_str = ALLOC_N(char, 2*parser->error_len + 6);
parsing_error_str_len=0;
for(i=0, j=0; i < parser->error_len; i++) {
if (i != parser->error_pos) {
if (parser->error_start[i] == '\r') {
parsing_error_str[j++] = '\\';
parsing_error_str[j++] = 'r';
parsing_error_str_len += 2;
}
else if (parser->error_start[i] == '\n') {
parsing_error_str[j++] = '\\';
parsing_error_str[j++] = 'n';
parsing_error_str_len += 2;
}
else {
parsing_error_str[j++] = parser->error_start[i];
parsing_error_str_len++;
}
}
else {
parsing_error_str[j++] = '{';
parsing_error_str[j++] = '{';
parsing_error_str[j++] = '{';
if (parser->error_start[i] == '\r') {
parsing_error_str[j++] = '\\';
parsing_error_str[j++] = 'r';
parsing_error_str_len += 2;
}
else if (parser->error_start[i] == '\n') {
parsing_error_str[j++] = '\\';
parsing_error_str[j++] = 'n';
parsing_error_str_len += 2;
}
else {
parsing_error_str[j++] = parser->error_start[i];
parsing_error_str_len++;
}
parsing_error_str[j++] = '}';
parsing_error_str[j++] = '}';
parsing_error_str[j++] = '}';
parsing_error_str_len += 6;
}
}
rb_error_str = rb_str_new(parsing_error_str, parsing_error_str_len);
xfree(parsing_error_str);
return rb_error_str;
}
else
return Qnil;
}
|
#error? ⇒ Boolean
Tells you whether the parser is in an error state.
933 934 935 936 937 938 939 940 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 933
VALUE SipMessageParser_has_error(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
return sip_message_parser_has_error(parser) ? Qtrue : Qfalse;
}
|
#execute(buffer, start) ⇒ Integer
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 897
VALUE SipMessageParser_execute(VALUE self, VALUE buffer, VALUE start)
{
TRACE();
sip_message_parser *parser = NULL;
int from = 0;
char *dptr = NULL;
long dlen = 0;
REQUIRE_TYPE(buffer, T_STRING);
REQUIRE_TYPE(start, T_FIXNUM);
DATA_GET(self, sip_message_parser, parser);
from = FIX2INT(start);
dptr = RSTRING_PTR(buffer);
dlen = RSTRING_LEN(buffer);
/* This should never occur or there is an error in the parser. */
if(from >= dlen)
rb_raise(eSIPMessageParserError, "requested start is after buffer end.");
sip_message_parser_execute(parser, dptr, dlen, from);
if (sip_message_parser_has_error(parser))
return Qfalse;
else
return INT2FIX(sip_message_parser_nread(parser));
}
|
#finish ⇒ Object
Finishes a parser early which could put in a “good” or bad state. You should call reset after finish it or bad things will happen.
882 883 884 885 886 887 888 889 890 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 882
VALUE SipMessageParser_finish(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
sip_message_parser_finish(parser);
return sip_message_parser_is_finished(parser) ? Qtrue : Qfalse;
}
|
#finished? ⇒ Boolean
Tells you whether the parser is finished or not and in a good state.
1024 1025 1026 1027 1028 1029 1030 1031 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1024
VALUE SipMessageParser_is_finished(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
return sip_message_parser_is_finished(parser) ? Qtrue : Qfalse;
}
|
#missing_core_header? ⇒ Boolean
In case a core header is missing its name is returned as string. False otherwise.
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1114
VALUE SipMessageParser_has_missing_core_header(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
if (parser->num_via == 0)
return string_Via;
else if (parser->num_from == 0)
return string_From;
else if (parser->num_to == 0)
return string_To;
else if (parser->num_cseq == 0)
return string_CSeq;
else if (parser->num_call_id == 0)
return string_Call_ID;
return Qfalse;
}
|
#nread ⇒ Integer
Returns the amount of data processed so far during this processing cycle. It is set to 0 on initialize or reset calls and is incremented each time execute is called.
1064 1065 1066 1067 1068 1069 1070 1071 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1064
VALUE SipMessageParser_nread(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
return INT2FIX(parser->nread);
}
|
#parsed ⇒ OverSIP::Request, ...
Returns the parsed object. It doesn’t meant that the parsing has succedded. The returned object could be a message identified as a Request or Response or :outbound_keepalive, but later the message has been detected as invalid. So the parsed object is incomplete.
In case the parsing has failed in the first char the method returns nil.
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1044
VALUE SipMessageParser_parsed(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
/* NOTE: We can safely access here to parser->parsed as its content is also referenced
* by id_parsed so it cannot be garbage collected while the OverSIP::MessageParser
* still alives. */
return parser->parsed;
}
|
#post_parsing ⇒ Object
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1135
VALUE SipMessageParser_post_parsing(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
/* We just parse Contact if it's a single header with a single Name Addr within it. */
if (! (parser->contact_is_valid == 1 && parser->num_contact == 1))
rb_ivar_set(parser->parsed, id_contact, Qnil);
return Qnil;
}
|
#reset ⇒ nil
Resets the parser to it’s initial state so that you can reuse it rather than making new ones.
864 865 866 867 868 869 870 871 872 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 864
VALUE SipMessageParser_reset(VALUE self)
{
TRACE();
sip_message_parser *parser = NULL;
DATA_GET(self, sip_message_parser, parser);
sip_message_parser_init(parser);
return Qnil;
}
|