From 5462f34ed037111d2d57638352b2f1a65a322579 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 23 Dec 2010 16:16:01 +0100 Subject: [PATCH] string_util: add function strchug_fast() Replace g_strchug() calls with a cheaper implementation. --- src/conf.c | 8 +++--- src/playlist/extm3u_playlist_plugin.c | 3 +- src/playlist_database.c | 3 +- src/song_save.c | 3 +- src/string_util.c | 9 ++++++ src/string_util.h | 41 +++++++++++++++++++++++++++ src/tokenizer.c | 7 +++-- 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/conf.c b/src/conf.c index 3310da17e..c759a1940 100644 --- a/src/conf.c +++ b/src/conf.c @@ -270,7 +270,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r) } (*count)++; - line = g_strchug(line); + line = strchug_fast(line); if (*line == 0 || *line == CONF_COMMENT) continue; @@ -278,7 +278,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r) /* end of this block; return from the function (and from this "while" loop) */ - line = g_strchug(line + 1); + line = strchug_fast(line + 1); if (*line != 0 && *line != CONF_COMMENT) { config_param_free(ret); g_set_error(error_r, config_quark(), 0, @@ -356,7 +356,7 @@ config_read_file(const char *file, GError **error_r) count++; - line = g_strchug(string); + line = strchug_fast(string); if (*line == 0 || *line == CONF_COMMENT) continue; @@ -402,7 +402,7 @@ config_read_file(const char *file, GError **error_r) return false; } - line = g_strchug(line + 1); + line = strchug_fast(line + 1); if (*line != 0 && *line != CONF_COMMENT) { g_set_error(error_r, config_quark(), 0, "line %i: Unknown tokens after '{'", diff --git a/src/playlist/extm3u_playlist_plugin.c b/src/playlist/extm3u_playlist_plugin.c index 9a04aa066..91f6eed08 100644 --- a/src/playlist/extm3u_playlist_plugin.c +++ b/src/playlist/extm3u_playlist_plugin.c @@ -24,6 +24,7 @@ #include "uri.h" #include "song.h" #include "tag.h" +#include "string_util.h" #include @@ -89,7 +90,7 @@ extm3u_parse_tag(const char *line) /* 0 means unknown duration */ duration = 0; - name = g_strchug(endptr + 1); + name = strchug_fast_c(endptr + 1); if (*name == 0 && duration == 0) /* no information available; don't allocate a tag object */ diff --git a/src/playlist_database.c b/src/playlist_database.c index 0a8a6f139..97da1c98e 100644 --- a/src/playlist_database.c +++ b/src/playlist_database.c @@ -21,6 +21,7 @@ #include "playlist_database.h" #include "playlist_vector.h" #include "text_file.h" +#include "string_util.h" #include #include @@ -62,7 +63,7 @@ playlist_metadata_load(FILE *fp, struct playlist_vector *pv, const char *name, } *colon++ = 0; - value = g_strchug(colon); + value = strchug_fast_c(colon); if (strcmp(line, "mtime") == 0) pm.mtime = strtol(value, NULL, 10); diff --git a/src/song_save.c b/src/song_save.c index a1a573298..d33e99c27 100644 --- a/src/song_save.c +++ b/src/song_save.c @@ -24,6 +24,7 @@ #include "directory.h" #include "tag.h" #include "text_file.h" +#include "string_util.h" #include @@ -96,7 +97,7 @@ song_load(FILE *fp, struct directory *parent, const char *uri, } *colon++ = 0; - value = g_strchug(colon); + value = strchug_fast_c(colon); if ((type = tag_name_parse(line)) != TAG_NUM_OF_ITEM_TYPES) { if (!song->tag) { diff --git a/src/string_util.c b/src/string_util.c index b93292854..3ae759917 100644 --- a/src/string_util.c +++ b/src/string_util.c @@ -24,6 +24,15 @@ #include +const char * +strchug_fast_c(const char *p) +{ + while (*p != 0 && g_ascii_isspace(*p)) + ++p; + + return p; +} + bool string_array_contains(const char *const* haystack, const char *needle) { diff --git a/src/string_util.h b/src/string_util.h index df8ceeef3..372354722 100644 --- a/src/string_util.h +++ b/src/string_util.h @@ -20,8 +20,49 @@ #ifndef MPD_STRING_UTIL_H #define MPD_STRING_UTIL_H +#include + #include +/** + * Remove the "const" attribute from a string pointer. This is a + * dirty hack, don't use it unless you know what you're doing! + */ +G_GNUC_CONST +static inline char * +deconst_string(const char *p) +{ + union { + const char *in; + char *out; + } u = { + .in = p, + }; + + return u.out; +} + +/** + * Returns a pointer to the first non-whitespace character in the + * string, or to the end of the string. + * + * This is a faster version of g_strchug(), because it does not move + * data. + */ +G_GNUC_PURE +const char * +strchug_fast_c(const char *p); + +/** + * Same as strchug_fast_c(), but works with a writable pointer. + */ +G_GNUC_PURE +static inline char * +strchug_fast(char *p) +{ + return deconst_string(strchug_fast_c(p)); +} + /** * Checks whether a string array contains the specified string. * diff --git a/src/tokenizer.c b/src/tokenizer.c index 2b9e05070..358d804dc 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -19,6 +19,7 @@ #include "config.h" #include "tokenizer.h" +#include "string_util.h" #include #include @@ -72,7 +73,7 @@ tokenizer_next_word(char **input_p, GError **error_r) /* a whitespace: the word ends here */ *input = 0; /* skip all following spaces, too */ - input = g_strchug(input + 1); + input = strchug_fast(input + 1); break; } @@ -126,7 +127,7 @@ tokenizer_next_unquoted(char **input_p, GError **error_r) /* a whitespace: the word ends here */ *input = 0; /* skip all following spaces, too */ - input = g_strchug(input + 1); + input = strchug_fast(input + 1); break; } @@ -205,7 +206,7 @@ tokenizer_next_string(char **input_p, GError **error_r) /* finish the string and return it */ *dest = 0; - *input_p = g_strchug(input); + *input_p = strchug_fast(input); return word; }