Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
0b3acc3e
Commit
0b3acc3e
authored
Apr 23, 2020
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'v0.21.23'
release v0.21.23
parents
6979be00
6c240f66
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
238 additions
and
60 deletions
+238
-60
NEWS
NEWS
+18
-0
AndroidManifest.xml
android/AndroidManifest.xml
+2
-2
GmeDecoderPlugin.cxx
src/decoder/plugins/GmeDecoderPlugin.cxx
+5
-1
PollGroupWinSelect.cxx
src/event/PollGroupWinSelect.cxx
+2
-2
SocketMonitor.cxx
src/event/SocketMonitor.cxx
+19
-0
SocketMonitor.hxx
src/event/SocketMonitor.hxx
+2
-2
NarrowPath.hxx
src/fs/NarrowPath.hxx
+5
-0
CaseFold.cxx
src/lib/icu/CaseFold.cxx
+0
-27
CaseFold.hxx
src/lib/icu/CaseFold.hxx
+1
-1
Collate.cxx
src/lib/icu/Collate.cxx
+1
-1
Compare.cxx
src/lib/icu/Compare.cxx
+50
-0
Compare.hxx
src/lib/icu/Compare.hxx
+12
-2
Connection.cxx
src/lib/nfs/Connection.cxx
+4
-3
FileReader.cxx
src/lib/nfs/FileReader.cxx
+12
-8
Order.cxx
src/pcm/Order.cxx
+86
-0
CrossFade.cxx
src/player/CrossFade.cxx
+1
-1
Thread.cxx
src/player/Thread.cxx
+6
-0
CurlStorage.cxx
src/storage/plugins/CurlStorage.cxx
+7
-7
Fallback.hxx
src/tag/Fallback.hxx
+4
-0
AvahiPoll.cxx
src/zeroconf/AvahiPoll.cxx
+1
-3
No files found.
NEWS
View file @
0b3acc3e
...
...
@@ -36,6 +36,24 @@ ver 0.22 (not yet released)
* switch to C++17
- GCC 7 or clang 4 (or newer) recommended
ver 0.21.23 (2020/04/23)
* protocol
- add tag fallback for AlbumSort
* storage
- curl: fix corrupt "href" values in the presence of XML entities
- curl: unescape "href" values
* input
- nfs: fix crash bug
- nfs: fix freeze bug on reconnect
* decoder
- gme: adapt to API change in the upcoming version 0.7.0
* output
- alsa: implement channel mapping for 5.0 and 7.0
* player
- drain outputs at end of song in "single" mode
* Windows
- fix case insensitive search
ver 0.21.22 (2020/04/02)
* database
- simple: optimize startup
...
...
android/AndroidManifest.xml
View file @
0b3acc3e
...
...
@@ -2,8 +2,8 @@
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"org.musicpd"
android:installLocation=
"auto"
android:versionCode=
"4
5
"
android:versionName=
"0.21.2
2
"
>
android:versionCode=
"4
6
"
android:versionName=
"0.21.2
3
"
>
<uses-sdk
android:minSdkVersion=
"21"
android:targetSdkVersion=
"28"
/>
...
...
src/decoder/plugins/GmeDecoderPlugin.cxx
View file @
0b3acc3e
...
...
@@ -187,7 +187,11 @@ gme_file_decode(DecoderClient &client, Path path_fs)
LogWarning
(
gme_domain
,
gme_err
);
if
(
length
>
0
)
gme_set_fade
(
emu
,
length
);
gme_set_fade
(
emu
,
length
#if GME_VERSION >= 0x000700
,
8000
#endif
);
/* play */
DecoderCommand
cmd
;
...
...
src/event/PollGroupWinSelect.cxx
View file @
0b3acc3e
...
...
@@ -23,8 +23,8 @@
#include "PollGroupWinSelect.hxx"
constexpr
int
EVENT_READ
=
0
;
constexpr
int
EVENT_WRITE
=
1
;
static
constexpr
int
EVENT_READ
=
0
;
static
constexpr
int
EVENT_WRITE
=
1
;
static
constexpr
bool
HasEvent
(
unsigned
events
,
int
event_id
)
noexcept
...
...
src/event/SocketMonitor.cxx
View file @
0b3acc3e
...
...
@@ -23,6 +23,10 @@
#include <cassert>
#include <utility>
#ifdef USE_EPOLL
#include <cerrno>
#endif
void
SocketMonitor
::
Dispatch
(
unsigned
flags
)
noexcept
{
...
...
@@ -81,6 +85,21 @@ SocketMonitor::Schedule(unsigned flags) noexcept
if
(
success
)
scheduled_flags
=
flags
;
#ifdef USE_EPOLL
else
if
(
errno
==
EBADF
||
errno
==
ENOENT
)
/* the socket was probably closed by somebody else
(EBADF) or a new file descriptor with the same
number was created but not registered already
(ENOENT) - we can assume that there are no
scheduled events */
/* note that when this happens, we're actually lucky
that it has failed - imagine another thread may
meanwhile have created something on the same file
descriptor number, and has registered it; the
epoll_ctl() call above would then have succeeded,
but broke the other thread's epoll registration */
scheduled_flags
=
0
;
#endif
return
success
;
}
src/event/SocketMonitor.hxx
View file @
0b3acc3e
...
...
@@ -108,7 +108,7 @@ public:
}
bool
ScheduleRead
()
noexcept
{
return
Schedule
(
GetScheduledFlags
()
|
READ
|
HANGUP
|
ERROR
);
return
Schedule
(
GetScheduledFlags
()
|
READ
);
}
bool
ScheduleWrite
()
noexcept
{
...
...
@@ -116,7 +116,7 @@ public:
}
void
CancelRead
()
noexcept
{
Schedule
(
GetScheduledFlags
()
&
~
(
READ
|
HANGUP
|
ERROR
)
);
Schedule
(
GetScheduledFlags
()
&
~
READ
);
}
void
CancelWrite
()
noexcept
{
...
...
src/fs/NarrowPath.hxx
View file @
0b3acc3e
...
...
@@ -90,6 +90,11 @@ public:
constexpr
#endif
operator
Path
()
const
noexcept
{
#ifdef _UNICODE
if
(
value
.
IsNull
())
return
nullptr
;
#endif
return
value
;
}
};
...
...
src/lib/icu/CaseFold.cxx
View file @
0b3acc3e
...
...
@@ -34,12 +34,6 @@
#include <algorithm>
#endif
#ifdef _WIN32
#include "Win32.hxx"
#include <windows.h>
#endif
#include <cassert>
#include <memory>
#include <string.h>
...
...
@@ -65,27 +59,6 @@ try {
folded
.
SetSize
(
folded_length
);
return
UCharToUTF8
({
folded
.
begin
(),
folded
.
size
()});
#elif defined(_WIN32)
const
auto
u
=
MultiByteToWideChar
(
CP_UTF8
,
src
);
const
int
size
=
LCMapStringEx
(
LOCALE_NAME_INVARIANT
,
LCMAP_SORTKEY
|
LINGUISTIC_IGNORECASE
,
u
.
c_str
(),
-
1
,
nullptr
,
0
,
nullptr
,
nullptr
,
0
);
if
(
size
<=
0
)
return
AllocatedString
<>::
Duplicate
(
src
);
std
::
unique_ptr
<
wchar_t
[]
>
buffer
(
new
wchar_t
[
size
]);
int
result
=
LCMapStringEx
(
LOCALE_NAME_INVARIANT
,
LCMAP_SORTKEY
|
LINGUISTIC_IGNORECASE
,
u
.
c_str
(),
-
1
,
buffer
.
get
(),
size
,
nullptr
,
nullptr
,
0
);
if
(
result
<=
0
)
return
AllocatedString
<>::
Duplicate
(
src
);
return
WideCharToMultiByte
(
CP_UTF8
,
{
buffer
.
get
(),
size_t
(
result
-
1
)});
#else
#error not implemented
#endif
...
...
src/lib/icu/CaseFold.hxx
View file @
0b3acc3e
...
...
@@ -22,7 +22,7 @@
#include "config.h"
#if
defined(HAVE_ICU) || defined(_WIN32)
#if
def HAVE_ICU
#define HAVE_ICU_CASE_FOLD
#include <string_view>
...
...
src/lib/icu/Collate.cxx
View file @
0b3acc3e
...
...
@@ -108,7 +108,7 @@ IcuCollate(std::string_view a, std::string_view b) noexcept
}
auto
result
=
CompareStringEx
(
LOCALE_NAME_INVARIANT
,
LINGUISTIC
_IGNORECASE
,
NORM
_IGNORECASE
,
wa
.
c_str
(),
-
1
,
wb
.
c_str
(),
-
1
,
nullptr
,
nullptr
,
0
);
...
...
src/lib/icu/Compare.cxx
View file @
0b3acc3e
...
...
@@ -22,11 +22,27 @@
#include "util/StringAPI.hxx"
#include "config.h"
#ifdef _WIN32
#include "Win32.hxx"
#include <windows.h>
#endif
#ifdef HAVE_ICU_CASE_FOLD
IcuCompare
::
IcuCompare
(
std
::
string_view
_needle
)
noexcept
:
needle
(
IcuCaseFold
(
_needle
))
{}
#elif defined(_WIN32)
IcuCompare
::
IcuCompare
(
std
::
string_view
_needle
)
noexcept
:
needle
(
nullptr
)
{
try
{
needle
=
MultiByteToWideChar
(
CP_UTF8
,
_needle
);
}
catch
(...)
{
}
}
#else
IcuCompare
::
IcuCompare
(
std
::
string_view
_needle
)
noexcept
...
...
@@ -39,6 +55,22 @@ IcuCompare::operator==(const char *haystack) const noexcept
{
#ifdef HAVE_ICU_CASE_FOLD
return
StringIsEqual
(
IcuCaseFold
(
haystack
).
c_str
(),
needle
.
c_str
());
#elif defined(_WIN32)
if
(
needle
.
IsNull
())
/* the MultiByteToWideChar() call in the constructor
has failed, so let's always fail the comparison */
return
false
;
try
{
auto
w_haystack
=
MultiByteToWideChar
(
CP_UTF8
,
haystack
);
return
CompareStringEx
(
LOCALE_NAME_INVARIANT
,
NORM_IGNORECASE
,
w_haystack
.
c_str
(),
-
1
,
needle
.
c_str
(),
-
1
,
nullptr
,
nullptr
,
0
)
==
CSTR_EQUAL
;
}
catch
(...)
{
return
false
;
}
#else
return
StringIsEqualIgnoreCase
(
haystack
,
needle
.
c_str
());
#endif
...
...
@@ -50,6 +82,24 @@ IcuCompare::IsIn(const char *haystack) const noexcept
#ifdef HAVE_ICU_CASE_FOLD
return
StringFind
(
IcuCaseFold
(
haystack
).
c_str
(),
needle
.
c_str
())
!=
nullptr
;
#elif defined(_WIN32)
if
(
needle
.
IsNull
())
/* the MultiByteToWideChar() call in the constructor
has failed, so let's always fail the comparison */
return
false
;
try
{
auto
w_haystack
=
MultiByteToWideChar
(
CP_UTF8
,
haystack
);
return
FindNLSStringEx
(
LOCALE_NAME_INVARIANT
,
FIND_FROMSTART
|
NORM_IGNORECASE
,
w_haystack
.
c_str
(),
-
1
,
needle
.
c_str
(),
-
1
,
nullptr
,
nullptr
,
nullptr
,
0
)
>=
0
;
}
catch
(...)
{
/* MultiByteToWideChar() has failed */
return
false
;
}
#elif defined(HAVE_STRCASESTR)
return
strcasestr
(
haystack
,
needle
.
c_str
())
!=
nullptr
;
#else
...
...
src/lib/icu/Compare.hxx
View file @
0b3acc3e
...
...
@@ -25,13 +25,23 @@
#include <string_view>
#ifdef _WIN32
#include <wchar.h>
#endif
/**
* This class can compare one string ("needle") with lots of other
* strings ("haystacks") efficiently, ignoring case. With some
* configurations, it can prepare a case-folded version of the needle.
*/
class
IcuCompare
{
#ifdef _WIN32
/* Windows API functions work with wchar_t strings, so let's
cache the MultiByteToWideChar() result for performance */
AllocatedString
<
wchar_t
>
needle
;
#else
AllocatedString
<>
needle
;
#endif
public
:
IcuCompare
()
:
needle
(
nullptr
)
{}
...
...
@@ -40,12 +50,12 @@ public:
IcuCompare
(
const
IcuCompare
&
src
)
noexcept
:
needle
(
src
?
AllocatedString
<>::
Duplicate
(
src
.
needle
)
?
src
.
needle
.
Clone
(
)
:
nullptr
)
{}
IcuCompare
&
operator
=
(
const
IcuCompare
&
src
)
noexcept
{
needle
=
src
?
AllocatedString
<>::
Duplicate
(
src
.
needle
)
?
src
.
needle
.
Clone
(
)
:
nullptr
;
return
*
this
;
}
...
...
src/lib/nfs/Connection.cxx
View file @
0b3acc3e
...
...
@@ -191,7 +191,9 @@ static constexpr int
events_to_libnfs
(
unsigned
i
)
noexcept
{
return
((
i
&
SocketMonitor
::
READ
)
?
POLLIN
:
0
)
|
((
i
&
SocketMonitor
::
WRITE
)
?
POLLOUT
:
0
);
((
i
&
SocketMonitor
::
WRITE
)
?
POLLOUT
:
0
)
|
((
i
&
SocketMonitor
::
HANGUP
)
?
POLLHUP
:
0
)
|
((
i
&
SocketMonitor
::
ERROR
)
?
POLLERR
:
0
);
}
NfsConnection
::~
NfsConnection
()
noexcept
...
...
@@ -450,8 +452,7 @@ NfsConnection::ScheduleSocket() noexcept
SocketMonitor
::
Open
(
_fd
);
}
SocketMonitor
::
Schedule
(
libnfs_to_events
(
which_events
)
|
SocketMonitor
::
HANGUP
);
SocketMonitor
::
Schedule
(
libnfs_to_events
(
which_events
));
}
inline
int
...
...
src/lib/nfs/FileReader.cxx
View file @
0b3acc3e
...
...
@@ -180,7 +180,6 @@ NfsFileReader::OnNfsConnectionDisconnected(std::exception_ptr e) noexcept
inline
void
NfsFileReader
::
OpenCallback
(
nfsfh
*
_fh
)
noexcept
{
assert
(
state
==
State
::
OPEN
);
assert
(
connection
!=
nullptr
);
assert
(
_fh
!=
nullptr
);
...
...
@@ -197,27 +196,33 @@ NfsFileReader::OpenCallback(nfsfh *_fh) noexcept
}
inline
void
NfsFileReader
::
StatCallback
(
const
struct
stat
*
st
)
noexcept
NfsFileReader
::
StatCallback
(
const
struct
stat
*
_
st
)
noexcept
{
assert
(
state
==
State
::
STAT
);
assert
(
connection
!=
nullptr
);
assert
(
fh
!=
nullptr
);
assert
(
st
!=
nullptr
);
assert
(
_st
!=
nullptr
);
#if defined(_WIN32) && !defined(_WIN64)
/* on 32-bit Windows, libnfs enables -D_FILE_OFFSET_BITS=64,
but MPD (Meson) doesn't - to work around this mismatch, we
cast explicitly to "struct stat64" */
const
auto
*
st
=
(
const
struct
stat64
*
)
_st
;
#else
const
auto
*
st
=
_st
;
#endif
if
(
!
S_ISREG
(
st
->
st_mode
))
{
OnNfsFileError
(
std
::
make_exception_ptr
(
std
::
runtime_error
(
"Not a regular file"
)));
return
;
}
state
=
State
::
IDLE
;
OnNfsFileOpen
(
st
->
st_size
);
}
void
NfsFileReader
::
OnNfsCallback
(
unsigned
status
,
void
*
data
)
noexcept
{
switch
(
st
ate
)
{
switch
(
st
d
::
exchange
(
state
,
State
::
IDLE
)
)
{
case
State
:
:
INITIAL
:
case
State
:
:
DEFER
:
case
State
:
:
MOUNT
:
...
...
@@ -234,7 +239,6 @@ NfsFileReader::OnNfsCallback(unsigned status, void *data) noexcept
break
;
case
State
:
:
READ
:
state
=
State
::
IDLE
;
OnNfsFileRead
(
data
,
status
);
break
;
}
...
...
src/pcm/Order.cxx
View file @
0b3acc3e
...
...
@@ -21,6 +21,28 @@
#include "Buffer.hxx"
#include "util/ConstBuffer.hxx"
/*
* According to:
* - https://xiph.org/flac/format.html#frame_header
* - https://github.com/nu774/qaac/wiki/Multichannel--handling
* the source channel order (after decoding, e.g., flac, alac) is for
* - 1ch: mono
* - 2ch: left, right
* - 3ch: left, right, center
* - 4ch: front left, front right, back left, back right
* - 5ch: front left, front right, front center, back/surround left, back/surround right
* - 6ch (aka 5.1): front left, front right, front center, LFE, back/surround left, back/surround right
* - 7ch: front left, front right, front center, LFE, back center, side left, side right
* - 8ch: (aka 7.1): front left, front right, front center, LFE, back left, back right, side left, side right
*
* The ALSA default channel map is (see /usr/share/alsa/pcm/surround71.conf):
* - front left, front right, back left, back right, front center, LFE, side left, side right
*
* Hence, in case of the following source channel orders 3ch, 5ch, 6ch (aka
* 5.1), 7ch and 8ch the channel order has to be adapted
*/
template
<
typename
V
>
struct
TwoPointers
{
V
*
dest
;
...
...
@@ -44,11 +66,33 @@ struct TwoPointers {
return
*
this
;
}
TwoPointers
<
V
>
&
ToAlsa50
()
noexcept
{
*
dest
++
=
src
[
0
];
// front left
*
dest
++
=
src
[
1
];
// front right
*
dest
++
=
src
[
3
];
// surround left
*
dest
++
=
src
[
4
];
// surround right
*
dest
++
=
src
[
2
];
// front center
src
+=
5
;
return
*
this
;
}
TwoPointers
<
V
>
&
ToAlsa51
()
noexcept
{
return
CopyTwo
()
// left+right
.
SwapTwoPairs
();
// center, LFE, surround left+right
}
TwoPointers
<
V
>
&
ToAlsa70
()
noexcept
{
*
dest
++
=
src
[
0
];
// front left
*
dest
++
=
src
[
1
];
// front right
*
dest
++
=
src
[
5
];
// side left
*
dest
++
=
src
[
6
];
// side right
*
dest
++
=
src
[
2
];
// front center
*
dest
++
=
src
[
3
];
// LFE
*
dest
++
=
src
[
4
];
// back center
src
+=
7
;
return
*
this
;
}
TwoPointers
<
V
>
&
ToAlsa71
()
noexcept
{
return
ToAlsa51
()
.
CopyTwo
();
// side left+right
...
...
@@ -57,6 +101,24 @@ struct TwoPointers {
template
<
typename
V
>
static
void
ToAlsaChannelOrder50
(
V
*
dest
,
const
V
*
src
,
size_t
n
)
noexcept
{
TwoPointers
<
V
>
p
{
dest
,
src
};
for
(
size_t
i
=
0
;
i
!=
n
;
++
i
)
p
.
ToAlsa50
();
}
template
<
typename
V
>
static
inline
ConstBuffer
<
V
>
ToAlsaChannelOrder50
(
PcmBuffer
&
buffer
,
ConstBuffer
<
V
>
src
)
noexcept
{
auto
dest
=
buffer
.
GetT
<
V
>
(
src
.
size
);
ToAlsaChannelOrder50
(
dest
,
src
.
data
,
src
.
size
/
5
);
return
{
dest
,
src
.
size
};
}
template
<
typename
V
>
static
void
ToAlsaChannelOrder51
(
V
*
dest
,
const
V
*
src
,
size_t
n
)
noexcept
{
TwoPointers
<
V
>
p
{
dest
,
src
};
...
...
@@ -75,6 +137,24 @@ ToAlsaChannelOrder51(PcmBuffer &buffer, ConstBuffer<V> src) noexcept
template
<
typename
V
>
static
void
ToAlsaChannelOrder70
(
V
*
dest
,
const
V
*
src
,
size_t
n
)
noexcept
{
TwoPointers
<
V
>
p
{
dest
,
src
};
for
(
size_t
i
=
0
;
i
!=
n
;
++
i
)
p
.
ToAlsa70
();
}
template
<
typename
V
>
static
inline
ConstBuffer
<
V
>
ToAlsaChannelOrder70
(
PcmBuffer
&
buffer
,
ConstBuffer
<
V
>
src
)
noexcept
{
auto
dest
=
buffer
.
GetT
<
V
>
(
src
.
size
);
ToAlsaChannelOrder70
(
dest
,
src
.
data
,
src
.
size
/
7
);
return
{
dest
,
src
.
size
};
}
template
<
typename
V
>
static
void
ToAlsaChannelOrder71
(
V
*
dest
,
const
V
*
src
,
size_t
n
)
noexcept
{
TwoPointers
<
V
>
p
{
dest
,
src
};
...
...
@@ -97,9 +177,15 @@ ToAlsaChannelOrderT(PcmBuffer &buffer, ConstBuffer<V> src,
unsigned
channels
)
noexcept
{
switch
(
channels
)
{
case
5
:
// 5.0
return
ToAlsaChannelOrder50
(
buffer
,
src
);
case
6
:
// 5.1
return
ToAlsaChannelOrder51
(
buffer
,
src
);
case
7
:
// 7.0
return
ToAlsaChannelOrder70
(
buffer
,
src
);
case
8
:
// 7.1
return
ToAlsaChannelOrder71
(
buffer
,
src
);
...
...
src/player/CrossFade.cxx
View file @
0b3acc3e
...
...
@@ -62,7 +62,7 @@ mixramp_interpolate(const char *ramp_list, float required_db) noexcept
++
ramp_list
;
/* Check for exact match. */
if
(
db
=
=
required_db
)
{
if
(
db
>
=
required_db
)
{
return
duration
;
}
...
...
src/player/Thread.cxx
View file @
0b3acc3e
...
...
@@ -967,6 +967,12 @@ Player::SongBorder() noexcept
if
(
border_pause
)
{
paused
=
true
;
pc
.
listener
.
OnBorderPause
();
/* drain all outputs to guarantee the current song is
really being played to the end; without this, the
Pause() call would drop all ring buffers */
pc
.
outputs
.
Drain
();
pc
.
outputs
.
Pause
();
idle_add
(
IDLE_PLAYER
);
}
...
...
src/storage/plugins/CurlStorage.cxx
View file @
0b3acc3e
...
...
@@ -394,7 +394,7 @@ private:
break
;
case
State
:
:
HREF
:
response
.
href
.
a
ssign
(
s
,
len
);
response
.
href
.
a
ppend
(
s
,
len
);
break
;
case
State
:
:
STATUS
:
...
...
@@ -474,7 +474,7 @@ class HttpListDirectoryOperation final : public PropfindOperation {
public
:
HttpListDirectoryOperation
(
CurlGlobal
&
curl
,
const
char
*
uri
)
:
PropfindOperation
(
curl
,
uri
,
1
),
base_path
(
UriPathOrSlash
(
uri
))
{}
base_path
(
CurlUnescape
(
GetEasy
(),
UriPathOrSlash
(
uri
)
))
{}
std
::
unique_ptr
<
StorageDirectoryReader
>
Perform
()
{
DeferStart
();
...
...
@@ -499,8 +499,7 @@ private:
/* kludge: ignoring case in this comparison to avoid
false negatives if the web server uses a different
case in hex digits in escaped characters; TODO:
implement properly */
case */
path
=
StringAfterPrefixIgnoreCase
(
path
,
base_path
.
c_str
());
if
(
path
==
nullptr
||
path
.
empty
())
return
nullptr
;
...
...
@@ -523,11 +522,12 @@ protected:
if
(
r
.
status
!=
200
)
return
;
const
auto
escaped_name
=
HrefToEscapedName
(
r
.
href
.
c_str
());
if
(
escaped_name
.
IsNull
())
std
::
string
href
=
CurlUnescape
(
GetEasy
(),
r
.
href
.
c_str
());
const
auto
name
=
HrefToEscapedName
(
href
.
c_str
());
if
(
name
.
IsNull
())
return
;
entries
.
emplace_front
(
CurlUnescape
(
GetEasy
(),
escaped_nam
e
));
entries
.
emplace_front
(
std
::
string
(
name
.
data
,
name
.
siz
e
));
auto
&
info
=
entries
.
front
().
info
;
info
=
StorageFileInfo
(
r
.
collection
...
...
src/tag/Fallback.hxx
View file @
0b3acc3e
...
...
@@ -45,6 +45,10 @@ ApplyTagFallback(TagType type, F &&f) noexcept
"AlbumArtist"/"ArtistSort" was found */
return
f
(
TAG_ARTIST
);
if
(
type
==
TAG_ALBUM_SORT
)
/* fall back to "Album" if no "AlbumSort" was found */
return
f
(
TAG_ALBUM
);
return
false
;
}
...
...
src/zeroconf/AvahiPoll.cxx
View file @
0b3acc3e
...
...
@@ -26,9 +26,7 @@ static unsigned
FromAvahiWatchEvent
(
AvahiWatchEvent
e
)
{
return
(
e
&
AVAHI_WATCH_IN
?
SocketMonitor
::
READ
:
0
)
|
(
e
&
AVAHI_WATCH_OUT
?
SocketMonitor
::
WRITE
:
0
)
|
(
e
&
AVAHI_WATCH_ERR
?
SocketMonitor
::
ERROR
:
0
)
|
(
e
&
AVAHI_WATCH_HUP
?
SocketMonitor
::
HANGUP
:
0
);
(
e
&
AVAHI_WATCH_OUT
?
SocketMonitor
::
WRITE
:
0
);
}
static
AvahiWatchEvent
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment