summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2017-01-11 04:38:29 +0000
committerRiza Sulistyo <riza@teluu.com>2017-01-11 04:38:29 +0000
commit8610e097171150a4b4b07e397bcdab07c63fb279 (patch)
treed64dbef33ec3fc4a4fed048f609842ccf5e4d668
parent1fe4df081023310e673fd9d9949f4b54ba691731 (diff)
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
-rw-r--r--pjlib/include/pj/string.h87
-rw-r--r--pjlib/src/pj/os_info.c18
-rw-r--r--pjlib/src/pj/string.c107
-rw-r--r--pjmedia/src/pjmedia/transport_ice.c68
-rw-r--r--pjmedia/src/pjmedia/transport_srtp.c51
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<maxtok;
- ++i, tok=strtok(NULL, ".-"))
+ delim = pj_str(".-");
+ for (found_idx = pj_strtok(&in_str, &delim, &token, 0), i=0;
+ found_idx != in_str.slen && i < maxtok;
+ ++i, found_idx = pj_strtok(&in_str, &delim, &token,
+ found_idx + token.slen))
{
int n;
- if (!pj_isdigit(*tok))
+ if (!pj_isdigit(*token.ptr))
break;
- n = atoi(tok);
+ n = atoi(token.ptr);
version |= (n << ((3-i)*8));
}
diff --git a/pjlib/src/pj/string.c b/pjlib/src/pj/string.c
index d62b674a..307cfb47 100644
--- a/pjlib/src/pj/string.c
+++ b/pjlib/src/pj/string.c
@@ -28,6 +28,113 @@
# include <pj/string_i.h>
#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"));