Commit 5dc4cbdf authored by Max Kellermann's avatar Max Kellermann

util/FormatString: new library to replace g_strdup_printf()

parent 1434e5a2
......@@ -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 \
......
......@@ -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
......
......@@ -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;
}
......@@ -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,
......
......@@ -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;
}
......
......@@ -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),
......
/*
* 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;
}
/*
* 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment