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.
818 819 820 821 822 823 824 825 826 827 828 829 830 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 818
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).
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1137
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.
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1057
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 }}.
925 926 927 928 929 930 931 932 933 934 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 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 925
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.
909 910 911 912 913 914 915 916 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 909
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
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 873
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.
858 859 860 861 862 863 864 865 866 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 858
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.
1000 1001 1002 1003 1004 1005 1006 1007 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1000
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.
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1090
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.
1040 1041 1042 1043 1044 1045 1046 1047 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1040
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.
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1020
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
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 1111
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.
840 841 842 843 844 845 846 847 848 |
# File 'ext/sip_parser/sip_parser_ruby.c', line 840
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;
}
|