/* TODO: be more tolerant regarding unmatched character in the needle. * Right now, we implicitly accept unmatched characters at the end of the * needle but absolutely not at the start. e.g. "xpy" won't match "python" at * all, though "pyx" will. */ static inline gint get_score (const gchar *needle, const gchar *haystack) { if (! needle || ! haystack) { return needle == NULL; } else if (! *needle || ! *haystack) { return *needle == 0; } if (IS_SEPARATOR (*haystack)) { return get_score (needle + IS_SEPARATOR (*needle), haystack + 1); } if (IS_SEPARATOR (*needle)) { return get_score (needle + 1, next_separator (haystack)); } if (*needle == *haystack) { gint a = get_score (needle + 1, haystack + 1) + 1 + IS_SEPARATOR (haystack[1]); gint b = get_score (needle, next_separator (haystack)); return MAX (a, b); } else { return get_score (needle, next_separator (haystack)); } }
int __osip_generic_param_parseall (osip_list_t * gen_params, const char *params) { char *pname; char *pvalue; const char *comma; const char *equal; /* find '=' wich is the separator for one param */ /* find ';' wich is the separator for multiple params */ equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); while (comma != NULL) { if (equal == NULL) { equal = comma; pvalue = NULL; } else { const char *tmp; /* check for NULL param with an '=' character */ tmp = equal + 1; for (; *tmp == '\t' || *tmp == ' '; tmp++) { } pvalue = NULL; if (*tmp != ',' && *tmp != '\0') { if (comma - equal < 2) return -1; pvalue = (char *) osip_malloc (comma - equal); if (pvalue == NULL) return -1; osip_strncpy (pvalue, equal + 1, comma - equal - 1); } } if (equal - params < 2) { osip_free (pvalue); return -1; } pname = (char *) osip_malloc (equal - params); if (pname == NULL) { osip_free (pvalue); return -1; } osip_strncpy (pname, params + 1, equal - params - 1); osip_generic_param_add (gen_params, pname, pvalue); params = comma; equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); } /* this is the last header (comma==NULL) */ comma = params + strlen (params); if (equal == NULL) { equal = comma; /* at the end */ pvalue = NULL; if (equal - params < 2) { osip_free (pvalue); return 0; /* empty comma? */ } } else { const char *tmp; /* check for NULL param with an '=' character */ tmp = equal + 1; for (; *tmp == '\t' || *tmp == ' '; tmp++) { } pvalue = NULL; if (*tmp != ',' && *tmp != '\0') { if (comma - equal < 2) return -1; pvalue = (char *) osip_malloc (comma - equal); if (pvalue == NULL) return -1; osip_strncpy (pvalue, equal + 1, comma - equal - 1); } } if (equal - params < 2) { osip_free (pvalue); return -1; } pname = (char *) osip_malloc (equal - params); if (pname == NULL) { osip_free (pvalue); return -1; } osip_strncpy (pname, params + 1, equal - params - 1); osip_generic_param_add (gen_params, pname, pvalue); return 0; }
int osip_uri_parse_params (osip_uri_t * url, const char *params) { char *pname; char *pvalue; const char *comma; const char *equal; /* find '=' wich is the separator for one param */ /* find ';' wich is the separator for multiple params */ equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); while (comma != NULL) { if (equal == NULL) { equal = comma; pvalue = NULL; } else { if (comma - equal < 2) return -1; pvalue = (char *) osip_malloc (comma - equal); if (pvalue == NULL) return -1; osip_strncpy (pvalue, equal + 1, comma - equal - 1); __osip_uri_unescape (pvalue); } if (equal - params < 2) { osip_free (pvalue); return -1; } pname = (char *) osip_malloc (equal - params); if (pname == NULL) { osip_free (pvalue); return -1; } osip_strncpy (pname, params + 1, equal - params - 1); __osip_uri_unescape (pname); osip_uri_uparam_add (url, pname, pvalue); params = comma; equal = next_separator (params + 1, '=', ';'); comma = strchr (params + 1, ';'); } /* this is the last header (comma==NULL) */ comma = params + strlen (params); if (equal == NULL) { equal = comma; /* at the end */ pvalue = NULL; } else { if (comma - equal < 2) return -1; pvalue = (char *) osip_malloc (comma - equal); if (pvalue == NULL) return -1; osip_strncpy (pvalue, equal + 1, comma - equal - 1); } if (equal - params < 2) { osip_free (pvalue); return -1; } pname = (char *) osip_malloc (equal - params); if (pname == NULL) { osip_free (pvalue); return -1; } osip_strncpy (pname, params + 1, equal - params - 1); osip_uri_uparam_add (url, pname, pvalue); return 0; }
/* return -1 on error */ int osip_uri_parse (osip_uri_t * url, const char *buf) { char *username; char *password; char *host; const char *port; const char *params; const char *headers; const char *tmp; /* basic tests */ if (buf == NULL || buf[0] == '\0') return -1; tmp = strchr (buf, ':'); if (tmp == NULL) return -1; if (tmp - buf < 2) return -1; url->scheme = (char *) osip_malloc (tmp - buf + 1); if (url->scheme == NULL) return -1; osip_strncpy (url->scheme, buf, tmp - buf); if (strlen (url->scheme) < 3 || (0 != osip_strncasecmp (url->scheme, "sip", 3) && 0 != osip_strncasecmp (url->scheme, "sips", 4))) { /* Is not a sipurl ! */ size_t i = strlen (tmp + 1); if (i < 2) return -1; url->string = (char *) osip_malloc (i + 1); if (url->string == NULL) return -1; osip_strncpy (url->string, tmp + 1, i); return 0; } /* law number 1: if ('?' exists && is_located_after '@') or if ('?' exists && '@' is not there -no username-) =====> HEADER_PARAM EXIST =====> start at index(?) =====> end at the end of url */ /* find the beginning of host */ username = strchr (buf, ':'); /* if ':' does not exist, the url is not valid */ if (username == NULL) return -1; host = strchr (buf, '@'); if (host == NULL) host = username; else if (username[1] == '@') /* username is empty */ host = username + 1; else /* username exists */ { password = next_separator (username + 1, ':', '@'); if (password == NULL) password = host; else /* password exists */ { if (host - password < 2) return -1; url->password = (char *) osip_malloc (host - password); if (url->password == NULL) return -1; osip_strncpy (url->password, password + 1, host - password - 1); __osip_uri_unescape (url->password); } if (password - username < 2) return -1; { url->username = (char *) osip_malloc (password - username); if (url->username == NULL) return -1; osip_strncpy (url->username, username + 1, password - username - 1); __osip_uri_unescape (url->username); } } /* search for header after host */ headers = strchr (host, '?'); if (headers == NULL) headers = buf + strlen (buf); else /* headers exist */ osip_uri_parse_headers (url, headers); /* search for params after host */ params = strchr (host, ';'); /* search for params after host */ if (params == NULL) params = headers; else /* params exist */ { char *tmpbuf; if (headers - params + 1 < 2) return -1; tmpbuf = osip_malloc (headers - params + 1); if (tmpbuf == NULL) return -1; tmpbuf = osip_strncpy (tmpbuf, params, headers - params); osip_uri_parse_params (url, tmpbuf); osip_free (tmpbuf); } port = params - 1; while (port > host && *port != ']' && *port != ':') port--; if (*port == ':') { if (host == port) port = params; else { if ((params - port < 2) || (params - port > 8)) return -1; /* error cases */ url->port = (char *) osip_malloc (params - port); if (url->port == NULL) return -1; osip_clrncpy (url->port, port + 1, params - port - 1); } } else port = params; /* adjust port for ipv6 address */ tmp = port; while (tmp > host && *tmp != ']') tmp--; if (*tmp == ']') { port = tmp; while (host < port && *host != '[') host++; if (host >= port) return -1; } if (port - host < 2) return -1; url->host = (char *) osip_malloc (port - host); if (url->host == NULL) return -1; osip_clrncpy (url->host, host + 1, port - host - 1); return 0; }
list<str *> *str::split(str *sp, int max_splits) { __GC_STRING s = unit; int num_splits = 0; int sep_iter = 0, tmp, chunk_iter = 0; list<str *> *result = new list<str *>(); if (sp == NULL) { #define next_separator(iter) (s.find_first_of(ws, (iter))) #define skip_separator(iter) (s.find_first_not_of(ws, (iter))) if(skip_separator(chunk_iter) == -1) /* XXX */ return result; if(next_separator(chunk_iter) == 0) chunk_iter = skip_separator(chunk_iter); while((max_splits < 0 or num_splits < max_splits) and ((sep_iter = next_separator(chunk_iter)) != -1)) { result->append(new str(s.substr(chunk_iter, sep_iter - chunk_iter))); if((tmp = skip_separator(sep_iter)) == -1) { chunk_iter = sep_iter; break; } else chunk_iter = tmp; ++num_splits; } if(not (max_splits < 0 or num_splits < max_splits)) result->append(new str(s.substr(chunk_iter, s.size()-chunk_iter))); else if(sep_iter == -1) result->append(new str(s.substr(chunk_iter, s.size()-chunk_iter))); #undef next_separator #undef skip_separator } else { /* given separator (slightly different algorithm required) * (python is very inconsistent in this respect) */ const char *sep = sp->unit.c_str(); int sep_size = sp->unit.size(); #define next_separator(iter) s.find(sep, (iter)) #define skip_separator(iter) ((iter + sep_size) > s.size()? -1 : (iter + sep_size)) if (max_splits == 0) { result->append(this); return result; } if(next_separator(chunk_iter) == 0) { chunk_iter = skip_separator(chunk_iter); result->append(new str()); ++num_splits; } while((max_splits < 0 or num_splits < max_splits) and (sep_iter = next_separator(chunk_iter)) != -1) { result->append(new str(s.substr(chunk_iter, sep_iter - chunk_iter))); if((tmp = skip_separator(sep_iter)) == -1) { chunk_iter = sep_iter; break; } else chunk_iter = tmp; ++num_splits; } if(not (max_splits < 0 or num_splits < max_splits)) result->append(new str(s.substr(chunk_iter, s.size()-chunk_iter))); else if(sep_iter == -1) result->append(new str(s.substr(chunk_iter, s.size()-chunk_iter))); #undef next_separator #undef skip_separator } return result; }