diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/ClientWrite.cxx | 35 | ||||
-rw-r--r-- | src/IcyMetaDataServer.cxx | 55 | ||||
-rw-r--r-- | src/IcyMetaDataServer.hxx | 3 | ||||
-rw-r--r-- | src/decoder/GmeDecoderPlugin.cxx | 6 | ||||
-rw-r--r-- | src/output/HttpdClient.cxx | 6 | ||||
-rw-r--r-- | src/util/FormatString.cxx | 68 | ||||
-rw-r--r-- | src/util/FormatString.hxx | 43 |
8 files changed, 151 insertions, 66 deletions
diff --git a/Makefile.am b/Makefile.am index 52ca84cc8..da7cdb00e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -246,6 +246,7 @@ libutil_a_SOURCES = \ src/util/Domain.hxx \ src/util/ReusableArray.hxx \ src/util/StringUtil.cxx src/util/StringUtil.hxx \ + src/util/FormatString.cxx src/util/FormatString.hxx \ src/util/Tokenizer.cxx src/util/Tokenizer.hxx \ src/util/UriUtil.cxx src/util/UriUtil.hxx \ src/util/Manual.hxx \ diff --git a/src/ClientWrite.cxx b/src/ClientWrite.cxx index ebed5f570..547f72bb5 100644 --- a/src/ClientWrite.cxx +++ b/src/ClientWrite.cxx @@ -19,11 +19,9 @@ #include "config.h" #include "ClientInternal.hxx" - -#include <glib.h> +#include "util/FormatString.hxx" #include <string.h> -#include <stdio.h> /** * Write a block of data to the client. @@ -47,34 +45,9 @@ client_puts(Client *client, const char *s) void client_vprintf(Client *client, const char *fmt, va_list args) { -#ifndef WIN32 - va_list tmp; - int length; - - va_copy(tmp, args); - length = vsnprintf(NULL, 0, fmt, tmp); - va_end(tmp); - - if (length <= 0) - /* wtf.. */ - return; - - char *buffer = (char *)g_malloc(length + 1); - vsnprintf(buffer, length + 1, fmt, args); - client_write(client, buffer, length); - g_free(buffer); -#else - /* On mingw32, snprintf() expects a 64 bit integer instead of - a "long int" for "%li". This is not consistent with our - expectation, so we're using plain sprintf() here, hoping - the static buffer is large enough. Sorry for this hack, - but WIN32 development is so painful, I'm not in the mood to - do it properly now. */ - - static char buffer[4096]; - vsprintf(buffer, fmt, args); - client_write(client, buffer, strlen(buffer)); -#endif + char *p = FormatNewV(fmt, args); + client_write(client, p, strlen(p)); + delete[] p; } void diff --git a/src/IcyMetaDataServer.cxx b/src/IcyMetaDataServer.cxx index 051a240ba..255f5b53f 100644 --- a/src/IcyMetaDataServer.cxx +++ b/src/IcyMetaDataServer.cxx @@ -21,6 +21,7 @@ #include "IcyMetaDataServer.hxx" #include "Page.hxx" #include "tag/Tag.hxx" +#include "util/FormatString.hxx" #include <glib.h> @@ -32,26 +33,26 @@ icy_server_metadata_header(const char *name, const char *genre, const char *url, const char *content_type, int metaint) { - return g_strdup_printf("ICY 200 OK\r\n" - "icy-notice1:<BR>This stream requires an audio player!<BR>\r\n" /* TODO */ - "icy-notice2:MPD - The music player daemon<BR>\r\n" - "icy-name: %s\r\n" /* TODO */ - "icy-genre: %s\r\n" /* TODO */ - "icy-url: %s\r\n" /* TODO */ - "icy-pub:1\r\n" - "icy-metaint:%d\r\n" - /* TODO "icy-br:%d\r\n" */ - "Content-Type: %s\r\n" - "Connection: close\r\n" - "Pragma: no-cache\r\n" - "Cache-Control: no-cache, no-store\r\n" - "\r\n", - name, - genre, - url, - metaint, - /* bitrate, */ - content_type); + return FormatNew("ICY 200 OK\r\n" + "icy-notice1:<BR>This stream requires an audio player!<BR>\r\n" /* TODO */ + "icy-notice2:MPD - The music player daemon<BR>\r\n" + "icy-name: %s\r\n" /* TODO */ + "icy-genre: %s\r\n" /* TODO */ + "icy-url: %s\r\n" /* TODO */ + "icy-pub:1\r\n" + "icy-metaint:%d\r\n" + /* TODO "icy-br:%d\r\n" */ + "Content-Type: %s\r\n" + "Connection: close\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache, no-store\r\n" + "\r\n", + name, + genre, + url, + metaint, + /* bitrate, */ + content_type); } static char * @@ -61,12 +62,10 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url) guint meta_length; // The leading n is a placeholder for the length information - icy_metadata = g_strdup_printf("nStreamTitle='%s';" - "StreamUrl='%s';", - stream_title, - stream_url); - - g_return_val_if_fail(icy_metadata, NULL); + icy_metadata = FormatNew("nStreamTitle='%s';" + "StreamUrl='%s';", + stream_title, + stream_url); meta_length = strlen(icy_metadata); @@ -77,7 +76,7 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url) icy_metadata[0] = meta_length; if (meta_length > 255) { - g_free(icy_metadata); + delete[] icy_metadata; return NULL; } @@ -130,7 +129,7 @@ icy_server_metadata_page(const Tag &tag, const enum tag_type *types) Page *icy_metadata = Page::Copy(icy_string, (icy_string[0] * 16) + 1); - g_free(icy_string); + delete[] icy_string; return icy_metadata; } diff --git a/src/IcyMetaDataServer.hxx b/src/IcyMetaDataServer.hxx index a37239cd7..941d8ba4a 100644 --- a/src/IcyMetaDataServer.hxx +++ b/src/IcyMetaDataServer.hxx @@ -25,6 +25,9 @@ struct Tag; class Page; +/** + * Free the return value with delete[]. + */ char* icy_server_metadata_header(const char *name, const char *genre, const char *url, diff --git a/src/decoder/GmeDecoderPlugin.cxx b/src/decoder/GmeDecoderPlugin.cxx index f735c55ba..3a68e2321 100644 --- a/src/decoder/GmeDecoderPlugin.cxx +++ b/src/decoder/GmeDecoderPlugin.cxx @@ -22,6 +22,7 @@ #include "DecoderAPI.hxx" #include "CheckAudioFormat.hxx" #include "tag/TagHandler.hxx" +#include "util/FormatString.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -122,9 +123,8 @@ gme_container_scan(const char *path_fs, const unsigned int tnum) const char *subtune_suffix = uri_get_suffix(path_fs); if (tnum <= num_songs){ - char *subtune = g_strdup_printf( - SUBTUNE_PREFIX "%03u.%s", tnum, subtune_suffix); - return subtune; + return FormatNew(SUBTUNE_PREFIX "%03u.%s", + tnum, subtune_suffix); } else return nullptr; } diff --git a/src/output/HttpdClient.cxx b/src/output/HttpdClient.cxx index c622f823a..9595e47f6 100644 --- a/src/output/HttpdClient.cxx +++ b/src/output/HttpdClient.cxx @@ -146,9 +146,7 @@ HttpdClient::SendResponse() httpd->content_type); } else if (metadata_requested) { - gchar *metadata_header; - - metadata_header = + char *metadata_header = icy_server_metadata_header(httpd->name, httpd->genre, httpd->website, httpd->content_type, @@ -156,7 +154,7 @@ HttpdClient::SendResponse() g_strlcpy(buffer, metadata_header, sizeof(buffer)); - g_free(metadata_header); + delete[] metadata_header; } else { /* revert to a normal HTTP request */ snprintf(buffer, sizeof(buffer), diff --git a/src/util/FormatString.cxx b/src/util/FormatString.cxx new file mode 100644 index 000000000..c13d0fb52 --- /dev/null +++ b/src/util/FormatString.cxx @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "FormatString.hxx" + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +char * +FormatNewV(const char *fmt, va_list args) +{ +#ifndef WIN32 + va_list tmp; + va_copy(tmp, args); + const int length = vsnprintf(NULL, 0, fmt, tmp); + va_end(tmp); + + if (length <= 0) + /* wtf.. */ + abort(); + + char *buffer = new char[length + 1]; + vsnprintf(buffer, length + 1, fmt, args); + return buffer; +#else + /* On mingw32, snprintf() expects a 64 bit integer instead of + a "long int" for "%li". This is not consistent with our + expectation, so we're using plain sprintf() here, hoping + the static buffer is large enough. Sorry for this hack, + but WIN32 development is so painful, I'm not in the mood to + do it properly now. */ + + char buffer[16384]; + vsprintf(buffer, fmt, args); + + const size_t length = strlen(buffer); + char *p = new char[length + 1]; + memcpy(p, buffer, length + 1); + return p; +#endif +} + +char * +FormatNew(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + char *p = FormatNewV(fmt, args); + va_end(args); + return p; +} diff --git a/src/util/FormatString.hxx b/src/util/FormatString.hxx new file mode 100644 index 000000000..bb4263107 --- /dev/null +++ b/src/util/FormatString.hxx @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_FORMAT_STRING_HXX +#define MPD_FORMAT_STRING_HXX + +#include "Compiler.h" + +#include <stdarg.h> + +/** + * Format into a newly allocated string. The caller frees the return + * value with delete[]. + */ +gcc_malloc gcc_nonnull_all +char * +FormatNewV(const char *fmt, va_list args); + +/** + * Format into a newly allocated string. The caller frees the return + * value with delete[]. + */ +gcc_malloc gcc_nonnull(1) gcc_printf(1,2) +char * +FormatNew(const char *fmt, ...); + +#endif |