#include #include #include "log.h" #include #include "parse_common.h" #include "parse_extensions.h" /** * some header's body = [option-tag *(COMMA option-tag) * token = 1*(alphanum / "-" / "." / "!" / "%" / "*" * / "_" / "+" / "`" / "'" / "~" ) */ int parse_extension(const char *begin, int len) { // simple, for now: only one extension to parse here if (len == SIP_HDR_LEN(SIP_EXT_100REL) && memcmp(begin, SIP_EXT_100REL, len) == 0) return SIP_EXTENSION_100REL; return 0; } bool parse_extensions(unsigned *extensions, const char *start, int len) { const char *begin; const char *pos; int ext; unsigned mask = 0; enum { EAT_WS, OVER_TAG, } state = EAT_WS; begin = 0; //g++ happy for (pos = start; pos < start + len; pos ++) { switch (*pos) { case ' ': case '\t': case ',': case CR: case LF: if (state == OVER_TAG) { assert(begin); if ((ext = parse_extension(begin, pos - begin))) mask |= ext; // reset stuff state = EAT_WS; begin = 0; } break; default: if (! IS_TOKEN(*pos)) { INFO("invalid extensions header content <%.*s>: illegal char `%c'", len, start, *pos); return false; } if (state == EAT_WS) { state = OVER_TAG; begin = pos; } } } if (begin) { if ((ext = parse_extension(begin, pos - begin))) mask |= ext; } *extensions = mask; DBG("mask of parsed extensions: 0x%x.\n", mask); return true; }