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.
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.
828 829 830 831 832 833 834 835 836 837 838 839 840 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 828
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).
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1147
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)));
}
|
Instance Method Details
#duplicated_core_header? ⇒ Boolean
In case a core header is duplicated its name is returned as string. False otherwise.
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1067
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 }}.
935 936 937 938 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 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 935
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.
919 920 921 922 923 924 925 926 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 919
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
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 883
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.
868 869 870 871 872 873 874 875 876 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 868
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.
1010 1011 1012 1013 1014 1015 1016 1017 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1010
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.
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1100
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.
1050 1051 1052 1053 1054 1055 1056 1057 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1050
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.
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1030
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
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1121
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)) {
/*printf("--- if (! (parser->contact_is_valid == 1 && parser->num_contact == 1)) returns false\n");
printf("--- parser->num_contact = %d\n", parser->num_contact);*/
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.
850 851 852 853 854 855 856 857 858 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 850
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;
}
|