From f3ae1b4116ab553076f70407d565318a75e52846 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sat, 11 Sep 2010 15:29:23 -0300 Subject: [PATCH] Added UpnpString_cmp() and UpnpString_casecmp() methods to UpnpString. UpnpString_set_String() and UpnpString_set_StringN now return error values. String lenghts are size_t. (cherry picked from commit 81b28fbb9073b8b3ea5724e5b7c11b29c44f9be4) --- upnp/inc/UpnpString.h | 46 +++++++++++++++++++++++--- upnp/src/api/UpnpString.c | 69 +++++++++++++++++++++++++++++++++------ 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/upnp/inc/UpnpString.h b/upnp/inc/UpnpString.h index 0942f67..58d8210 100644 --- a/upnp/inc/UpnpString.h +++ b/upnp/inc/UpnpString.h @@ -24,6 +24,9 @@ #include "UpnpGlobal.h" /* for EXPORT_SPEC */ +#include /* for size_t */ + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -76,11 +79,22 @@ EXPORT_SPEC void UpnpString_assign( * * \return The length of the string. * */ -EXPORT_SPEC int UpnpString_get_Length( +EXPORT_SPEC size_t UpnpString_get_Length( /*! [in] The \em \b this pointer. */ const UpnpString *p); +/*! + * \brief Truncates the string to the specified lenght, or does nothing + * if the current lenght is less than or equal to the requested length. + * */ +EXPORT_SPEC void UpnpString_set_Length( + /*! [in] The \em \b this pointer. */ + UpnpString *p, + /*! [in] The requested length. */ + size_t n); + + /*! * \brief Returns the pointer to char. * @@ -94,7 +108,7 @@ EXPORT_SPEC const char *UpnpString_get_String( /*! * \brief Sets the string from a pointer to char. */ -EXPORT_SPEC void UpnpString_set_String( +EXPORT_SPEC int UpnpString_set_String( /*! [in] The \em \b this pointer. */ UpnpString *p, /*! [in] (char *) to copy from. */ @@ -104,13 +118,13 @@ EXPORT_SPEC void UpnpString_set_String( /*! * \brief Sets the string from a pointer to char using a maximum of N chars. */ -EXPORT_SPEC void UpnpString_set_StringN( +EXPORT_SPEC int UpnpString_set_StringN( /*! [in] The \em \b this pointer. */ UpnpString *p, /*! [in] (char *) to copy from. */ const char *s, /*! Maximum number of chars to copy.*/ - int n); + size_t n); /*! @@ -121,6 +135,30 @@ EXPORT_SPEC void UpnpString_clear( UpnpString *p); +/*! + * \brief Compares two strings for equality. Case matters. + * + * \return The result of strcmp(). + */ +EXPORT_SPEC int UpnpString_cmp( + /*! [in] The \em \b the first string. */ + UpnpString *p, + /*! [in] The \em \b the second string. */ + UpnpString *q); + + +/*! + * \brief Compares two strings for equality. Case does not matter. + * + * \return The result of strcasecmp(). + */ +EXPORT_SPEC int UpnpString_casecmp( + /*! [in] The \em \b the first string. */ + UpnpString *p, + /*! [in] The \em \b the second string. */ + UpnpString *q); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/upnp/src/api/UpnpString.c b/upnp/src/api/UpnpString.c index baba49d..9b6a64b 100644 --- a/upnp/src/api/UpnpString.c +++ b/upnp/src/api/UpnpString.c @@ -28,6 +28,19 @@ #include /* for strlen(), strdup() */ +#ifdef WIN32 + #define strcasecmp stricmp +#else + /* Other systems have strncasecmp */ +#endif + + +/* strndup() is a GNU extension. Other systems must fix it with elif's. */ +#ifdef __GNUC__ +extern char *strndup(__const char *__string, size_t __n); +#endif + + /*! * \brief Internal implementation of the class UpnpString. * @@ -115,42 +128,78 @@ void UpnpString_assign(UpnpString *p, const UpnpString *q) } -int UpnpString_get_Length(const UpnpString *p) +size_t UpnpString_get_Length(const UpnpString *p) { return ((struct SUpnpString *)p)->m_length; } +void UpnpString_set_Length(UpnpString *p, size_t n) +{ + if (((struct SUpnpString *)p)->m_length > n) { + ((struct SUpnpString *)p)->m_length = n; + /* No need to realloc now, will do later when needed. */ + ((struct SUpnpString *)p)->m_string[n] = 0; + } +} + + const char *UpnpString_get_String(const UpnpString *p) { return ((struct SUpnpString *)p)->m_string; } -void UpnpString_set_String(UpnpString *p, const char *s) +int UpnpString_set_String(UpnpString *p, const char *s) { + char *q = strdup(s); + if (!q) goto error_handler1; free(((struct SUpnpString *)p)->m_string); - ((struct SUpnpString *)p)->m_length = strlen(s); - ((struct SUpnpString *)p)->m_string = strdup(s); + ((struct SUpnpString *)p)->m_length = strlen(q); + ((struct SUpnpString *)p)->m_string = q; + +error_handler1: + return q != NULL; } -void UpnpString_set_StringN(UpnpString *p, const char *s, int n) +int UpnpString_set_StringN(UpnpString *p, const char *s, size_t n) { + char *q = strndup(s, n); + if (!q) goto error_handler1; free(((struct SUpnpString *)p)->m_string); - ((struct SUpnpString *)p)->m_length = n; - ((struct SUpnpString *)p)->m_string = (char *)malloc(n+1); - strncpy(((struct SUpnpString *)p)->m_string, s, n); - ((struct SUpnpString *)p)->m_string[n] = 0; + ((struct SUpnpString *)p)->m_length = strlen(q); + ((struct SUpnpString *)p)->m_string = q; + +error_handler1: + return q != NULL; } void UpnpString_clear(UpnpString *p) { ((struct SUpnpString *)p)->m_length = 0; - // No need to realloc now, will do later when needed + /* No need to realloc now, will do later when needed. */ ((struct SUpnpString *)p)->m_string[0] = 0; } + +int UpnpString_cmp(UpnpString *p, UpnpString *q) +{ + const char *cp = UpnpString_get_String(p); + const char *cq = UpnpString_get_String(q); + + return strcmp(cp, cq); +} + + +int UpnpString_casecmp(UpnpString *p, UpnpString *q) +{ + const char *cp = UpnpString_get_String(p); + const char *cq = UpnpString_get_String(q); + + return strcasecmp(cp, cq); +} + /* @} UpnpString */