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.
832 833 834 835 836 837 838 839 840 841 842 843 844 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 832
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).
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1148
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
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 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 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1165
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.
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1071
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 }}.
939 940 941 942 943 944 945 946 947 948 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 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 939
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.
923 924 925 926 927 928 929 930 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 923
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
887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 887
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.
872 873 874 875 876 877 878 879 880 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 872
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.
1014 1015 1016 1017 1018 1019 1020 1021 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1014
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.
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1104
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.
1054 1055 1056 1057 1058 1059 1060 1061 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1054
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.
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1034
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
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1125
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.
854 855 856 857 858 859 860 861 862 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 854
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;
}
|