diff --git a/upnp/Makefile.am b/upnp/Makefile.am index 39d7c6f..7d843c8 100644 --- a/upnp/Makefile.am +++ b/upnp/Makefile.am @@ -19,6 +19,7 @@ LDADD = \ upnpincludedir = $(includedir)/upnp upnpinclude_HEADERS = \ + inc/UpnpString.h \ inc/upnp.h \ inc/upnpdebug.h \ inc/UpnpGlobal.h \ @@ -113,6 +114,7 @@ libupnp_la_SOURCES += \ # api libupnp_la_SOURCES += \ + src/api/UpnpString.c \ src/api/upnpapi.c if ENABLE_TOOLS diff --git a/upnp/inc/UpnpString.h b/upnp/inc/UpnpString.h new file mode 100644 index 0000000..0942f67 --- /dev/null +++ b/upnp/inc/UpnpString.h @@ -0,0 +1,133 @@ + + +#ifndef STRING_H +#define STRING_H + + +/*! + * \defgroup UpnpString The UpnpString Class + * + * \brief Implements string operations in the UPnP library. + * + * \author Marcelo Roberto Jimenez + * + * \version 1.0 + * + * @{ + * + * \file + * + * \brief UpnpString object declarartion. + */ + + +#include "UpnpGlobal.h" /* for EXPORT_SPEC */ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/*! + * \brief Type of the string objects inside libupnp. + */ +typedef struct s_UpnpString UpnpString; + + +/*! + * \brief Constructor. + * + * \return A pointer to a new allocated object. + */ +EXPORT_SPEC UpnpString *UpnpString_new(); + + +/*! + * \brief Destructor. + */ +EXPORT_SPEC void UpnpString_delete( + /*! [in] The \em \b this pointer. */ + UpnpString *p); + + +/*! + * \brief Copy Constructor. + * + * \return A pointer to a new allocated copy of the original object. + */ +EXPORT_SPEC UpnpString *UpnpString_dup( + /*! [in] The \em \b this pointer. */ + const UpnpString *p); + + +/*! + * \brief Assignment operator. + */ +EXPORT_SPEC void UpnpString_assign( + /*! [in] The \em \b this pointer. */ + UpnpString *p, + /*! [in] The \em \b that pointer. */ + const UpnpString *q); + + +/*! + * \brief Returns the length of the string. + * + * \return The length of the string. + * */ +EXPORT_SPEC int UpnpString_get_Length( + /*! [in] The \em \b this pointer. */ + const UpnpString *p); + + +/*! + * \brief Returns the pointer to char. + * + * \return The pointer to char. + */ +EXPORT_SPEC const char *UpnpString_get_String( + /*! [in] The \em \b this pointer. */ + const UpnpString *p); + + +/*! + * \brief Sets the string from a pointer to char. + */ +EXPORT_SPEC void UpnpString_set_String( + /*! [in] The \em \b this pointer. */ + UpnpString *p, + /*! [in] (char *) to copy from. */ + const char *s); + + +/*! + * \brief Sets the string from a pointer to char using a maximum of N chars. + */ +EXPORT_SPEC void 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); + + +/*! + * \brief Clears the string, sets its size to zero. + */ +EXPORT_SPEC void UpnpString_clear( + /*! [in] The \em \b this pointer. */ + UpnpString *p); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +/* @} UpnpString The UpnpString API */ + + +#endif /* STRING_H */ + diff --git a/upnp/src/api/UpnpString.c b/upnp/src/api/UpnpString.c new file mode 100644 index 0000000..baba49d --- /dev/null +++ b/upnp/src/api/UpnpString.c @@ -0,0 +1,156 @@ + + +/*! + * \addtogroup UpnpString + * + * Due to its heavy use, this class is coded for efficiency, not for beauty. + * Do not use this as example to other classes. Please take a look at any + * other one. + * + * \todo Always alloc a minimum size like 64 bytes or so and when shrinking + * do not perform a new memory allocation. + * + * @{ + * + * \file + * + * \brief UpnpString object implementation. + */ + + +#include "config.h" + + +#include "UpnpString.h" + + +#include /* for calloc(), free() */ +#include /* for strlen(), strdup() */ + + +/*! + * \brief Internal implementation of the class UpnpString. + * + * \internal + */ +struct SUpnpString +{ + /*! \brief Length of the string. */ + int m_length; + /*! \brief Pointer to a dynamically allocated area that holds the NULL + * terminated string. */ + char *m_string; +}; + + +UpnpString *UpnpString_new() +{ + // All bytes are zero, and so is the length of the string. + struct SUpnpString *p = calloc(1, sizeof (struct SUpnpString)); + if (p == NULL) { + goto error_handler1; + } +#if 0 + p->m_length = 0; +#endif + + // This byte is zero, calloc does initialize it. + p->m_string = calloc(1, 1); + if (p->m_string == NULL) { + goto error_handler2; + } + + return (UpnpString *)p; + + //free(p->m_string); +error_handler2: + free(p); +error_handler1: + return NULL; +} + + +void UpnpString_delete(UpnpString *p) +{ + struct SUpnpString *q = (struct SUpnpString *)p; + + if (!q) return; + + q->m_length = 0; + + free(q->m_string); + q->m_string = NULL; + + free(p); +} + + +UpnpString *UpnpString_dup(const UpnpString *p) +{ + struct SUpnpString *q = calloc(1, sizeof (struct SUpnpString)); + if (q == NULL) { + goto error_handler1; + } + q->m_length = ((struct SUpnpString *)p)->m_length; + q->m_string = strdup(((struct SUpnpString *)p)->m_string); + if (q->m_string == NULL) { + goto error_handler2; + } + + return (UpnpString *)q; + + //free(q->m_string); +error_handler2: + free(q); +error_handler1: + return NULL; +} + + +void UpnpString_assign(UpnpString *p, const UpnpString *q) +{ + if (p != q) { + UpnpString_set_String(p, UpnpString_get_String(q)); + } +} + + +int UpnpString_get_Length(const UpnpString *p) +{ + return ((struct SUpnpString *)p)->m_length; +} + + +const char *UpnpString_get_String(const UpnpString *p) +{ + return ((struct SUpnpString *)p)->m_string; +} + + +void UpnpString_set_String(UpnpString *p, const char *s) +{ + free(((struct SUpnpString *)p)->m_string); + ((struct SUpnpString *)p)->m_length = strlen(s); + ((struct SUpnpString *)p)->m_string = strdup(s); +} + + +void UpnpString_set_StringN(UpnpString *p, const char *s, int n) +{ + 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; +} + + +void UpnpString_clear(UpnpString *p) +{ + ((struct SUpnpString *)p)->m_length = 0; + // No need to realloc now, will do later when needed + ((struct SUpnpString *)p)->m_string[0] = 0; +} + +/* @} UpnpString */ +