#include "config.h" #include "String.h" #include // for calloc(), free() #include // for strlen(), strdup() /*! * \ingroup UpnpString * * \brief Internal implementation of the class UpnpString. * * \internal * * 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. */ 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; 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; }