output/recorder: dynamic file name
This commit is contained in:
106
src/tag/Format.cxx
Normal file
106
src/tag/Format.cxx
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2015 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 "config.h"
|
||||
#include "Format.hxx"
|
||||
#include "Tag.hxx"
|
||||
#include "util/format.h"
|
||||
#include "util/StringUtil.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct FormatTagContext {
|
||||
const Tag &tag;
|
||||
|
||||
char buffer[256];
|
||||
|
||||
explicit FormatTagContext(const Tag &_tag):tag(_tag) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Is this a character unsafe to use in a path name segment?
|
||||
*/
|
||||
static constexpr bool
|
||||
IsUnsafeChar(char ch)
|
||||
{
|
||||
return
|
||||
/* disallow characters illegal in file names on
|
||||
Windows (Linux allows almost anything) */
|
||||
ch == '\\' || ch == '/' || ch == ':' || ch == '*' ||
|
||||
ch == '?' || ch == '<' || ch == '>' || ch == '|' ||
|
||||
/* allow space, but disallow all other whitespace */
|
||||
(unsigned char)ch < 0x20;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
HasUnsafeChar(const char *s)
|
||||
{
|
||||
for (; *s; ++s)
|
||||
if (IsUnsafeChar(*s))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *
|
||||
SanitizeString(const char *s, char *buffer, size_t buffer_size)
|
||||
{
|
||||
/* skip leading dots to avoid generating "../" sequences */
|
||||
while (*s == '.')
|
||||
++s;
|
||||
|
||||
if (!HasUnsafeChar(s))
|
||||
return s;
|
||||
|
||||
char *end = CopyString(buffer, s, buffer_size);
|
||||
std::replace_if(buffer, end, IsUnsafeChar, ' ');
|
||||
return buffer;
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static const char *
|
||||
TagGetter(const void *object, const char *name)
|
||||
{
|
||||
const auto &_ctx = *(const FormatTagContext *)object;
|
||||
auto &ctx = const_cast<FormatTagContext &>(_ctx);
|
||||
const Tag &tag = ctx.tag;
|
||||
|
||||
TagType tag_type = tag_name_parse_i(name);
|
||||
if (tag_type == TAG_NUM_OF_ITEM_TYPES)
|
||||
/* unknown tag name */
|
||||
return nullptr;
|
||||
|
||||
const char *value = tag.GetValue(tag_type);
|
||||
if (value == nullptr)
|
||||
/* known tag name, but not present in this object */
|
||||
value = "";
|
||||
|
||||
// TODO: handle multiple tag values
|
||||
return SanitizeString(value, ctx.buffer, sizeof(ctx.buffer));
|
||||
}
|
||||
|
||||
char *
|
||||
FormatTag(const Tag &tag, const char *format)
|
||||
{
|
||||
FormatTagContext ctx(tag);
|
||||
return format_object(format, &ctx, TagGetter);
|
||||
}
|
32
src/tag/Format.hxx
Normal file
32
src/tag/Format.hxx
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2015 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_TAG_FORMAT_HXX
|
||||
#define MPD_TAG_FORMAT_HXX
|
||||
|
||||
#include "check.h"
|
||||
#include "Compiler.h"
|
||||
|
||||
struct Tag;
|
||||
|
||||
gcc_malloc gcc_nonnull_all
|
||||
char *
|
||||
FormatTag(const Tag &tag, const char *format);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user