diff options
author | Max Kellermann <max@duempel.org> | 2008-08-29 09:39:04 +0200 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2008-09-02 00:20:17 -0700 |
commit | 82a37682c692896bbf74fbaa91f5da727e8e1b0e (patch) | |
tree | 4928c4df9e6ff8e2080f85f8135c28a2c8f8583b | |
parent | 55e297674f35a90ea9f2deeda2267e8520f1f414 (diff) | |
download | mpd-82a37682c692896bbf74fbaa91f5da727e8e1b0e.tar.gz mpd-82a37682c692896bbf74fbaa91f5da727e8e1b0e.tar.xz mpd-82a37682c692896bbf74fbaa91f5da727e8e1b0e.zip |
tag: try not to duplicate the input string
Try to detect if the string needs Latin1-UTF8 conversion, or
whitespace cleanup. If not, we don't need to allocate temporary
memory, leading to decreased heap fragmentation.
-rw-r--r-- | src/tag.c | 31 |
1 files changed, 18 insertions, 13 deletions
@@ -347,8 +347,8 @@ int tag_equal(struct mpd_tag *tag1, struct mpd_tag *tag2) return 1; } -static inline char *fix_utf8(char *str, size_t *length_r) { - char *temp; +static inline const char *fix_utf8(const char *str, size_t *length_r) { + const char *temp; assert(str != NULL); @@ -357,7 +357,6 @@ static inline char *fix_utf8(char *str, size_t *length_r) { DEBUG("not valid utf8 in tag: %s\n",str); temp = latin1StrToUtf8Dup(str); - free(str); *length_r = strlen(temp); return temp; } @@ -366,22 +365,28 @@ static void appendToTagItems(struct mpd_tag *tag, enum tag_type type, const char *value, size_t len) { unsigned int i = tag->numOfItems; - char *duplicated = xmalloc(len + 1); - - memcpy(duplicated, value, len); - duplicated[len] = '\0'; - - duplicated = fix_utf8(duplicated, &len); - stripReturnChar(duplicated); + const char *p; + + p = fix_utf8(value, &len); + if (memchr(p, '\n', len) != NULL) { + char *duplicated = xmalloc(len + 1); + memcpy(duplicated, p, len); + duplicated[len] = '\0'; + if (p != value) + free(deconst_ptr(p)); + + stripReturnChar(duplicated); + p = duplicated; + } tag->numOfItems++; tag->items = xrealloc(tag->items, tag->numOfItems * sizeof(*tag->items)); - len = strlen(duplicated); - tag->items[i] = tag_pool_get_item(type, duplicated, len); + tag->items[i] = tag_pool_get_item(type, p, len); - free(duplicated); + if (p != value) + free(deconst_ptr(p)); } void tag_add_item_n(struct mpd_tag *tag, enum tag_type itemType, |