Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98afae2520 | ||
|
|
ddc85c620f | ||
|
|
12bc625fe1 | ||
|
|
6b407356b9 | ||
|
|
a4e0b52468 | ||
|
|
98efb4f6d5 | ||
|
|
36edb4886c | ||
|
|
76290f786d | ||
|
|
c6299c26b5 | ||
|
|
fb5f9baf9c | ||
|
|
dee591d970 | ||
|
|
a5cc13b0c5 | ||
|
|
aaf588aeaa | ||
|
|
533a3def9f | ||
|
|
fcf487f4e0 | ||
|
|
906972973e | ||
|
|
116edf5fce | ||
|
|
8581013911 | ||
|
|
b1e073bacd | ||
|
|
501e48daba | ||
|
|
643ecd1edd | ||
|
|
7393e1cba1 | ||
|
|
ceee47fda8 | ||
|
|
6f3c0d0a60 | ||
|
|
466625f7ad | ||
|
|
b8259e604a | ||
|
|
86e2075c63 | ||
|
|
30900b2fe2 | ||
|
|
fd7ae7ea4c | ||
|
|
60d5bf0240 | ||
|
|
41cdc4e14b | ||
|
|
87dfca0477 | ||
|
|
e1ee8e7812 | ||
|
|
63406efcd8 | ||
|
|
d5c132fca0 | ||
|
|
5f082a2739 | ||
|
|
7d6a762845 | ||
|
|
8dcb1f805d | ||
|
|
a8b9e5b9b9 | ||
|
|
04f928e2b0 | ||
|
|
c7a803c922 |
13
Makefile.am
13
Makefile.am
@@ -234,6 +234,7 @@ libmpd_a_SOURCES += \
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
CURL_SOURCES = \
|
CURL_SOURCES = \
|
||||||
|
src/lib/curl/Error.hxx \
|
||||||
src/lib/curl/Version.cxx src/lib/curl/Version.hxx \
|
src/lib/curl/Version.cxx src/lib/curl/Version.hxx \
|
||||||
src/lib/curl/Global.cxx src/lib/curl/Global.hxx \
|
src/lib/curl/Global.cxx src/lib/curl/Global.hxx \
|
||||||
src/lib/curl/Request.cxx src/lib/curl/Request.hxx \
|
src/lib/curl/Request.cxx src/lib/curl/Request.hxx \
|
||||||
@@ -293,7 +294,7 @@ libmpd.so: $(filter %.a,$(src_mpd_LDADD)) libmain.a
|
|||||||
$(AM_V_CXXLD)$(CXXLD) -shared -Wl,--no-undefined,-shared,-Bsymbolic -llog -lz -o $@ $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) src/libmain_a-Main.o $(src_mpd_LDADD) $(LIBS)
|
$(AM_V_CXXLD)$(CXXLD) -shared -Wl,--no-undefined,-shared,-Bsymbolic -llog -lz -o $@ $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) src/libmain_a-Main.o $(src_mpd_LDADD) $(LIBS)
|
||||||
|
|
||||||
ANDROID_SDK_BUILD_TOOLS_VERSION = 27.0.0
|
ANDROID_SDK_BUILD_TOOLS_VERSION = 27.0.0
|
||||||
ANDROID_SDK_PLATFORM = android-17
|
ANDROID_SDK_PLATFORM = android-21
|
||||||
|
|
||||||
ANDROID_BUILD_TOOLS_DIR = $(ANDROID_SDK)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)
|
ANDROID_BUILD_TOOLS_DIR = $(ANDROID_SDK)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)
|
||||||
ANDROID_SDK_PLATFORM_DIR = $(ANDROID_SDK)/platforms/$(ANDROID_SDK_PLATFORM)
|
ANDROID_SDK_PLATFORM_DIR = $(ANDROID_SDK)/platforms/$(ANDROID_SDK_PLATFORM)
|
||||||
@@ -340,7 +341,7 @@ android/build/include/org_musicpd_Bridge.h: android/build/classes.dex
|
|||||||
|
|
||||||
BUILT_SOURCES = android/build/include/org_musicpd_Bridge.h
|
BUILT_SOURCES = android/build/include/org_musicpd_Bridge.h
|
||||||
|
|
||||||
android/build/lib/armeabi-v7a/libmpd.so: libmpd.so
|
android/build/lib/$(ANDROID_ABI)/libmpd.so: libmpd.so
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
rm -f $@
|
rm -f $@
|
||||||
$(STRIP) -o $@ $<
|
$(STRIP) -o $@ $<
|
||||||
@@ -350,7 +351,7 @@ android/build/res/drawable/icon.png: mpd.svg
|
|||||||
rsvg-convert --width=48 --height=48 $< -o $@
|
rsvg-convert --width=48 --height=48 $< -o $@
|
||||||
|
|
||||||
.DELETE_ON_ERROR: android/build/unsigned.apk
|
.DELETE_ON_ERROR: android/build/unsigned.apk
|
||||||
android/build/unsigned.apk: android/build/classes.dex android/build/resources.apk android/build/lib/armeabi-v7a/libmpd.so
|
android/build/unsigned.apk: android/build/classes.dex android/build/resources.apk android/build/lib/$(ANDROID_ABI)/libmpd.so
|
||||||
cp android/build/resources.apk $@
|
cp android/build/resources.apk $@
|
||||||
cd $(dir $@) && zip -q -r $(notdir $@) classes.dex lib
|
cd $(dir $@) && zip -q -r $(notdir $@) classes.dex lib
|
||||||
|
|
||||||
@@ -444,6 +445,7 @@ libutil_a_SOURCES = \
|
|||||||
src/util/NumberParser.hxx \
|
src/util/NumberParser.hxx \
|
||||||
src/util/MimeType.cxx src/util/MimeType.hxx \
|
src/util/MimeType.cxx src/util/MimeType.hxx \
|
||||||
src/util/StringBuffer.hxx \
|
src/util/StringBuffer.hxx \
|
||||||
|
src/util/StringFormat.hxx \
|
||||||
src/util/StringPointer.hxx \
|
src/util/StringPointer.hxx \
|
||||||
src/util/StringView.cxx src/util/StringView.hxx \
|
src/util/StringView.cxx src/util/StringView.hxx \
|
||||||
src/util/AllocatedString.cxx src/util/AllocatedString.hxx \
|
src/util/AllocatedString.cxx src/util/AllocatedString.hxx \
|
||||||
@@ -712,6 +714,7 @@ NFS_SOURCES = \
|
|||||||
src/lib/nfs/Cancellable.hxx \
|
src/lib/nfs/Cancellable.hxx \
|
||||||
src/lib/nfs/Lease.hxx \
|
src/lib/nfs/Lease.hxx \
|
||||||
src/lib/nfs/Connection.cxx src/lib/nfs/Connection.hxx \
|
src/lib/nfs/Connection.cxx src/lib/nfs/Connection.hxx \
|
||||||
|
src/lib/nfs/Error.cxx src/lib/nfs/Error.hxx \
|
||||||
src/lib/nfs/Manager.cxx src/lib/nfs/Manager.hxx \
|
src/lib/nfs/Manager.cxx src/lib/nfs/Manager.hxx \
|
||||||
src/lib/nfs/Glue.cxx src/lib/nfs/Glue.hxx \
|
src/lib/nfs/Glue.cxx src/lib/nfs/Glue.hxx \
|
||||||
src/lib/nfs/Base.cxx src/lib/nfs/Base.hxx \
|
src/lib/nfs/Base.cxx src/lib/nfs/Base.hxx \
|
||||||
@@ -734,6 +737,8 @@ libstorage_a_SOURCES = \
|
|||||||
src/storage/FileInfo.hxx
|
src/storage/FileInfo.hxx
|
||||||
|
|
||||||
libstorage_a_CPPFLAGS = $(AM_CPPFLAGS) \
|
libstorage_a_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||||
|
$(CURL_CFLAGS) \
|
||||||
|
$(EXPAT_CFLAGS) \
|
||||||
$(NFS_CFLAGS) \
|
$(NFS_CFLAGS) \
|
||||||
$(SMBCLIENT_CFLAGS)
|
$(SMBCLIENT_CFLAGS)
|
||||||
|
|
||||||
@@ -1292,7 +1297,7 @@ endif
|
|||||||
#
|
#
|
||||||
|
|
||||||
libinput_a_SOURCES = \
|
libinput_a_SOURCES = \
|
||||||
src/input/Domain.cxx src/input/Domain.hxx \
|
src/input/Error.cxx src/input/Error.hxx \
|
||||||
src/input/Init.cxx src/input/Init.hxx \
|
src/input/Init.cxx src/input/Init.hxx \
|
||||||
src/input/Registry.cxx src/input/Registry.hxx \
|
src/input/Registry.cxx src/input/Registry.hxx \
|
||||||
src/input/Open.cxx \
|
src/input/Open.cxx \
|
||||||
|
|||||||
13
NEWS
13
NEWS
@@ -1,3 +1,16 @@
|
|||||||
|
ver 0.20.21 (2018/08/17)
|
||||||
|
* database
|
||||||
|
- proxy: add "password" setting
|
||||||
|
- proxy: support tags "ArtistSort", "AlbumArtistSort", "AlbumSort"
|
||||||
|
- simple: allow .mpdignore comments only at start of line
|
||||||
|
* output
|
||||||
|
- httpd: remove broken DLNA support code
|
||||||
|
* playlist
|
||||||
|
- cue: support file type declaration "FLAC" (non-standard)
|
||||||
|
* URI schemes are case insensitive
|
||||||
|
* Android, Windows
|
||||||
|
- enable the "curl" storage plugin
|
||||||
|
|
||||||
ver 0.20.20 (2018/05/22)
|
ver 0.20.20 (2018/05/22)
|
||||||
* protocol
|
* protocol
|
||||||
- fix "modified-since" filter regression
|
- fix "modified-since" filter regression
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.musicpd"
|
package="org.musicpd"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="19"
|
android:versionCode="20"
|
||||||
android:versionName="0.20.20">
|
android:versionName="0.20.21">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17"/>
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21"/>
|
||||||
|
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||||
<activity android:name=".Main"
|
<activity android:name=".Main"
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ android_abis = {
|
|||||||
'cflags': '-march=armv7-a -mfpu=vfp -mfloat-abi=softfp',
|
'cflags': '-march=armv7-a -mfpu=vfp -mfloat-abi=softfp',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'arm64-v8a': {
|
||||||
|
'android_api_level': '21',
|
||||||
|
'arch': 'aarch64-linux-android',
|
||||||
|
'ndk_arch': 'arm64',
|
||||||
|
'toolchain_arch': 'aarch64-linux-android',
|
||||||
|
'llvm_triple': 'aarch64-none-linux-android',
|
||||||
|
'cflags': '',
|
||||||
|
},
|
||||||
|
|
||||||
'x86': {
|
'x86': {
|
||||||
'arch': 'i686-linux-android',
|
'arch': 'i686-linux-android',
|
||||||
'ndk_arch': 'x86',
|
'ndk_arch': 'x86',
|
||||||
@@ -65,7 +74,8 @@ class AndroidNdkToolchain:
|
|||||||
self.build_path = build_path
|
self.build_path = build_path
|
||||||
|
|
||||||
ndk_arch = abi_info['ndk_arch']
|
ndk_arch = abi_info['ndk_arch']
|
||||||
ndk_platform = 'android-14'
|
android_api_level = '21'
|
||||||
|
ndk_platform = 'android-' + android_api_level
|
||||||
|
|
||||||
# select the NDK compiler
|
# select the NDK compiler
|
||||||
gcc_version = '4.9'
|
gcc_version = '4.9'
|
||||||
@@ -106,7 +116,7 @@ class AndroidNdkToolchain:
|
|||||||
self.cppflags = '--sysroot=' + sysroot + \
|
self.cppflags = '--sysroot=' + sysroot + \
|
||||||
' -isystem ' + os.path.join(install_prefix, 'include') + \
|
' -isystem ' + os.path.join(install_prefix, 'include') + \
|
||||||
' -isystem ' + os.path.join(sysroot, 'usr', 'include', arch) + \
|
' -isystem ' + os.path.join(sysroot, 'usr', 'include', arch) + \
|
||||||
' -D__ANDROID_API__=14'
|
' -D__ANDROID_API__=' + android_api_level
|
||||||
self.ldflags = '--sysroot=' + sysroot + \
|
self.ldflags = '--sysroot=' + sysroot + \
|
||||||
' -L' + os.path.join(install_prefix, 'lib') + \
|
' -L' + os.path.join(install_prefix, 'lib') + \
|
||||||
' -L' + os.path.join(target_root, 'usr', 'lib') + \
|
' -L' + os.path.join(target_root, 'usr', 'lib') + \
|
||||||
@@ -116,6 +126,7 @@ class AndroidNdkToolchain:
|
|||||||
|
|
||||||
self.is_arm = ndk_arch == 'arm'
|
self.is_arm = ndk_arch == 'arm'
|
||||||
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
||||||
|
self.is_aarch64 = ndk_arch == 'arm64'
|
||||||
self.is_windows = False
|
self.is_windows = False
|
||||||
|
|
||||||
libcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/llvm-libc++')
|
libcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/llvm-libc++')
|
||||||
@@ -146,6 +157,7 @@ thirdparty_libs = [
|
|||||||
libid3tag,
|
libid3tag,
|
||||||
ffmpeg,
|
ffmpeg,
|
||||||
curl,
|
curl,
|
||||||
|
libexpat,
|
||||||
libnfs,
|
libnfs,
|
||||||
boost,
|
boost,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class Main extends Activity implements Runnable {
|
|||||||
TextView tv = new TextView(this);
|
TextView tv = new TextView(this);
|
||||||
tv.setText("Failed to load the native MPD libary.\n" +
|
tv.setText("Failed to load the native MPD libary.\n" +
|
||||||
"Report this problem to us, and include the following information:\n" +
|
"Report this problem to us, and include the following information:\n" +
|
||||||
"ABI=" + Build.CPU_ABI + "\n" +
|
"SUPPORTED_ABIS=" + String.join(", ", Build.SUPPORTED_ABIS) + "\n" +
|
||||||
"PRODUCT=" + Build.PRODUCT + "\n" +
|
"PRODUCT=" + Build.PRODUCT + "\n" +
|
||||||
"FINGERPRINT=" + Build.FINGERPRINT + "\n" +
|
"FINGERPRINT=" + Build.FINGERPRINT + "\n" +
|
||||||
"error=" + Loader.error);
|
"error=" + Loader.error);
|
||||||
|
|||||||
24
configure.ac
24
configure.ac
@@ -1,10 +1,10 @@
|
|||||||
AC_PREREQ(2.60)
|
AC_PREREQ(2.60)
|
||||||
|
|
||||||
AC_INIT(mpd, 0.20.20, musicpd-dev-team@lists.sourceforge.net)
|
AC_INIT(mpd, 0.20.21, musicpd-dev-team@lists.sourceforge.net)
|
||||||
|
|
||||||
VERSION_MAJOR=0
|
VERSION_MAJOR=0
|
||||||
VERSION_MINOR=20
|
VERSION_MINOR=20
|
||||||
VERSION_REVISION=20
|
VERSION_REVISION=21
|
||||||
VERSION_EXTRA=0
|
VERSION_EXTRA=0
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([src/Main.cxx])
|
AC_CONFIG_SRCDIR([src/Main.cxx])
|
||||||
@@ -16,7 +16,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
|
|
||||||
AC_DEFINE(PROTOCOL_VERSION, "0.20.0", [The MPD protocol version])
|
AC_DEFINE(PROTOCOL_VERSION, "0.20.0", [The MPD protocol version])
|
||||||
|
|
||||||
GIT_COMMIT=`GIT_DIR="$srcdir/.git" git describe --dirty --always 2>/dev/null`
|
GIT_COMMIT=`cd "$srcdir" && git describe --dirty --always 2>/dev/null`
|
||||||
if test x$GIT_COMMIT != x; then
|
if test x$GIT_COMMIT != x; then
|
||||||
AC_DEFINE_UNQUOTED(GIT_COMMIT, ["$GIT_COMMIT"], [The current git commit])
|
AC_DEFINE_UNQUOTED(GIT_COMMIT, ["$GIT_COMMIT"], [The current git commit])
|
||||||
fi
|
fi
|
||||||
@@ -186,6 +186,7 @@ AC_ARG_WITH([android-sdk],
|
|||||||
[Directory for Android SDK]),
|
[Directory for Android SDK]),
|
||||||
[], [with_android_sdk=no])
|
[], [with_android_sdk=no])
|
||||||
|
|
||||||
|
android_abi=""
|
||||||
if test x$host_is_android = xyes; then
|
if test x$host_is_android = xyes; then
|
||||||
if test x$with_android_sdk = xno; then
|
if test x$with_android_sdk = xno; then
|
||||||
AC_MSG_ERROR([Android build requires option --with-android-sdk=DIR])
|
AC_MSG_ERROR([Android build requires option --with-android-sdk=DIR])
|
||||||
@@ -194,9 +195,15 @@ if test x$host_is_android = xyes; then
|
|||||||
if ! test -x $with_android_sdk/tools/android; then
|
if ! test -x $with_android_sdk/tools/android; then
|
||||||
AC_MSG_ERROR([Android SDK not found in $with_android_sdk])
|
AC_MSG_ERROR([Android SDK not found in $with_android_sdk])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AS_CASE([$host_cpu],
|
||||||
|
[i686], [android_abi="x86"],
|
||||||
|
[aarch64], [android_abi="arm64-v8a"],
|
||||||
|
[android_abi="armeabi-v7a"])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(ANDROID_SDK, [$with_android_sdk])
|
AC_SUBST(ANDROID_SDK, [$with_android_sdk])
|
||||||
|
AC_SUBST(ANDROID_ABI, [$android_abi])
|
||||||
|
|
||||||
dnl ---------------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------------
|
||||||
dnl Language Checks
|
dnl Language Checks
|
||||||
@@ -315,7 +322,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
default_enable_daemon=yes
|
default_enable_daemon=yes
|
||||||
if test x$host_is_android = xyes || test x$host_is_android = xyes; then
|
if test x$host_is_android = xyes || test x$host_is_windows = xyes; then
|
||||||
default_enable_daemon=no
|
default_enable_daemon=no
|
||||||
fi
|
fi
|
||||||
AC_ARG_ENABLE(daemon,
|
AC_ARG_ENABLE(daemon,
|
||||||
@@ -402,7 +409,7 @@ AC_ARG_ENABLE(recorder-output,
|
|||||||
|
|
||||||
AC_ARG_ENABLE(sidplay,
|
AC_ARG_ENABLE(sidplay,
|
||||||
AS_HELP_STRING([--enable-sidplay],
|
AS_HELP_STRING([--enable-sidplay],
|
||||||
[enable C64 SID support via libsidplay2]),,
|
[enable C64 SID support via libsidplayfp or libsidplay2]),,
|
||||||
enable_sidplay=auto)
|
enable_sidplay=auto)
|
||||||
|
|
||||||
AC_ARG_ENABLE(shout,
|
AC_ARG_ENABLE(shout,
|
||||||
@@ -1005,7 +1012,7 @@ if test x$enable_sidplay != xno && test x$found_sidplayfp = xno; then
|
|||||||
[found_sidplay=no])
|
[found_sidplay=no])
|
||||||
|
|
||||||
MPD_AUTO_PRE(sidplay, [sidplay decoder plugin],
|
MPD_AUTO_PRE(sidplay, [sidplay decoder plugin],
|
||||||
[libsidplay2 not found])
|
[libsidplay2 or libsidutils not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$enable_sidplay != xno && test x$found_sidplayfp = xno; then
|
if test x$enable_sidplay != xno && test x$found_sidplayfp = xno; then
|
||||||
@@ -1017,10 +1024,11 @@ if test x$enable_sidplay != xno && test x$found_sidplayfp = xno; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$enable_sidplay = xyes; then
|
if test x$enable_sidplay = xyes; then
|
||||||
SIDPLAY_LIBS="$SIDPLAY_LIBS -lresid-builder"
|
AC_DEFINE(ENABLE_SIDPLAY, 1, [Define for libsidplayfp or libsidplay2 support])
|
||||||
AC_DEFINE(ENABLE_SIDPLAY, 1, [Define for libsidplay2 support])
|
|
||||||
if test x$found_sidplayfp = xyes; then
|
if test x$found_sidplayfp = xyes; then
|
||||||
AC_DEFINE(HAVE_SIDPLAYFP, 1, [Define if libsidplayfp is used instead of libsidplay2])
|
AC_DEFINE(HAVE_SIDPLAYFP, 1, [Define if libsidplayfp is used instead of libsidplay2])
|
||||||
|
else
|
||||||
|
SIDPLAY_LIBS="$SIDPLAY_LIBS -lresid-builder"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
16
doc/user.xml
16
doc/user.xml
@@ -2087,13 +2087,6 @@ run</programlisting>
|
|||||||
database.
|
database.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Note that unless overridden by the below settings (e.g. by
|
|
||||||
setting them to a blank value), general curl configuration
|
|
||||||
from environment variables such as http_proxy or specified
|
|
||||||
in ~/.curlrc will be in effect.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<informaltable>
|
<informaltable>
|
||||||
<tgroup cols="2">
|
<tgroup cols="2">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -2121,6 +2114,15 @@ run</programlisting>
|
|||||||
<application>MPD</application> instance.
|
<application>MPD</application> instance.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<varname>password</varname>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
The password used to log in to the "master"
|
||||||
|
<application>MPD</application> instance.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<varname>keepalive</varname>
|
<varname>keepalive</varname>
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class FfmpegProject(Project):
|
|||||||
|
|
||||||
if toolchain.is_arm:
|
if toolchain.is_arm:
|
||||||
arch = 'arm'
|
arch = 'arm'
|
||||||
|
elif toolchain.is_aarch64:
|
||||||
|
arch = 'aarch64'
|
||||||
else:
|
else:
|
||||||
arch = 'x86'
|
arch = 'x86'
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ liblame = AutotoolsProject(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ffmpeg = FfmpegProject(
|
ffmpeg = FfmpegProject(
|
||||||
'http://ffmpeg.org/releases/ffmpeg-4.0.tar.xz',
|
'http://ffmpeg.org/releases/ffmpeg-4.0.2.tar.xz',
|
||||||
'ed945daf40b124e77a685893cc025d086f638bc703183460aff49508edb3a43f',
|
'a95c0cc9eb990e94031d2183f2e6e444cc61c99f6f182d1575c433d62afb2f97',
|
||||||
'lib/libavcodec.a',
|
'lib/libavcodec.a',
|
||||||
[
|
[
|
||||||
'--disable-shared', '--enable-static',
|
'--disable-shared', '--enable-static',
|
||||||
@@ -341,8 +341,8 @@ ffmpeg = FfmpegProject(
|
|||||||
)
|
)
|
||||||
|
|
||||||
curl = AutotoolsProject(
|
curl = AutotoolsProject(
|
||||||
'http://curl.haxx.se/download/curl-7.60.0.tar.xz',
|
'http://curl.haxx.se/download/curl-7.61.0.tar.xz',
|
||||||
'8736ff8ded89ddf7e926eec7b16f82597d029fc1469f3a551f1fafaac164e6a0',
|
'ef6e55192d04713673b4409ccbcb4cb6cd723137d6e10ca45b0c593a454e1720',
|
||||||
'lib/libcurl.a',
|
'lib/libcurl.a',
|
||||||
[
|
[
|
||||||
'--disable-shared', '--enable-static',
|
'--disable-shared', '--enable-static',
|
||||||
@@ -364,9 +364,19 @@ curl = AutotoolsProject(
|
|||||||
patches='src/lib/curl/patches',
|
patches='src/lib/curl/patches',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
libexpat = AutotoolsProject(
|
||||||
|
'https://github.com/libexpat/libexpat/releases/download/R_2_2_6/expat-2.2.6.tar.bz2',
|
||||||
|
'17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2',
|
||||||
|
'lib/libexpat.a',
|
||||||
|
[
|
||||||
|
'--disable-shared', '--enable-static',
|
||||||
|
'--without-docbook',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
libnfs = AutotoolsProject(
|
libnfs = AutotoolsProject(
|
||||||
'https://github.com/sahlberg/libnfs/archive/libnfs-2.0.0.tar.gz',
|
'https://github.com/sahlberg/libnfs/archive/libnfs-3.0.0.tar.gz',
|
||||||
'7ea6cd8fa6c461d01091e584d424d28e137d23ff4b65b95d01a3fd0ef95d120e',
|
'445d92c5fc55e4a5b115e358e60486cf8f87ee50e0103d46a02e7fb4618566a5',
|
||||||
'lib/libnfs.a',
|
'lib/libnfs.a',
|
||||||
[
|
[
|
||||||
'--disable-shared', '--enable-static',
|
'--disable-shared', '--enable-static',
|
||||||
@@ -374,13 +384,15 @@ libnfs = AutotoolsProject(
|
|||||||
|
|
||||||
# work around -Wtautological-compare
|
# work around -Wtautological-compare
|
||||||
'--disable-werror',
|
'--disable-werror',
|
||||||
|
|
||||||
|
'--disable-utils', '--disable-examples',
|
||||||
],
|
],
|
||||||
base='libnfs-libnfs-2.0.0',
|
base='libnfs-libnfs-3.0.0',
|
||||||
autoreconf=True,
|
autoreconf=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
boost = BoostProject(
|
boost = BoostProject(
|
||||||
'http://downloads.sourceforge.net/project/boost/boost/1.66.0/boost_1_66_0.tar.bz2',
|
'http://downloads.sourceforge.net/project/boost/boost/1.68.0/boost_1_68_0.tar.bz2',
|
||||||
'5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9',
|
'7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7',
|
||||||
'include/boost/version.hpp',
|
'include/boost/version.hpp',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ class MesonProject(Project):
|
|||||||
cpu = 'armv7'
|
cpu = 'armv7'
|
||||||
else:
|
else:
|
||||||
cpu = 'armv6'
|
cpu = 'armv6'
|
||||||
|
elif toolchain.is_aarch64:
|
||||||
|
cpu_family = 'aarch64'
|
||||||
|
cpu = 'arm64-v8a'
|
||||||
else:
|
else:
|
||||||
cpu_family = 'x86'
|
cpu_family = 'x86'
|
||||||
if 'x86_64' in toolchain.arch:
|
if 'x86_64' in toolchain.arch:
|
||||||
@@ -51,6 +54,9 @@ c_link_args = %s
|
|||||||
cpp_args = %s
|
cpp_args = %s
|
||||||
cpp_link_args = %s
|
cpp_link_args = %s
|
||||||
|
|
||||||
|
# Keep Meson from executing Android-x86 test binariees
|
||||||
|
needs_exe_wrapper = true
|
||||||
|
|
||||||
[host_machine]
|
[host_machine]
|
||||||
system = '%s'
|
system = '%s'
|
||||||
cpu_family = '%s'
|
cpu_family = '%s'
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "util/StringBuffer.hxx"
|
#include "util/StringBuffer.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioFormat::ApplyMask(AudioFormat mask) noexcept
|
AudioFormat::ApplyMask(AudioFormat mask) noexcept
|
||||||
@@ -44,21 +44,16 @@ AudioFormat::ApplyMask(AudioFormat mask) noexcept
|
|||||||
StringBuffer<24>
|
StringBuffer<24>
|
||||||
ToString(const AudioFormat af) noexcept
|
ToString(const AudioFormat af) noexcept
|
||||||
{
|
{
|
||||||
StringBuffer<24> buffer;
|
|
||||||
|
|
||||||
if (af.format == SampleFormat::DSD && af.sample_rate > 0 &&
|
if (af.format == SampleFormat::DSD && af.sample_rate > 0 &&
|
||||||
af.sample_rate % 44100 == 0) {
|
af.sample_rate % 44100 == 0) {
|
||||||
/* use shortcuts such as "dsd64" which implies the
|
/* use shortcuts such as "dsd64" which implies the
|
||||||
sample rate */
|
sample rate */
|
||||||
snprintf(buffer.data(), buffer.capacity(), "dsd%u:%u",
|
return StringFormat<24>("dsd%u:%u",
|
||||||
af.sample_rate * 8 / 44100,
|
af.sample_rate * 8 / 44100,
|
||||||
af.channels);
|
af.channels);
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buffer.data(), buffer.capacity(), "%u:%s:%u",
|
return StringFormat<24>("%u:%s:%u",
|
||||||
af.sample_rate, sample_format_to_string(af.format),
|
af.sample_rate, sample_format_to_string(af.format),
|
||||||
af.channels);
|
af.channels);
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "pcm/SampleFormat.hxx"
|
#include "pcm/SampleFormat.hxx"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "ls.hxx"
|
#include "ls.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
#include "storage/StorageInterface.hxx"
|
#include "storage/StorageInterface.hxx"
|
||||||
@@ -83,7 +83,7 @@ LocateUri(const char *uri, const Client *client
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* skip the obsolete "file://" prefix */
|
/* skip the obsolete "file://" prefix */
|
||||||
const char *path_utf8 = StringAfterPrefix(uri, "file://");
|
const char *path_utf8 = StringAfterPrefixCaseASCII(uri, "file://");
|
||||||
if (path_utf8 != nullptr) {
|
if (path_utf8 != nullptr) {
|
||||||
if (!PathTraitsUTF8::IsAbsolute(path_utf8))
|
if (!PathTraitsUTF8::IsAbsolute(path_utf8))
|
||||||
throw std::runtime_error("Malformed file:// URI");
|
throw std::runtime_error("Malformed file:// URI");
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class ProxyDatabase final : public Database, SocketMonitor, IdleMonitor {
|
|||||||
DatabaseListener &listener;
|
DatabaseListener &listener;
|
||||||
|
|
||||||
const std::string host;
|
const std::string host;
|
||||||
|
const std::string password;
|
||||||
const unsigned port;
|
const unsigned port;
|
||||||
const bool keepalive;
|
const bool keepalive;
|
||||||
|
|
||||||
@@ -169,6 +170,13 @@ static constexpr struct {
|
|||||||
#if LIBMPDCLIENT_CHECK_VERSION(2,10,0)
|
#if LIBMPDCLIENT_CHECK_VERSION(2,10,0)
|
||||||
{ TAG_MUSICBRAINZ_RELEASETRACKID,
|
{ TAG_MUSICBRAINZ_RELEASETRACKID,
|
||||||
MPD_TAG_MUSICBRAINZ_RELEASETRACKID },
|
MPD_TAG_MUSICBRAINZ_RELEASETRACKID },
|
||||||
|
#endif
|
||||||
|
#if LIBMPDCLIENT_CHECK_VERSION(2,11,0)
|
||||||
|
{ TAG_ARTIST_SORT, MPD_TAG_ARTIST_SORT },
|
||||||
|
{ TAG_ALBUM_ARTIST_SORT, MPD_TAG_ALBUM_ARTIST_SORT },
|
||||||
|
#endif
|
||||||
|
#if LIBMPDCLIENT_CHECK_VERSION(2,12,0)
|
||||||
|
{ TAG_ALBUM_SORT, MPD_TAG_ALBUM_SORT },
|
||||||
#endif
|
#endif
|
||||||
{ TAG_NUM_OF_ITEM_TYPES, MPD_TAG_COUNT }
|
{ TAG_NUM_OF_ITEM_TYPES, MPD_TAG_COUNT }
|
||||||
};
|
};
|
||||||
@@ -359,6 +367,7 @@ ProxyDatabase::ProxyDatabase(EventLoop &_loop, DatabaseListener &_listener,
|
|||||||
SocketMonitor(_loop), IdleMonitor(_loop),
|
SocketMonitor(_loop), IdleMonitor(_loop),
|
||||||
listener(_listener),
|
listener(_listener),
|
||||||
host(block.GetBlockValue("host", "")),
|
host(block.GetBlockValue("host", "")),
|
||||||
|
password(block.GetBlockValue("password", "")),
|
||||||
port(block.GetBlockValue("port", 0u)),
|
port(block.GetBlockValue("port", 0u)),
|
||||||
keepalive(block.GetBlockValue("keepalive", false))
|
keepalive(block.GetBlockValue("keepalive", false))
|
||||||
{
|
{
|
||||||
@@ -402,6 +411,10 @@ ProxyDatabase::Connect()
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
CheckError(connection);
|
CheckError(connection);
|
||||||
|
|
||||||
|
if (!password.empty() &&
|
||||||
|
!mpd_run_password(connection, password.c_str()))
|
||||||
|
ThrowError(connection);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
mpd_connection_free(connection);
|
mpd_connection_free(connection);
|
||||||
connection = nullptr;
|
connection = nullptr;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -47,10 +48,6 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
|
|||||||
unsigned &didreadp,
|
unsigned &didreadp,
|
||||||
unsigned &totalp) const
|
unsigned &totalp) const
|
||||||
{
|
{
|
||||||
// Create request
|
|
||||||
char ofbuf[100], cntbuf[100];
|
|
||||||
sprintf(ofbuf, "%u", offset);
|
|
||||||
sprintf(cntbuf, "%u", count);
|
|
||||||
// Some devices require an empty SortCriteria, else bad params
|
// Some devices require an empty SortCriteria, else bad params
|
||||||
IXML_Document *request =
|
IXML_Document *request =
|
||||||
MakeActionHelper("Browse", m_serviceType.c_str(),
|
MakeActionHelper("Browse", m_serviceType.c_str(),
|
||||||
@@ -58,8 +55,10 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
|
|||||||
"BrowseFlag", "BrowseDirectChildren",
|
"BrowseFlag", "BrowseDirectChildren",
|
||||||
"Filter", "*",
|
"Filter", "*",
|
||||||
"SortCriteria", "",
|
"SortCriteria", "",
|
||||||
"StartingIndex", ofbuf,
|
"StartingIndex",
|
||||||
"RequestedCount", cntbuf);
|
StringFormat<32>("%u", offset).c_str(),
|
||||||
|
"RequestedCount",
|
||||||
|
StringFormat<32>("%u", count).c_str());
|
||||||
if (request == nullptr)
|
if (request == nullptr)
|
||||||
throw std::runtime_error("UpnpMakeAction() failed");
|
throw std::runtime_error("UpnpMakeAction() failed");
|
||||||
|
|
||||||
@@ -112,15 +111,13 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
|
|||||||
unsigned offset = 0, total = -1, count;
|
unsigned offset = 0, total = -1, count;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char ofbuf[100];
|
|
||||||
sprintf(ofbuf, "%d", offset);
|
|
||||||
|
|
||||||
UniqueIxmlDocument request(MakeActionHelper("Search", m_serviceType.c_str(),
|
UniqueIxmlDocument request(MakeActionHelper("Search", m_serviceType.c_str(),
|
||||||
"ContainerID", objectId,
|
"ContainerID", objectId,
|
||||||
"SearchCriteria", ss,
|
"SearchCriteria", ss,
|
||||||
"Filter", "*",
|
"Filter", "*",
|
||||||
"SortCriteria", "",
|
"SortCriteria", "",
|
||||||
"StartingIndex", ofbuf,
|
"StartingIndex",
|
||||||
|
StringFormat<32>("%u", offset).c_str(),
|
||||||
"RequestedCount", "0")); // Setting a value here gets twonky into fits
|
"RequestedCount", "0")); // Setting a value here gets twonky into fits
|
||||||
if (!request)
|
if (!request)
|
||||||
throw std::runtime_error("UpnpMakeAction() failed");
|
throw std::runtime_error("UpnpMakeAction() failed");
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
#include "ExcludeList.hxx"
|
#include "ExcludeList.hxx"
|
||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "fs/NarrowPath.hxx"
|
#include "fs/NarrowPath.hxx"
|
||||||
#include "fs/io/TextFile.hxx"
|
#include "input/TextInputStream.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -35,35 +35,29 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ExcludeList::ParseLine(char *line) noexcept
|
||||||
|
{
|
||||||
|
char *p = Strip(line);
|
||||||
|
if (*p != 0 && *p != '#')
|
||||||
|
patterns.emplace_front(p);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ExcludeList::LoadFile(Path path_fs) noexcept
|
ExcludeList::Load(InputStreamPtr is)
|
||||||
try {
|
{
|
||||||
#ifdef HAVE_CLASS_GLOB
|
#ifdef HAVE_CLASS_GLOB
|
||||||
TextFile file(path_fs);
|
TextInputStream tis(std::move(is));
|
||||||
|
|
||||||
char *line;
|
char *line;
|
||||||
while ((line = file.ReadLine()) != nullptr) {
|
while ((line = tis.ReadLine()) != nullptr)
|
||||||
char *p = strchr(line, '#');
|
ParseLine(line);
|
||||||
if (p != nullptr)
|
|
||||||
*p = 0;
|
|
||||||
|
|
||||||
p = Strip(line);
|
|
||||||
if (*p != 0)
|
|
||||||
patterns.emplace_front(p);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
/* not implemented */
|
/* not implemented */
|
||||||
(void)path_fs;
|
(void)path_fs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::system_error &e) {
|
|
||||||
if (!IsFileNotFound(e))
|
|
||||||
LogError(e);
|
|
||||||
return false;
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
LogError(e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
#include "fs/Glob.hxx"
|
#include "fs/Glob.hxx"
|
||||||
|
#include "input/Ptr.hxx"
|
||||||
|
|
||||||
#ifdef HAVE_CLASS_GLOB
|
#ifdef HAVE_CLASS_GLOB
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
@@ -62,13 +63,16 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Loads and parses a .mpdignore file.
|
* Loads and parses a .mpdignore file.
|
||||||
*/
|
*/
|
||||||
bool LoadFile(Path path_fs) noexcept;
|
bool Load(InputStreamPtr is);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether one of the patterns in the .mpdignore file matches
|
* Checks whether one of the patterns in the .mpdignore file matches
|
||||||
* the specified file name.
|
* the specified file name.
|
||||||
*/
|
*/
|
||||||
bool Check(Path name_fs) const noexcept;
|
bool Check(Path name_fs) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ParseLine(char *line) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
#include "storage/FileInfo.hxx"
|
#include "storage/FileInfo.hxx"
|
||||||
|
#include "input/InputStream.hxx"
|
||||||
|
#include "input/Error.hxx"
|
||||||
|
#include "thread/Cond.hxx"
|
||||||
#include "util/Alloc.hxx"
|
#include "util/Alloc.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
@@ -345,11 +348,16 @@ UpdateWalk::UpdateDirectory(Directory &directory,
|
|||||||
|
|
||||||
ExcludeList child_exclude_list(exclude_list);
|
ExcludeList child_exclude_list(exclude_list);
|
||||||
|
|
||||||
{
|
try {
|
||||||
const auto exclude_path_fs =
|
Mutex mutex;
|
||||||
storage.MapChildFS(directory.GetPath(), ".mpdignore");
|
Cond cond;
|
||||||
if (!exclude_path_fs.IsNull())
|
auto is = InputStream::OpenReady(PathTraitsUTF8::Build(storage.MapUTF8(directory.GetPath()).c_str(),
|
||||||
child_exclude_list.LoadFile(exclude_path_fs);
|
".mpdignore").c_str(),
|
||||||
|
mutex, cond);
|
||||||
|
child_exclude_list.Load(std::move(is));
|
||||||
|
} catch (...) {
|
||||||
|
if (!IsFileNotFound(std::current_exception()))
|
||||||
|
LogError(std::current_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!child_exclude_list.IsEmpty())
|
if (!child_exclude_list.IsEmpty())
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
@@ -38,7 +38,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define SUBTUNE_PREFIX "tune_"
|
#define SUBTUNE_PREFIX "tune_"
|
||||||
|
|
||||||
@@ -191,20 +190,17 @@ ScanGmeInfo(const gme_info_t &info, unsigned song_num, int track_count,
|
|||||||
tag_handler_invoke_duration(handler, handler_ctx,
|
tag_handler_invoke_duration(handler, handler_ctx,
|
||||||
SongTime::FromMS(info.play_length));
|
SongTime::FromMS(info.play_length));
|
||||||
|
|
||||||
if (track_count > 1) {
|
if (track_count > 1)
|
||||||
char track[16];
|
tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK,
|
||||||
sprintf(track, "%u", song_num + 1);
|
StringFormat<16>("%u", song_num + 1));
|
||||||
tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK, track);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.song != nullptr) {
|
if (info.song != nullptr) {
|
||||||
if (track_count > 1) {
|
if (track_count > 1) {
|
||||||
/* start numbering subtunes from 1 */
|
/* start numbering subtunes from 1 */
|
||||||
char tag_title[1024];
|
const auto tag_title =
|
||||||
snprintf(tag_title, sizeof(tag_title),
|
StringFormat<1024>("%s (%u/%d)",
|
||||||
"%s (%u/%d)",
|
info.song, song_num + 1,
|
||||||
info.song, song_num + 1,
|
track_count);
|
||||||
track_count);
|
|
||||||
tag_handler_invoke_tag(handler, handler_ctx,
|
tag_handler_invoke_tag(handler, handler_ctx,
|
||||||
TAG_TITLE, tag_title);
|
TAG_TITLE, tag_title);
|
||||||
} else
|
} else
|
||||||
@@ -297,9 +293,9 @@ gme_container_scan(Path path_fs)
|
|||||||
ScanMusicEmu(emu, i,
|
ScanMusicEmu(emu, i,
|
||||||
add_tag_handler, &tag_builder);
|
add_tag_handler, &tag_builder);
|
||||||
|
|
||||||
char track_name[64];
|
const auto track_name =
|
||||||
snprintf(track_name, sizeof(track_name),
|
StringFormat<64>(SUBTUNE_PREFIX "%03u.%s", i+1,
|
||||||
SUBTUNE_PREFIX "%03u.%s", i+1, subtune_suffix);
|
subtune_suffix);
|
||||||
tail = list.emplace_after(tail, track_name,
|
tail = list.emplace_after(tail, track_name,
|
||||||
tag_builder.Commit());
|
tag_builder.Commit());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "system/ByteOrder.hxx"
|
#include "system/ByteOrder.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
@@ -413,10 +413,9 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks,
|
|||||||
title = "";
|
title = "";
|
||||||
|
|
||||||
if (n_tracks > 1) {
|
if (n_tracks > 1) {
|
||||||
char tag_title[1024];
|
const auto tag_title =
|
||||||
snprintf(tag_title, sizeof(tag_title),
|
StringFormat<1024>("%s (%u/%u)",
|
||||||
"%s (%u/%u)",
|
title, track, n_tracks);
|
||||||
title, track, n_tracks);
|
|
||||||
tag_handler_invoke_tag(handler, handler_ctx,
|
tag_handler_invoke_tag(handler, handler_ctx,
|
||||||
TAG_TITLE, tag_title);
|
TAG_TITLE, tag_title);
|
||||||
} else
|
} else
|
||||||
@@ -435,9 +434,8 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks,
|
|||||||
date);
|
date);
|
||||||
|
|
||||||
/* track */
|
/* track */
|
||||||
char track_buffer[16];
|
tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK,
|
||||||
sprintf(track_buffer, "%d", track);
|
StringFormat<16>("%u", track));
|
||||||
tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK, track_buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "FileOutputStream.hxx"
|
#include "FileOutputStream.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
FileOutputStream::FileOutputStream(Path _path, Mode _mode)
|
FileOutputStream::FileOutputStream(Path _path, Mode _mode)
|
||||||
:path(_path), mode(_mode)
|
:path(_path), mode(_mode)
|
||||||
@@ -212,10 +213,9 @@ FileOutputStream::Commit()
|
|||||||
unlink(GetPath().c_str());
|
unlink(GetPath().c_str());
|
||||||
|
|
||||||
/* hard-link the temporary file to the final path */
|
/* hard-link the temporary file to the final path */
|
||||||
char fd_path[64];
|
if (linkat(AT_FDCWD,
|
||||||
snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d",
|
StringFormat<64>("/proc/self/fd/%d", fd.Get()),
|
||||||
fd.Get());
|
AT_FDCWD, path.c_str(),
|
||||||
if (linkat(AT_FDCWD, fd_path, AT_FDCWD, path.c_str(),
|
|
||||||
AT_SYMLINK_FOLLOW) < 0)
|
AT_SYMLINK_FOLLOW) < 0)
|
||||||
throw FormatErrno("Failed to commit %s",
|
throw FormatErrno("Failed to commit %s",
|
||||||
path.c_str());
|
path.c_str());
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "AsyncInputStream.hxx"
|
#include "AsyncInputStream.hxx"
|
||||||
#include "Domain.hxx"
|
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
#include "IOThread.hxx"
|
#include "IOThread.hxx"
|
||||||
|
|||||||
53
src/input/Error.cxx
Normal file
53
src/input/Error.cxx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2018 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 "Error.hxx"
|
||||||
|
#include "system/Error.hxx"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CURL
|
||||||
|
#include "lib/curl/Error.hxx"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_NFS
|
||||||
|
#include "lib/nfs/Error.hxx"
|
||||||
|
#include <nfsc/libnfs-raw-nfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsFileNotFound(std::exception_ptr ep)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ep);
|
||||||
|
} catch (const std::system_error &e) {
|
||||||
|
return IsFileNotFound(e);
|
||||||
|
#ifdef ENABLE_CURL
|
||||||
|
} catch (const HttpStatusError &e) {
|
||||||
|
return e.GetStatus() == 404;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_NFS
|
||||||
|
} catch (const NfsClientError &e) {
|
||||||
|
return e.GetCode() == NFS3ERR_NOENT;
|
||||||
|
#endif
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2017 The Music Player Daemon Project
|
* Copyright 2003-2018 The Music Player Daemon Project
|
||||||
* http://www.musicpd.org
|
* http://www.musicpd.org
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -17,11 +17,21 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MPD_INPUT_DOMAIN_HXX
|
#ifndef INPUT_ERROR_HXX
|
||||||
#define MPD_INPUT_DOMAIN_HXX
|
#define INPUT_ERROR_HXX
|
||||||
|
|
||||||
class Domain;
|
#include "check.h"
|
||||||
|
#include "Compiler.h"
|
||||||
|
|
||||||
extern const Domain input_domain;
|
#include <exception>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was this exception thrown because the requested file does not
|
||||||
|
* exist? This function attempts to recognize exceptions thrown by
|
||||||
|
* various input plugins.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
bool
|
||||||
|
IsFileNotFound(std::exception_ptr e);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "InputStream.hxx"
|
#include "InputStream.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
@@ -77,8 +77,8 @@ gcc_pure
|
|||||||
static bool
|
static bool
|
||||||
ExpensiveSeeking(const char *uri) noexcept
|
ExpensiveSeeking(const char *uri) noexcept
|
||||||
{
|
{
|
||||||
return StringStartsWith(uri, "http://") ||
|
return StringStartsWithCaseASCII(uri, "http://") ||
|
||||||
StringStartsWith(uri, "https://");
|
StringStartsWithCaseASCII(uri, "https://");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -29,4 +29,10 @@
|
|||||||
*/
|
*/
|
||||||
typedef uint64_t offset_type;
|
typedef uint64_t offset_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To format an offset_type with printf(). To use this, include
|
||||||
|
* <cinttypes>.
|
||||||
|
*/
|
||||||
|
#define PRIoffset PRIu64
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "Registry.hxx"
|
#include "Registry.hxx"
|
||||||
#include "InputPlugin.hxx"
|
#include "InputPlugin.hxx"
|
||||||
#include "LocalOpen.hxx"
|
#include "LocalOpen.hxx"
|
||||||
#include "Domain.hxx"
|
|
||||||
#include "plugins/RewindInputPlugin.hxx"
|
#include "plugins/RewindInputPlugin.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/ReusableArray.hxx"
|
#include "util/ReusableArray.hxx"
|
||||||
|
#include "util/ASCII.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
#include "event/MultiSocketMonitor.hxx"
|
#include "event/MultiSocketMonitor.hxx"
|
||||||
#include "event/DeferredMonitor.hxx"
|
#include "event/DeferredMonitor.hxx"
|
||||||
@@ -147,7 +147,7 @@ private:
|
|||||||
inline InputStream *
|
inline InputStream *
|
||||||
AlsaInputStream::Create(const char *uri, Mutex &mutex, Cond &cond)
|
AlsaInputStream::Create(const char *uri, Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
const char *device = StringAfterPrefix(uri, "alsa://");
|
const char *device = StringAfterPrefixCaseASCII(uri, "alsa://");
|
||||||
if (device == nullptr)
|
if (device == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include "../InputStream.hxx"
|
#include "../InputStream.hxx"
|
||||||
#include "../InputPlugin.hxx"
|
#include "../InputPlugin.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "system/ByteOrder.hxx"
|
#include "system/ByteOrder.hxx"
|
||||||
@@ -128,7 +128,7 @@ struct cdio_uri {
|
|||||||
static bool
|
static bool
|
||||||
parse_cdio_uri(struct cdio_uri *dest, const char *src)
|
parse_cdio_uri(struct cdio_uri *dest, const char *src)
|
||||||
{
|
{
|
||||||
if (!StringStartsWith(src, "cdda://"))
|
if (!StringStartsWithCaseASCII(src, "cdda://"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
src += 7;
|
src += 7;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "CurlInputPlugin.hxx"
|
#include "CurlInputPlugin.hxx"
|
||||||
|
#include "lib/curl/Error.hxx"
|
||||||
#include "lib/curl/Easy.hxx"
|
#include "lib/curl/Easy.hxx"
|
||||||
#include "lib/curl/Global.hxx"
|
#include "lib/curl/Global.hxx"
|
||||||
#include "lib/curl/Request.hxx"
|
#include "lib/curl/Request.hxx"
|
||||||
@@ -34,12 +35,15 @@
|
|||||||
#include "IOThread.hxx"
|
#include "IOThread.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
#include "util/NumberParser.hxx"
|
#include "util/NumberParser.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
#include "PluginUnavailable.hxx"
|
#include "PluginUnavailable.hxx"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -185,7 +189,9 @@ CurlInputStream::OnHeaders(unsigned status,
|
|||||||
assert(!postponed_exception);
|
assert(!postponed_exception);
|
||||||
|
|
||||||
if (status < 200 || status >= 300)
|
if (status < 200 || status >= 300)
|
||||||
throw FormatRuntimeError("got HTTP status %ld", status);
|
throw HttpStatusError(status,
|
||||||
|
StringFormat<40>("got HTTP status %u",
|
||||||
|
status).c_str());
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
const std::lock_guard<Mutex> protect(mutex);
|
||||||
|
|
||||||
@@ -371,13 +377,10 @@ CurlInputStream::InitEasy()
|
|||||||
if (proxy_port > 0)
|
if (proxy_port > 0)
|
||||||
request->SetOption(CURLOPT_PROXYPORT, (long)proxy_port);
|
request->SetOption(CURLOPT_PROXYPORT, (long)proxy_port);
|
||||||
|
|
||||||
if (proxy_user != nullptr && proxy_password != nullptr) {
|
if (proxy_user != nullptr && proxy_password != nullptr)
|
||||||
char proxy_auth_str[1024];
|
request->SetOption(CURLOPT_PROXYUSERPWD,
|
||||||
snprintf(proxy_auth_str, sizeof(proxy_auth_str),
|
StringFormat<1024>("%s:%s", proxy_user,
|
||||||
"%s:%s",
|
proxy_password).c_str());
|
||||||
proxy_user, proxy_password);
|
|
||||||
request->SetOption(CURLOPT_PROXYUSERPWD, proxy_auth_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
request->SetOption(CURLOPT_SSL_VERIFYPEER, verify_peer ? 1l : 0l);
|
request->SetOption(CURLOPT_SSL_VERIFYPEER, verify_peer ? 1l : 0l);
|
||||||
request->SetOption(CURLOPT_SSL_VERIFYHOST, verify_host ? 2l : 0l);
|
request->SetOption(CURLOPT_SSL_VERIFYHOST, verify_host ? 2l : 0l);
|
||||||
@@ -414,16 +417,10 @@ CurlInputStream::SeekInternal(offset_type new_offset)
|
|||||||
|
|
||||||
/* send the "Range" header */
|
/* send the "Range" header */
|
||||||
|
|
||||||
if (offset > 0) {
|
if (offset > 0)
|
||||||
char range[32];
|
request->SetOption(CURLOPT_RANGE,
|
||||||
#ifdef _WIN32
|
StringFormat<40>("%" PRIoffset "-",
|
||||||
// TODO: what can we use on Windows to format 64 bit?
|
offset).c_str());
|
||||||
sprintf(range, "%lu-", (long)offset);
|
|
||||||
#else
|
|
||||||
sprintf(range, "%llu-", (unsigned long long)offset);
|
|
||||||
#endif
|
|
||||||
request->SetOption(CURLOPT_RANGE, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
StartRequest();
|
StartRequest();
|
||||||
}
|
}
|
||||||
@@ -461,8 +458,8 @@ CurlInputStream::Open(const char *url, Mutex &mutex, Cond &cond)
|
|||||||
static InputStream *
|
static InputStream *
|
||||||
input_curl_open(const char *url, Mutex &mutex, Cond &cond)
|
input_curl_open(const char *url, Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
if (strncmp(url, "http://", 7) != 0 &&
|
if (!StringStartsWithCaseASCII(url, "http://") &&
|
||||||
strncmp(url, "https://", 8) != 0)
|
!StringStartsWithCaseASCII(url, "https://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return CurlInputStream::Open(url, mutex, cond);
|
return CurlInputStream::Open(url, mutex, cond);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "../InputStream.hxx"
|
#include "../InputStream.hxx"
|
||||||
#include "../InputPlugin.hxx"
|
#include "../InputPlugin.hxx"
|
||||||
#include "PluginUnavailable.hxx"
|
#include "PluginUnavailable.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavformat/avio.h>
|
#include <libavformat/avio.h>
|
||||||
@@ -85,12 +85,12 @@ static InputStream *
|
|||||||
input_ffmpeg_open(const char *uri,
|
input_ffmpeg_open(const char *uri,
|
||||||
Mutex &mutex, Cond &cond)
|
Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
if (!StringStartsWith(uri, "gopher://") &&
|
if (!StringStartsWithCaseASCII(uri, "gopher://") &&
|
||||||
!StringStartsWith(uri, "rtp://") &&
|
!StringStartsWithCaseASCII(uri, "rtp://") &&
|
||||||
!StringStartsWith(uri, "rtsp://") &&
|
!StringStartsWithCaseASCII(uri, "rtsp://") &&
|
||||||
!StringStartsWith(uri, "rtmp://") &&
|
!StringStartsWithCaseASCII(uri, "rtmp://") &&
|
||||||
!StringStartsWith(uri, "rtmpt://") &&
|
!StringStartsWithCaseASCII(uri, "rtmpt://") &&
|
||||||
!StringStartsWith(uri, "rtmps://"))
|
!StringStartsWithCaseASCII(uri, "rtmps://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
AVIOContext *h;
|
AVIOContext *h;
|
||||||
|
|||||||
@@ -65,12 +65,9 @@ OpenFileInputStream(Path path,
|
|||||||
throw FormatRuntimeError("Not a regular file: %s",
|
throw FormatRuntimeError("Not a regular file: %s",
|
||||||
path.c_str());
|
path.c_str());
|
||||||
|
|
||||||
#if !defined(__BIONIC__) || __ANDROID_API__ >= 21
|
|
||||||
/* posix_fadvise() requires Android API 21 */
|
|
||||||
#ifdef POSIX_FADV_SEQUENTIAL
|
#ifdef POSIX_FADV_SEQUENTIAL
|
||||||
posix_fadvise(reader.GetFD().Get(), (off_t)0, info.GetSize(),
|
posix_fadvise(reader.GetFD().Get(), (off_t)0, info.GetSize(),
|
||||||
POSIX_FADV_SEQUENTIAL);
|
POSIX_FADV_SEQUENTIAL);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return InputStreamPtr(new FileInputStream(path.ToUTF8().c_str(),
|
return InputStreamPtr(new FileInputStream(path.ToUTF8().c_str(),
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "input/ThreadInputStream.hxx"
|
#include "input/ThreadInputStream.hxx"
|
||||||
#include "input/InputPlugin.hxx"
|
#include "input/InputPlugin.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#include <libmms/mmsx.h>
|
#include <libmms/mmsx.h>
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ static InputStream *
|
|||||||
input_mms_open(const char *url,
|
input_mms_open(const char *url,
|
||||||
Mutex &mutex, Cond &cond)
|
Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
if (!StringStartsWith(url, "mms://") &&
|
if (!StringStartsWithCaseASCII(url, "mms://") &&
|
||||||
!StringStartsWith(url, "mmsh://") &&
|
!StringStartsWithCaseASCII(url, "mmsh://") &&
|
||||||
!StringStartsWith(url, "mmst://") &&
|
!StringStartsWithCaseASCII(url, "mmst://") &&
|
||||||
!StringStartsWith(url, "mmsu://"))
|
!StringStartsWithCaseASCII(url, "mmsu://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto m = new MmsInputStream(url, mutex, cond);
|
auto m = new MmsInputStream(url, mutex, cond);
|
||||||
|
|||||||
@@ -23,9 +23,7 @@
|
|||||||
#include "../InputPlugin.hxx"
|
#include "../InputPlugin.hxx"
|
||||||
#include "lib/nfs/Glue.hxx"
|
#include "lib/nfs/Glue.hxx"
|
||||||
#include "lib/nfs/FileReader.hxx"
|
#include "lib/nfs/FileReader.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not buffer more than this number of bytes. It should be a
|
* Do not buffer more than this number of bytes. It should be a
|
||||||
@@ -219,7 +217,7 @@ static InputStream *
|
|||||||
input_nfs_open(const char *uri,
|
input_nfs_open(const char *uri,
|
||||||
Mutex &mutex, Cond &cond)
|
Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
if (!StringStartsWith(uri, "nfs://"))
|
if (!StringStartsWithCaseASCII(uri, "nfs://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
NfsInputStream *is = new NfsInputStream(uri, mutex, cond);
|
NfsInputStream *is = new NfsInputStream(uri, mutex, cond);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "../InputPlugin.hxx"
|
#include "../InputPlugin.hxx"
|
||||||
#include "PluginUnavailable.hxx"
|
#include "PluginUnavailable.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#include <libsmbclient.h>
|
#include <libsmbclient.h>
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ static InputStream *
|
|||||||
input_smbclient_open(const char *uri,
|
input_smbclient_open(const char *uri,
|
||||||
Mutex &mutex, Cond &cond)
|
Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
if (!StringStartsWith(uri, "smb://"))
|
if (!StringStartsWithCaseASCII(uri, "smb://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(smbclient_mutex);
|
const std::lock_guard<Mutex> protect(smbclient_mutex);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2017 The Music Player Daemon Project
|
* Copyright 2003-2018 The Music Player Daemon Project
|
||||||
* http://www.musicpd.org
|
* http://www.musicpd.org
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -17,8 +17,26 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#ifndef CURL_ERROR_HXX
|
||||||
#include "Domain.hxx"
|
#define CURL_ERROR_HXX
|
||||||
#include "util/Domain.hxx"
|
|
||||||
|
|
||||||
const Domain input_domain("input");
|
#include <stdexcept>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when an unsuccessful status was received from the HTTP
|
||||||
|
* server.
|
||||||
|
*/
|
||||||
|
class HttpStatusError : public std::runtime_error {
|
||||||
|
unsigned status;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename M>
|
||||||
|
explicit HttpStatusError(unsigned _status, M &&_msg) noexcept
|
||||||
|
:std::runtime_error(std::forward<M>(_msg)), status(_status) {}
|
||||||
|
|
||||||
|
unsigned GetStatus() const noexcept {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "Domain.hxx"
|
#include "Domain.hxx"
|
||||||
#include "LogV.hxx"
|
#include "LogV.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavutil/log.h>
|
#include <libavutil/log.h>
|
||||||
@@ -57,9 +58,10 @@ FfmpegLogCallback(gcc_unused void *ptr, int level, const char *fmt, va_list vl)
|
|||||||
cls = *(const AVClass *const*)ptr;
|
cls = *(const AVClass *const*)ptr;
|
||||||
|
|
||||||
if (cls != nullptr) {
|
if (cls != nullptr) {
|
||||||
char domain[64];
|
const auto domain =
|
||||||
snprintf(domain, sizeof(domain), "%s/%s",
|
StringFormat<64>("%s/%s",
|
||||||
ffmpeg_domain.GetName(), cls->item_name(ptr));
|
ffmpeg_domain.GetName(),
|
||||||
|
cls->item_name(ptr));
|
||||||
const Domain d(domain);
|
const Domain d(domain);
|
||||||
LogFormatV(d, FfmpegImportLogLevel(level), fmt, vl);
|
LogFormatV(d, FfmpegImportLogLevel(level), fmt, vl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "Connection.hxx"
|
#include "Connection.hxx"
|
||||||
|
#include "Error.hxx"
|
||||||
#include "Lease.hxx"
|
#include "Lease.hxx"
|
||||||
#include "Callback.hxx"
|
#include "Callback.hxx"
|
||||||
#include "event/Loop.hxx"
|
#include "event/Loop.hxx"
|
||||||
@@ -139,7 +140,7 @@ NfsConnection::CancellableCallback::Callback(int err, void *data)
|
|||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
cb.OnNfsCallback((unsigned)err, data);
|
cb.OnNfsCallback((unsigned)err, data);
|
||||||
else
|
else
|
||||||
cb.OnNfsError(std::make_exception_ptr(std::runtime_error((const char *)data)));
|
cb.OnNfsError(std::make_exception_ptr(NfsClientError(-err, (const char *)data)));
|
||||||
} else {
|
} else {
|
||||||
if (open) {
|
if (open) {
|
||||||
/* a nfs_open_async() call was cancelled - to
|
/* a nfs_open_async() call was cancelled - to
|
||||||
|
|||||||
76
src/lib/nfs/Error.cxx
Normal file
76
src/lib/nfs/Error.cxx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007-2017 Content Management AG
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Error.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <nfsc/libnfs.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static StringBuffer<256>
|
||||||
|
FormatNfsClientError(struct nfs_context *nfs, const char *msg) noexcept
|
||||||
|
{
|
||||||
|
assert(msg != nullptr);
|
||||||
|
|
||||||
|
const char *msg2 = nfs_get_error(nfs);
|
||||||
|
return StringFormat<256>("%s: %s", msg, msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
NfsClientError::NfsClientError(struct nfs_context *nfs, const char *msg) noexcept
|
||||||
|
:std::runtime_error(FormatNfsClientError(nfs, msg).c_str()),
|
||||||
|
code(0) {}
|
||||||
|
|
||||||
|
static StringBuffer<256>
|
||||||
|
FormatNfsClientError(int err, struct nfs_context *nfs, void *data,
|
||||||
|
const char *msg) noexcept
|
||||||
|
{
|
||||||
|
assert(msg != nullptr);
|
||||||
|
assert(err < 0);
|
||||||
|
|
||||||
|
const char *msg2 = (const char *)data;
|
||||||
|
if (data == nullptr || *(const char *)data == 0) {
|
||||||
|
msg2 = nfs_get_error(nfs);
|
||||||
|
if (msg2 == nullptr)
|
||||||
|
msg2 = strerror(-err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringFormat<256>("%s: %s", msg, msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
NfsClientError::NfsClientError(int err, struct nfs_context *nfs, void *data,
|
||||||
|
const char *msg) noexcept
|
||||||
|
:std::runtime_error(FormatNfsClientError(err, nfs, data, msg).c_str()),
|
||||||
|
code(-err) {}
|
||||||
58
src/lib/nfs/Error.hxx
Normal file
58
src/lib/nfs/Error.hxx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007-2017 Content Management AG
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NFS_ERROR_HXX
|
||||||
|
#define NFS_ERROR_HXX
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
class NfsClientError : public std::runtime_error {
|
||||||
|
int code;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NfsClientError(const char *_msg) noexcept
|
||||||
|
:std::runtime_error(_msg), code(0) {}
|
||||||
|
|
||||||
|
NfsClientError(int _code, const char *_msg) noexcept
|
||||||
|
:std::runtime_error(_msg), code(_code) {}
|
||||||
|
|
||||||
|
NfsClientError(struct nfs_context *nfs, const char *msg) noexcept;
|
||||||
|
|
||||||
|
NfsClientError(int err, struct nfs_context *nfs, void *data,
|
||||||
|
const char *msg) noexcept;
|
||||||
|
|
||||||
|
int GetCode() const noexcept {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "Connection.hxx"
|
#include "Connection.hxx"
|
||||||
#include "event/Call.hxx"
|
#include "event/Call.hxx"
|
||||||
#include "IOThread.hxx"
|
#include "IOThread.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ NfsFileReader::Open(const char *uri)
|
|||||||
{
|
{
|
||||||
assert(state == State::INITIAL);
|
assert(state == State::INITIAL);
|
||||||
|
|
||||||
if (!StringStartsWith(uri, "nfs://"))
|
if (!StringStartsWithCaseASCII(uri, "nfs://"))
|
||||||
throw std::runtime_error("Malformed nfs:// URI");
|
throw std::runtime_error("Malformed nfs:// URI");
|
||||||
|
|
||||||
uri += 6;
|
uri += 6;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ls.hxx"
|
#include "ls.hxx"
|
||||||
#include "client/Response.hxx"
|
#include "client/Response.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -97,7 +97,7 @@ uri_supported_scheme(const char *uri) noexcept
|
|||||||
assert(uri_has_scheme(uri));
|
assert(uri_has_scheme(uri));
|
||||||
|
|
||||||
while (*urlPrefixes) {
|
while (*urlPrefixes) {
|
||||||
if (StringStartsWith(uri, *urlPrefixes))
|
if (StringStartsWithCaseASCII(uri, *urlPrefixes))
|
||||||
return true;
|
return true;
|
||||||
urlPrefixes++;
|
urlPrefixes++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include <roaraudio.h>
|
#include <roaraudio.h>
|
||||||
#undef new
|
#undef new
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
class RoarOutput {
|
class RoarOutput {
|
||||||
friend struct AudioOutputWrapper<RoarOutput>;
|
friend struct AudioOutputWrapper<RoarOutput>;
|
||||||
|
|
||||||
|
|||||||
@@ -122,15 +122,6 @@ HttpdClient::HandleLine(const char *line)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringEqualsCaseASCII(line, "transferMode.dlna.org: Streaming", 32)) {
|
|
||||||
/* Send as dlna */
|
|
||||||
dlna_streaming_requested = true;
|
|
||||||
/* metadata is not supported by dlna streaming, so disable it */
|
|
||||||
metadata_supported = false;
|
|
||||||
metadata_requested = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* expect more request headers */
|
/* expect more request headers */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -148,22 +139,7 @@ HttpdClient::SendResponse()
|
|||||||
|
|
||||||
assert(state == RESPONSE);
|
assert(state == RESPONSE);
|
||||||
|
|
||||||
if (dlna_streaming_requested) {
|
if (metadata_requested) {
|
||||||
snprintf(buffer, sizeof(buffer),
|
|
||||||
"HTTP/1.1 206 OK\r\n"
|
|
||||||
"Content-Type: %s\r\n"
|
|
||||||
"Content-Length: 10000\r\n"
|
|
||||||
"Content-RangeX: 0-1000000/1000000\r\n"
|
|
||||||
"transferMode.dlna.org: Streaming\r\n"
|
|
||||||
"Accept-Ranges: bytes\r\n"
|
|
||||||
"Connection: close\r\n"
|
|
||||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
|
||||||
"contentFeatures.dlna.org: DLNA.ORG_OP=01;DLNA.ORG_CI=0\r\n"
|
|
||||||
"\r\n",
|
|
||||||
httpd.content_type);
|
|
||||||
response = buffer;
|
|
||||||
|
|
||||||
} else if (metadata_requested) {
|
|
||||||
allocated =
|
allocated =
|
||||||
icy_server_metadata_header(httpd.name, httpd.genre,
|
icy_server_metadata_header(httpd.name, httpd.genre,
|
||||||
httpd.website,
|
httpd.website,
|
||||||
@@ -202,7 +178,6 @@ HttpdClient::HttpdClient(HttpdOutput &_httpd, int _fd, EventLoop &_loop,
|
|||||||
state(REQUEST),
|
state(REQUEST),
|
||||||
queue_size(0),
|
queue_size(0),
|
||||||
head_method(false),
|
head_method(false),
|
||||||
dlna_streaming_requested(false),
|
|
||||||
metadata_supported(_metadata_supported),
|
metadata_supported(_metadata_supported),
|
||||||
metadata_requested(false), metadata_sent(true),
|
metadata_requested(false), metadata_sent(true),
|
||||||
metaint(8192), /*TODO: just a std value */
|
metaint(8192), /*TODO: just a std value */
|
||||||
|
|||||||
@@ -82,11 +82,6 @@ class HttpdClient final
|
|||||||
*/
|
*/
|
||||||
bool head_method;
|
bool head_method;
|
||||||
|
|
||||||
/**
|
|
||||||
* If DLNA streaming was an option.
|
|
||||||
*/
|
|
||||||
bool dlna_streaming_requested;
|
|
||||||
|
|
||||||
/* ICY */
|
/* ICY */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "SoxrResampler.hxx"
|
#include "SoxrResampler.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
enum class SelectedResampler {
|
enum class SelectedResampler {
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#include "PcmDop.hxx"
|
#include "PcmDop.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
PcmExport::Open(SampleFormat sample_format, unsigned _channels,
|
PcmExport::Open(SampleFormat sample_format, unsigned _channels,
|
||||||
Params params)
|
Params params)
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ CueParser::Feed2(char *p) noexcept
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (strcmp(type, "WAVE") != 0 &&
|
if (strcmp(type, "WAVE") != 0 &&
|
||||||
|
strcmp(type, "FLAC") != 0 && /* non-standard */
|
||||||
strcmp(type, "MP3") != 0 &&
|
strcmp(type, "MP3") != 0 &&
|
||||||
strcmp(type, "AIFF") != 0) {
|
strcmp(type, "AIFF") != 0) {
|
||||||
state = IGNORE_FILE;
|
state = IGNORE_FILE;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "tag/TagBuilder.hxx"
|
#include "tag/TagBuilder.hxx"
|
||||||
|
#include "util/ASCII.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/Alloc.hxx"
|
#include "util/Alloc.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@@ -68,7 +69,7 @@ soundcloud_resolve(const char* uri)
|
|||||||
{
|
{
|
||||||
char *u, *ru;
|
char *u, *ru;
|
||||||
|
|
||||||
if (StringStartsWith(uri, "https://")) {
|
if (StringStartsWithCaseASCII(uri, "https://")) {
|
||||||
u = xstrdup(uri);
|
u = xstrdup(uri);
|
||||||
} else if (StringStartsWith(uri, "soundcloud.com")) {
|
} else if (StringStartsWith(uri, "soundcloud.com")) {
|
||||||
u = xstrcatdup("https://", uri);
|
u = xstrcatdup("https://", uri);
|
||||||
@@ -273,7 +274,7 @@ try {
|
|||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
|
soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
|
||||||
{
|
{
|
||||||
assert(strncmp(uri, "soundcloud://", 13) == 0);
|
assert(StringEqualsCaseASCII(uri, "soundcloud://", 13));
|
||||||
uri += 13;
|
uri += 13;
|
||||||
|
|
||||||
char *u = nullptr;
|
char *u = nullptr;
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
#ifndef MPD_ACK_H
|
#ifndef MPD_ACK_H
|
||||||
#define MPD_ACK_H
|
#define MPD_ACK_H
|
||||||
|
|
||||||
#include <stdexcept>
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdexcept>
|
||||||
|
|
||||||
class Domain;
|
class Domain;
|
||||||
|
|
||||||
@@ -60,9 +60,9 @@ template<typename... Args>
|
|||||||
static inline ProtocolError
|
static inline ProtocolError
|
||||||
FormatProtocolError(enum ack code, const char *fmt, Args&&... args) noexcept
|
FormatProtocolError(enum ack code, const char *fmt, Args&&... args) noexcept
|
||||||
{
|
{
|
||||||
char buffer[256];
|
return ProtocolError(code,
|
||||||
snprintf(buffer, sizeof(buffer), fmt, std::forward<Args>(args)...);
|
StringFormat<256>(fmt,
|
||||||
return ProtocolError(code, buffer);
|
std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,8 +33,10 @@
|
|||||||
#include "event/DeferredMonitor.hxx"
|
#include "event/DeferredMonitor.hxx"
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
|
#include "util/ASCII.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
#include "util/TimeParser.hxx"
|
#include "util/TimeParser.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
|
|
||||||
@@ -296,9 +298,7 @@ public:
|
|||||||
{
|
{
|
||||||
request.SetOption(CURLOPT_CUSTOMREQUEST, "PROPFIND");
|
request.SetOption(CURLOPT_CUSTOMREQUEST, "PROPFIND");
|
||||||
|
|
||||||
char buffer[40];
|
request_headers.Append(StringFormat<40>("depth: %u", depth));
|
||||||
sprintf(buffer, "depth: %u", depth);
|
|
||||||
request_headers.Append(buffer);
|
|
||||||
|
|
||||||
request.SetOption(CURLOPT_HTTPHEADER, request_headers.Get());
|
request.SetOption(CURLOPT_HTTPHEADER, request_headers.Get());
|
||||||
|
|
||||||
@@ -591,8 +591,8 @@ CurlStorage::OpenDirectory(const char *uri_utf8)
|
|||||||
static Storage *
|
static Storage *
|
||||||
CreateCurlStorageURI(EventLoop &event_loop, const char *uri)
|
CreateCurlStorageURI(EventLoop &event_loop, const char *uri)
|
||||||
{
|
{
|
||||||
if (strncmp(uri, "http://", 7) != 0 &&
|
if (!StringStartsWithCaseASCII(uri, "http://") &&
|
||||||
strncmp(uri, "https://", 8) != 0)
|
!StringStartsWithCaseASCII(uri, "https://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return new CurlStorage(event_loop, uri);
|
return new CurlStorage(event_loop, uri);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "event/Call.hxx"
|
#include "event/Call.hxx"
|
||||||
#include "event/DeferredMonitor.hxx"
|
#include "event/DeferredMonitor.hxx"
|
||||||
#include "event/TimeoutMonitor.hxx"
|
#include "event/TimeoutMonitor.hxx"
|
||||||
|
#include "util/ASCII.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -401,11 +402,10 @@ NfsStorage::OpenDirectory(const char *uri_utf8)
|
|||||||
static Storage *
|
static Storage *
|
||||||
CreateNfsStorageURI(EventLoop &event_loop, const char *base)
|
CreateNfsStorageURI(EventLoop &event_loop, const char *base)
|
||||||
{
|
{
|
||||||
if (strncmp(base, "nfs://", 6) != 0)
|
const char *p = StringAfterPrefixCaseASCII(base, "nfs://");
|
||||||
|
if (p == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const char *p = base + 6;
|
|
||||||
|
|
||||||
const char *mount = strchr(p, '/');
|
const char *mount = strchr(p, '/');
|
||||||
if (mount == nullptr)
|
if (mount == nullptr)
|
||||||
throw std::runtime_error("Malformed nfs:// URI");
|
throw std::runtime_error("Malformed nfs:// URI");
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
|
#include "util/ASCII.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
|
||||||
@@ -182,7 +183,7 @@ SmbclientDirectoryReader::GetInfo(gcc_unused bool follow)
|
|||||||
static Storage *
|
static Storage *
|
||||||
CreateSmbclientStorageURI(gcc_unused EventLoop &event_loop, const char *base)
|
CreateSmbclientStorageURI(gcc_unused EventLoop &event_loop, const char *base)
|
||||||
{
|
{
|
||||||
if (strncmp(base, "smb://", 6) != 0)
|
if (!StringStartsWithCaseASCII(base, "smb://"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
SmbclientInit();
|
SmbclientInit();
|
||||||
|
|||||||
@@ -22,21 +22,6 @@
|
|||||||
#include "EPollFD.hxx"
|
#include "EPollFD.hxx"
|
||||||
#include "FatalError.hxx"
|
#include "FatalError.hxx"
|
||||||
|
|
||||||
#if defined(__BIONIC__) && __ANDROID_API__ < 21
|
|
||||||
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#define EPOLL_CLOEXEC O_CLOEXEC
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
epoll_create1(int flags)
|
|
||||||
{
|
|
||||||
return syscall(__NR_epoll_create1, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EPollFD::EPollFD()
|
EPollFD::EPollFD()
|
||||||
:fd(::epoll_create1(EPOLL_CLOEXEC))
|
:fd(::epoll_create1(EPOLL_CLOEXEC))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
#include "TagHandler.hxx"
|
#include "TagHandler.hxx"
|
||||||
#include "TagBuilder.hxx"
|
#include "TagBuilder.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -42,11 +42,8 @@ add_tag_tag(TagType type, const char *value, void *ctx)
|
|||||||
/* filter out this extra data and leading zeroes */
|
/* filter out this extra data and leading zeroes */
|
||||||
char *end;
|
char *end;
|
||||||
unsigned n = strtoul(value, &end, 10);
|
unsigned n = strtoul(value, &end, 10);
|
||||||
if (value != end) {
|
if (value != end)
|
||||||
char s[21];
|
tag.AddItem(type, StringFormat<21>("%u", n));
|
||||||
if (snprintf(s, 21, "%u", n) > 0)
|
|
||||||
tag.AddItem(type, s);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
tag.AddItem(type, value);
|
tag.AddItem(type, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_NAME
|
#ifdef HAVE_THREAD_NAME
|
||||||
# include <stdio.h>
|
#include "util/StringFormat.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -59,9 +59,7 @@ static inline void
|
|||||||
FormatThreadName(const char *fmt, gcc_unused Args&&... args)
|
FormatThreadName(const char *fmt, gcc_unused Args&&... args)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREAD_NAME
|
#ifdef HAVE_THREAD_NAME
|
||||||
char buffer[16];
|
SetThreadName(StringFormat<16>(fmt, args...));
|
||||||
snprintf(buffer, sizeof(buffer), fmt, args...);
|
|
||||||
SetThreadName(buffer);
|
|
||||||
#else
|
#else
|
||||||
(void)fmt;
|
(void)fmt;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Max Kellermann <max.kellermann@gmail.com>
|
* Copyright (C) 2013-2018 Max Kellermann <max.kellermann@gmail.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#ifndef ASCII_HXX
|
#ifndef ASCII_HXX
|
||||||
#define ASCII_HXX
|
#define ASCII_HXX
|
||||||
|
|
||||||
|
#include "StringView.hxx"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -69,4 +70,20 @@ StringEqualsCaseASCII(const char *a, const char *b, size_t n) noexcept
|
|||||||
return strncasecmp(a, b, n) == 0;
|
return strncasecmp(a, b, n) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_pure gcc_nonnull_all
|
||||||
|
static inline bool
|
||||||
|
StringStartsWithCaseASCII(const char *haystack, StringView needle) noexcept
|
||||||
|
{
|
||||||
|
return StringEqualsCaseASCII(haystack, needle.data, needle.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_pure gcc_nonnull_all
|
||||||
|
static inline const char *
|
||||||
|
StringAfterPrefixCaseASCII(const char *haystack, StringView needle) noexcept
|
||||||
|
{
|
||||||
|
return StringStartsWithCaseASCII(haystack, needle)
|
||||||
|
? haystack + needle.size
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,14 +23,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AllocatedString<>
|
AllocatedString<>
|
||||||
FormatStringV(const char *fmt, va_list args)
|
FormatStringV(const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
|
||||||
va_list tmp;
|
va_list tmp;
|
||||||
va_copy(tmp, args);
|
va_copy(tmp, args);
|
||||||
const int length = vsnprintf(NULL, 0, fmt, tmp);
|
const int length = vsnprintf(NULL, 0, fmt, tmp);
|
||||||
@@ -43,22 +38,6 @@ FormatStringV(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 AllocatedString<>::Donate(buffer);
|
return AllocatedString<>::Donate(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 AllocatedString<>::Donate(p);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatedString<>
|
AllocatedString<>
|
||||||
|
|||||||
69
src/util/StringFormat.hxx
Normal file
69
src/util/StringFormat.hxx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2015 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STRING_FORMAT_HXX
|
||||||
|
#define STRING_FORMAT_HXX
|
||||||
|
|
||||||
|
#include "StringBuffer.hxx"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static inline void
|
||||||
|
StringFormat(char *buffer, size_t size,
|
||||||
|
const char *fmt, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
snprintf(buffer, size, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t CAPACITY, typename... Args>
|
||||||
|
static inline void
|
||||||
|
StringFormat(StringBuffer<CAPACITY> &buffer,
|
||||||
|
const char *fmt, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
StringFormat(buffer.data(), buffer.capacity(), fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t CAPACITY, typename... Args>
|
||||||
|
static inline StringBuffer<CAPACITY>
|
||||||
|
StringFormat(const char *fmt, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
StringBuffer<CAPACITY> result;
|
||||||
|
StringFormat(result, fmt, args...);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static inline void
|
||||||
|
StringFormatUnsafe(char *buffer, const char *fmt, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
sprintf(buffer, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "UriUtil.hxx"
|
#include "UriUtil.hxx"
|
||||||
#include "StringCompare.hxx"
|
#include "ASCII.hxx"
|
||||||
#include "CharUtil.hxx"
|
#include "CharUtil.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -169,7 +169,7 @@ SkipUriScheme(const char *uri) noexcept
|
|||||||
{
|
{
|
||||||
const char *const schemes[] = { "http://", "https://", "ftp://" };
|
const char *const schemes[] = { "http://", "https://", "ftp://" };
|
||||||
for (auto scheme : schemes) {
|
for (auto scheme : schemes) {
|
||||||
auto result = StringAfterPrefix(uri, scheme);
|
auto result = StringAfterPrefixCaseASCII(uri, scheme);
|
||||||
if (result != nullptr)
|
if (result != nullptr)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class CrossGccToolchain:
|
|||||||
|
|
||||||
self.is_arm = arch.startswith('arm')
|
self.is_arm = arch.startswith('arm')
|
||||||
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
||||||
|
self.is_aarch64 = arch == 'aarch64'
|
||||||
self.is_windows = 'mingw32' in arch
|
self.is_windows = 'mingw32' in arch
|
||||||
|
|
||||||
self.env = dict(os.environ)
|
self.env = dict(os.environ)
|
||||||
@@ -86,6 +87,7 @@ thirdparty_libs = [
|
|||||||
liblame,
|
liblame,
|
||||||
ffmpeg,
|
ffmpeg,
|
||||||
curl,
|
curl,
|
||||||
|
libexpat,
|
||||||
libnfs,
|
libnfs,
|
||||||
boost,
|
boost,
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user