util/FormatString: return AllocatedString
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "Client.hxx"
|
#include "Client.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -45,9 +46,7 @@ client_puts(Client &client, const char *s)
|
|||||||
void
|
void
|
||||||
client_vprintf(Client &client, const char *fmt, va_list args)
|
client_vprintf(Client &client, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
char *p = FormatNewV(fmt, args);
|
client.Write(FormatStringV(fmt, args).c_str());
|
||||||
client.Write(p);
|
|
||||||
delete[] p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "Response.hxx"
|
#include "Response.hxx"
|
||||||
#include "Client.hxx"
|
#include "Client.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Response::Write(const void *data, size_t length)
|
Response::Write(const void *data, size_t length)
|
||||||
@@ -37,10 +38,7 @@ Response::Write(const char *data)
|
|||||||
bool
|
bool
|
||||||
Response::FormatV(const char *fmt, va_list args)
|
Response::FormatV(const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
char *p = FormatNewV(fmt, args);
|
return Write(FormatStringV(fmt, args).c_str());
|
||||||
bool success = Write(p);
|
|
||||||
delete[] p;
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@@ -121,8 +122,8 @@ gme_container_scan(Path path_fs, const unsigned int tnum)
|
|||||||
|
|
||||||
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
|
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
|
||||||
if (tnum <= num_songs){
|
if (tnum <= num_songs){
|
||||||
return FormatNew(SUBTUNE_PREFIX "%03u.%s",
|
return FormatString(SUBTUNE_PREFIX "%03u.%s",
|
||||||
tnum, subtune_suffix);
|
tnum, subtune_suffix).Steal();
|
||||||
} else
|
} else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "system/ByteOrder.hxx"
|
#include "system/ByteOrder.hxx"
|
||||||
@@ -352,7 +353,7 @@ sidplay_container_scan(Path path_fs, const unsigned int tnum)
|
|||||||
/* Construct container/tune path names, eg.
|
/* Construct container/tune path names, eg.
|
||||||
Delta.sid/tune_001.sid */
|
Delta.sid/tune_001.sid */
|
||||||
if(tnum<=info.songs) {
|
if(tnum<=info.songs) {
|
||||||
return FormatNew(SUBTUNE_PREFIX "%03u.sid", tnum);
|
return FormatString(SUBTUNE_PREFIX "%03u.sid", tnum).Steal();
|
||||||
} else
|
} else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "HttpdClient.hxx"
|
#include "HttpdClient.hxx"
|
||||||
#include "HttpdInternal.hxx"
|
#include "HttpdInternal.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
#include "Page.hxx"
|
#include "Page.hxx"
|
||||||
#include "IcyMetaDataServer.hxx"
|
#include "IcyMetaDataServer.hxx"
|
||||||
#include "net/SocketError.hxx"
|
#include "net/SocketError.hxx"
|
||||||
@@ -141,7 +142,8 @@ HttpdClient::HandleLine(const char *line)
|
|||||||
bool
|
bool
|
||||||
HttpdClient::SendResponse()
|
HttpdClient::SendResponse()
|
||||||
{
|
{
|
||||||
char buffer[1024], *allocated = nullptr;
|
char buffer[1024];
|
||||||
|
AllocatedString<> allocated = nullptr;
|
||||||
const char *response;
|
const char *response;
|
||||||
|
|
||||||
assert(state == RESPONSE);
|
assert(state == RESPONSE);
|
||||||
@@ -162,11 +164,12 @@ HttpdClient::SendResponse()
|
|||||||
response = buffer;
|
response = buffer;
|
||||||
|
|
||||||
} else if (metadata_requested) {
|
} else if (metadata_requested) {
|
||||||
response = allocated =
|
allocated =
|
||||||
icy_server_metadata_header(httpd.name, httpd.genre,
|
icy_server_metadata_header(httpd.name, httpd.genre,
|
||||||
httpd.website,
|
httpd.website,
|
||||||
httpd.content_type,
|
httpd.content_type,
|
||||||
metaint);
|
metaint);
|
||||||
|
response = allocated.c_str();
|
||||||
} else { /* revert to a normal HTTP request */
|
} else { /* revert to a normal HTTP request */
|
||||||
snprintf(buffer, sizeof(buffer),
|
snprintf(buffer, sizeof(buffer),
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
@@ -180,7 +183,6 @@ HttpdClient::SendResponse()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t nbytes = SocketMonitor::Write(response, strlen(response));
|
ssize_t nbytes = SocketMonitor::Write(response, strlen(response));
|
||||||
delete[] allocated;
|
|
||||||
if (gcc_unlikely(nbytes < 0)) {
|
if (gcc_unlikely(nbytes < 0)) {
|
||||||
const SocketErrorMessage msg;
|
const SocketErrorMessage msg;
|
||||||
FormatWarning(httpd_output_domain,
|
FormatWarning(httpd_output_domain,
|
||||||
|
@@ -22,48 +22,49 @@
|
|||||||
#include "Page.hxx"
|
#include "Page.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
|
#include "util/AllocatedString.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char*
|
AllocatedString<>
|
||||||
icy_server_metadata_header(const char *name,
|
icy_server_metadata_header(const char *name,
|
||||||
const char *genre, const char *url,
|
const char *genre, const char *url,
|
||||||
const char *content_type, int metaint)
|
const char *content_type, int metaint)
|
||||||
{
|
{
|
||||||
return FormatNew("ICY 200 OK\r\n"
|
return FormatString("ICY 200 OK\r\n"
|
||||||
"icy-notice1:<BR>This stream requires an audio player!<BR>\r\n" /* TODO */
|
"icy-notice1:<BR>This stream requires an audio player!<BR>\r\n" /* TODO */
|
||||||
"icy-notice2:MPD - The music player daemon<BR>\r\n"
|
"icy-notice2:MPD - The music player daemon<BR>\r\n"
|
||||||
"icy-name: %s\r\n" /* TODO */
|
"icy-name: %s\r\n" /* TODO */
|
||||||
"icy-genre: %s\r\n" /* TODO */
|
"icy-genre: %s\r\n" /* TODO */
|
||||||
"icy-url: %s\r\n" /* TODO */
|
"icy-url: %s\r\n" /* TODO */
|
||||||
"icy-pub:1\r\n"
|
"icy-pub:1\r\n"
|
||||||
"icy-metaint:%d\r\n"
|
"icy-metaint:%d\r\n"
|
||||||
/* TODO "icy-br:%d\r\n" */
|
/* TODO "icy-br:%d\r\n" */
|
||||||
"Content-Type: %s\r\n"
|
"Content-Type: %s\r\n"
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"Pragma: no-cache\r\n"
|
"Pragma: no-cache\r\n"
|
||||||
"Cache-Control: no-cache, no-store\r\n"
|
"Cache-Control: no-cache, no-store\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
name,
|
name,
|
||||||
genre,
|
genre,
|
||||||
url,
|
url,
|
||||||
metaint,
|
metaint,
|
||||||
/* bitrate, */
|
/* bitrate, */
|
||||||
content_type);
|
content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static AllocatedString<>
|
||||||
icy_server_metadata_string(const char *stream_title, const char* stream_url)
|
icy_server_metadata_string(const char *stream_title, const char* stream_url)
|
||||||
{
|
{
|
||||||
// The leading n is a placeholder for the length information
|
// The leading n is a placeholder for the length information
|
||||||
char *icy_metadata = FormatNew("nStreamTitle='%s';"
|
auto icy_metadata = FormatString("nStreamTitle='%s';"
|
||||||
"StreamUrl='%s';",
|
"StreamUrl='%s';",
|
||||||
stream_title,
|
stream_title,
|
||||||
stream_url);
|
stream_url);
|
||||||
|
|
||||||
size_t meta_length = strlen(icy_metadata);
|
size_t meta_length = strlen(icy_metadata.c_str());
|
||||||
|
|
||||||
meta_length--; // subtract placeholder
|
meta_length--; // subtract placeholder
|
||||||
|
|
||||||
@@ -71,10 +72,8 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url)
|
|||||||
|
|
||||||
icy_metadata[0] = meta_length;
|
icy_metadata[0] = meta_length;
|
||||||
|
|
||||||
if (meta_length > 255) {
|
if (meta_length > 255)
|
||||||
delete[] icy_metadata;
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
return icy_metadata;
|
return icy_metadata;
|
||||||
}
|
}
|
||||||
@@ -105,14 +104,10 @@ icy_server_metadata_page(const Tag &tag, const TagType *types)
|
|||||||
p = CopyString(p, " - ", end - p);
|
p = CopyString(p, " - ", end - p);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *icy_string = icy_server_metadata_string(stream_title, "");
|
const auto icy_string = icy_server_metadata_string(stream_title, "");
|
||||||
|
|
||||||
if (icy_string == nullptr)
|
if (icy_string.IsNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Page *icy_metadata = Page::Copy(icy_string, (icy_string[0] * 16) + 1);
|
return Page::Copy(icy_string.c_str(), (icy_string[0] * 16) + 1);
|
||||||
|
|
||||||
delete[] icy_string;
|
|
||||||
|
|
||||||
return icy_metadata;
|
|
||||||
}
|
}
|
||||||
|
@@ -24,11 +24,9 @@
|
|||||||
|
|
||||||
struct Tag;
|
struct Tag;
|
||||||
class Page;
|
class Page;
|
||||||
|
template<typename T> class AllocatedString;
|
||||||
|
|
||||||
/**
|
AllocatedString<char>
|
||||||
* Free the return value with delete[].
|
|
||||||
*/
|
|
||||||
char*
|
|
||||||
icy_server_metadata_header(const char *name,
|
icy_server_metadata_header(const char *name,
|
||||||
const char *genre, const char *url,
|
const char *genre, const char *url,
|
||||||
const char *content_type, int metaint);
|
const char *content_type, int metaint);
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FormatString.hxx"
|
#include "FormatString.hxx"
|
||||||
|
#include "AllocatedString.hxx"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -26,8 +27,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *
|
AllocatedString<>
|
||||||
FormatNewV(const char *fmt, va_list args)
|
FormatStringV(const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
va_list tmp;
|
va_list tmp;
|
||||||
@@ -41,7 +42,7 @@ FormatNewV(const char *fmt, va_list args)
|
|||||||
|
|
||||||
char *buffer = new char[length + 1];
|
char *buffer = new char[length + 1];
|
||||||
vsnprintf(buffer, length + 1, fmt, args);
|
vsnprintf(buffer, length + 1, fmt, args);
|
||||||
return buffer;
|
return AllocatedString<>::Donate(buffer);
|
||||||
#else
|
#else
|
||||||
/* On mingw32, snprintf() expects a 64 bit integer instead of
|
/* On mingw32, snprintf() expects a 64 bit integer instead of
|
||||||
a "long int" for "%li". This is not consistent with our
|
a "long int" for "%li". This is not consistent with our
|
||||||
@@ -56,16 +57,16 @@ FormatNewV(const char *fmt, va_list args)
|
|||||||
const size_t length = strlen(buffer);
|
const size_t length = strlen(buffer);
|
||||||
char *p = new char[length + 1];
|
char *p = new char[length + 1];
|
||||||
memcpy(p, buffer, length + 1);
|
memcpy(p, buffer, length + 1);
|
||||||
return p;
|
return AllocatedString<>::Donate(buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
AllocatedString<>
|
||||||
FormatNew(const char *fmt, ...)
|
FormatString(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
char *p = FormatNewV(fmt, args);
|
auto p = FormatStringV(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@@ -24,20 +24,22 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/**
|
template<typename T> class AllocatedString;
|
||||||
* 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
|
* Format into a newly allocated string. The caller frees the return
|
||||||
* value with delete[].
|
* value with delete[].
|
||||||
*/
|
*/
|
||||||
gcc_malloc gcc_nonnull(1) gcc_printf(1,2)
|
gcc_nonnull_all
|
||||||
char *
|
AllocatedString<char>
|
||||||
FormatNew(const char *fmt, ...);
|
FormatStringV(const char *fmt, va_list args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format into a newly allocated string. The caller frees the return
|
||||||
|
* value with delete[].
|
||||||
|
*/
|
||||||
|
gcc_nonnull(1) gcc_printf(1,2)
|
||||||
|
AllocatedString<char>
|
||||||
|
FormatString(const char *fmt, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user