From 8610e097171150a4b4b07e397bcdab07c63fb279 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Wed, 11 Jan 2017 04:38:29 +0000 Subject: Re 1989: Implement pj_strtok()/pj_strtok() as a replacement to strtok(). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5520 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/string.h | 87 ++++++++++++++++++++++++++++ pjlib/src/pj/os_info.c | 18 +++--- pjlib/src/pj/string.c | 107 +++++++++++++++++++++++++++++++++++ pjmedia/src/pjmedia/transport_ice.c | 68 +++++++++++----------- pjmedia/src/pjmedia/transport_srtp.c | 51 ++++++++--------- 5 files changed, 263 insertions(+), 68 deletions(-) diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h index cfbdd458..70a1d6c8 100644 --- a/pjlib/include/pj/string.h +++ b/pjlib/include/pj/string.h @@ -474,6 +474,93 @@ PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr) return (char*) memchr((char*)str->ptr, chr, str->slen); } + +/** + * Find the first index of character, in a string, that does not belong to a + * set of characters. + * + * @param str The string. + * @param set_char The string containing the set of characters. + * + * @return the index of the first character in the str that doesn't belong to + * set_char. If str starts with a character not in set_char, return 0. + */ +PJ_DECL(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char); + + +/** + * Find the first index of character, in a string, that does not belong to a + * set of characters. + * + * @param str The string. + * @param set_char The string containing the set of characters. + * + * @return the index of the first character in the str that doesn't belong to + * set_char. If str starts with a character not in set_char, return 0. + */ +PJ_DECL(pj_ssize_t) pj_strspn2(const pj_str_t *str, const char *set_char); + + +/** + * Find the first index of character, in a string, that belong to a set of + * characters. + * + * @param str The string. + * @param set_char The string containing the set of characters. + * + * @return the index of the first character in the str that belong to + * set_char. If no match is found, return the length of str. + */ +PJ_DECL(pj_ssize_t) pj_strcspn(const pj_str_t *str, const pj_str_t *set_char); + + +/** + * Find the first index of character, in a string, that belong to a set of + * characters. + * + * @param str The string. + * @param set_char The string containing the set of characters. + * + * @return the index of the first character in the str that belong to + * set_char. If no match is found, return the length of str. + */ +PJ_DECL(pj_ssize_t) pj_strcspn2(const pj_str_t *str, const char *set_char); + + +/** + * Find tokens from a string using the delimiter. + * + * @param str The string. + * @param delim The string containing the delimiter. It might contain + * multiple character treated as unique set. If same character + * was found on the set, it will be skipped. + * @param tok The string containing the token. + * @param start_idx The search will start from this index. + * + * @return the index of token from the str, or the length of the str + * if the token is not found. + */ +PJ_DECL(pj_ssize_t) pj_strtok(const pj_str_t *str, const pj_str_t *delim, + pj_str_t *tok, pj_size_t start_idx); + + +/** + * Find tokens from a string using the delimiter. + * + * @param str The string. + * @param delim The string containing the delimiter. It might contain + * multiple character treated as unique set. If same character + * was found on the set, it will be skipped. + * @param tok The string containing the token. + * @param start_idx The search will start from this index. + * + * @return the index of token from the str, or the length of the str + * if the token is not found. + */ +PJ_DECL(pj_ssize_t) pj_strtok2(const pj_str_t *str, const char *delim, + pj_str_t *tok, pj_size_t start_idx); + + /** * Find the occurence of a substring substr in string str. * diff --git a/pjlib/src/pj/os_info.c b/pjlib/src/pj/os_info.c index 514ff242..3bf11670 100644 --- a/pjlib/src/pj/os_info.c +++ b/pjlib/src/pj/os_info.c @@ -98,24 +98,28 @@ static char *ver_info(pj_uint32_t ver, char *buf) } static pj_uint32_t parse_version(char *str) -{ - char *tok; - int i, maxtok; +{ + int i, maxtok, found_idx; pj_uint32_t version = 0; + pj_str_t in_str = pj_str(str); + pj_str_t token, delim; while (*str && !pj_isdigit(*str)) str++; maxtok = 4; - for (tok = strtok(str, ".-"), i=0; tok && i #endif +PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char) +{ + pj_ssize_t i, j, count = 0; + for (i = 0; i < str->slen; i++) { + if (count != i) + break; + + for (j = 0; j < set_char->slen; j++) { + if (str->ptr[i] == set_char->ptr[j]) + count++; + } + } + return count; +} + + +PJ_DEF(pj_ssize_t) pj_strspn2(const pj_str_t *str, const char *set_char) +{ + pj_ssize_t i, j, count = 0; + for (i = 0; i < str->slen; i++) { + if (count != i) + break; + + for (j = 0; set_char[j] != 0; j++) { + if (str->ptr[i] == set_char[j]) + count++; + } + } + return count; +} + + +PJ_DEF(pj_ssize_t) pj_strcspn(const pj_str_t *str, const pj_str_t *set_char) +{ + pj_ssize_t i, j; + for (i = 0; i < str->slen; i++) { + for (j = 0; j < set_char->slen; j++) { + if (str->ptr[i] == set_char->ptr[j]) + return i; + } + } + return i; +} + + +PJ_DECL(pj_ssize_t) pj_strcspn2(const pj_str_t *str, const char *set_char) +{ + pj_ssize_t i, j; + for (i = 0; i < str->slen; i++) { + for (j = 0; set_char[j] != 0; j++) { + if (str->ptr[i] == set_char[j]) + return i; + } + } + return i; +} + + +PJ_DEF(pj_ssize_t) pj_strtok(const pj_str_t *str, const pj_str_t *delim, + pj_str_t *tok, pj_size_t start_idx) +{ + pj_ssize_t str_idx; + + tok->slen = 0; + if ((str->slen == 0) || ((pj_size_t)str->slen < start_idx)) { + return str->slen; + } + + tok->ptr = str->ptr + start_idx; + tok->slen = str->slen - start_idx; + + str_idx = pj_strspn(tok, delim); + if (start_idx+str_idx == (pj_size_t)str->slen) { + return str->slen; + } + tok->ptr += str_idx; + tok->slen -= str_idx; + + tok->slen = pj_strcspn(tok, delim); + return start_idx + str_idx; +} + + +PJ_DECL(pj_ssize_t) pj_strtok2(const pj_str_t *str, const char *delim, + pj_str_t *tok, pj_size_t start_idx) +{ + pj_ssize_t str_idx; + + tok->slen = 0; + if ((str->slen == 0) || ((pj_size_t)str->slen < start_idx)) { + return str->slen; + } + + tok->ptr = str->ptr + start_idx; + tok->slen = str->slen - start_idx; + + str_idx = pj_strspn2(tok, delim); + if (start_idx + str_idx == (pj_size_t)str->slen) { + return str->slen; + } + tok->ptr += str_idx; + tok->slen -= str_idx; + + tok->slen = pj_strcspn2(tok, delim); + return start_idx + str_idx; +} + PJ_DEF(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr) { diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c index 5876aea8..9630537d 100644 --- a/pjmedia/src/pjmedia/transport_ice.c +++ b/pjmedia/src/pjmedia/transport_ice.c @@ -671,111 +671,109 @@ static pj_status_t parse_cand(const char *obj_name, const pj_str_t *orig_input, pj_ice_sess_cand *cand) { - pj_str_t input; - char *token, *host; - int af; - pj_str_t s; + pj_str_t token, delim, host; + int af, found_idx; pj_status_t status = PJNATH_EICEINCANDSDP; pj_bzero(cand, sizeof(*cand)); - pj_strdup_with_null(pool, &input, orig_input); PJ_UNUSED_ARG(obj_name); /* Foundation */ - token = strtok(input.ptr, " "); - if (!token) { + delim = pj_str(" "); + found_idx = pj_strtok(orig_input, &delim, &token, 0); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE foundation in candidate")); goto on_return; } - pj_strdup2(pool, &cand->foundation, token); + pj_strdup(pool, &cand->foundation, &token); /* Component ID */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE component ID in candidate")); goto on_return; } - cand->comp_id = (pj_uint8_t) atoi(token); + cand->comp_id = (pj_uint8_t)pj_strtoul(&token); /* Transport */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE transport in candidate")); goto on_return; } - if (pj_ansi_stricmp(token, "UDP") != 0) { + if (pj_stricmp2(&token, "UDP") != 0) { TRACE__((obj_name, "Expecting ICE UDP transport only in candidate")); goto on_return; } /* Priority */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE priority in candidate")); goto on_return; } - cand->prio = atoi(token); + cand->prio = pj_strtoul(&token); /* Host */ - host = strtok(NULL, " "); - if (!host) { + found_idx = pj_strtok(orig_input, &delim, &host, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE host in candidate")); goto on_return; } /* Detect address family */ - if (pj_ansi_strchr(host, ':')) + if (pj_strchr(&host, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); /* Assign address */ - if (pj_sockaddr_init(af, &cand->addr, pj_cstr(&s, host), 0)) { + if (pj_sockaddr_init(af, &cand->addr, &host, 0)) { TRACE__((obj_name, "Invalid ICE candidate address")); goto on_return; } /* Port */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + host.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE port number in candidate")); goto on_return; } - pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)atoi(token)); + pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)pj_strtoul(&token)); /* typ */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE \"typ\" in candidate")); goto on_return; } - if (pj_ansi_stricmp(token, "typ") != 0) { + if (pj_stricmp2(&token, "typ") != 0) { TRACE__((obj_name, "Expecting ICE \"typ\" in candidate")); goto on_return; } /* candidate type */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(orig_input, &delim, &token, found_idx + token.slen); + if (found_idx == orig_input->slen) { TRACE__((obj_name, "Expecting ICE candidate type in candidate")); goto on_return; } - if (pj_ansi_stricmp(token, "host") == 0) { + if (pj_stricmp2(&token, "host") == 0) { cand->type = PJ_ICE_CAND_TYPE_HOST; - } else if (pj_ansi_stricmp(token, "srflx") == 0) { + } else if (pj_stricmp2(&token, "srflx") == 0) { cand->type = PJ_ICE_CAND_TYPE_SRFLX; - } else if (pj_ansi_stricmp(token, "relay") == 0) { + } else if (pj_stricmp2(&token, "relay") == 0) { cand->type = PJ_ICE_CAND_TYPE_RELAYED; - } else if (pj_ansi_stricmp(token, "prflx") == 0) { + } else if (pj_stricmp2(&token, "prflx") == 0) { cand->type = PJ_ICE_CAND_TYPE_PRFLX; } else { - PJ_LOG(5,(obj_name, "Invalid ICE candidate type %s in candidate", - token)); + PJ_LOG(5,(obj_name, "Invalid ICE candidate type %.*s in candidate", + token.slen, token.ptr)); goto on_return; } diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c index 1e4e57c7..699eaeb2 100644 --- a/pjmedia/src/pjmedia/transport_srtp.c +++ b/pjmedia/src/pjmedia/transport_srtp.c @@ -1216,63 +1216,62 @@ static pj_status_t parse_attr_crypto(pj_pool_t *pool, pjmedia_srtp_crypto *crypto, int *tag) { - pj_str_t input; - char *token; - pj_str_t tmp; + pj_str_t token, delim; pj_status_t status; - int itmp, token_len; + int itmp, found_idx; pj_bzero(crypto, sizeof(*crypto)); - pj_strdup_with_null(pool, &input, &attr->value); /* Tag */ - token = strtok(input.ptr, " "); - if (!token) { + delim = pj_str(" "); + found_idx = pj_strtok(&attr->value, &delim, &token, 0); + if (found_idx == attr->value.slen) { PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag")); return PJMEDIA_SDP_EINATTR; } - token_len = pj_ansi_strlen(token); /* Tag must not use leading zeroes. */ - if (token_len > 1 && *token == '0') + if (token.slen > 1 && *token.ptr == '0') return PJMEDIA_SDP_EINATTR; /* Tag must be decimal, i.e: contains only digit '0'-'9'. */ - for (itmp = 0; itmp < token_len; ++itmp) - if (!pj_isdigit(token[itmp])) + for (itmp = 0; itmp < token.slen; ++itmp) + if (!pj_isdigit(token.ptr[itmp])) return PJMEDIA_SDP_EINATTR; /* Get tag value. */ - *tag = atoi(token); + *tag = pj_strtoul(&token); /* Crypto-suite */ - token = strtok(NULL, " "); - if (!token) { + found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen); + if (found_idx == attr->value.slen) { PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite")); return PJMEDIA_SDP_EINATTR; } - crypto->name = pj_str(token); + crypto->name = token; /* Key method */ - token = strtok(NULL, ":"); - if (!token) { + delim = pj_str(": "); + found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen); + if (found_idx == attr->value.slen) { PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method")); return PJMEDIA_SDP_EINATTR; } - if (pj_ansi_stricmp(token, "inline")) { - PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!", - token)); + if (pj_stricmp2(&token, "inline")) { + PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%.*s' " + "not supported!", token.slen, token.ptr)); return PJMEDIA_SDP_EINATTR; } - /* Key */ - token = strtok(NULL, "| "); - if (!token) { + /* Key */ + delim = pj_str("| "); + found_idx = pj_strtok(&attr->value, &delim, &token, found_idx+token.slen); + if (found_idx == attr->value.slen) { PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key")); return PJMEDIA_SDP_EINATTR; } - tmp = pj_str(token); - if (PJ_BASE64_TO_BASE256_LEN(tmp.slen) > MAX_KEY_LEN) { + + if (PJ_BASE64_TO_BASE256_LEN(token.slen) > MAX_KEY_LEN) { PJ_LOG(4,(THIS_FILE, "Key too long")); return PJMEDIA_SRTP_EINKEYLEN; } @@ -1280,7 +1279,7 @@ static pj_status_t parse_attr_crypto(pj_pool_t *pool, /* Decode key */ crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN); itmp = MAX_KEY_LEN; - status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, + status = pj_base64_decode(&token, (pj_uint8_t*)crypto->key.ptr, &itmp); if (status != PJ_SUCCESS) { PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64")); -- cgit v1.2.3