Compare commits
108 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
323231d1dd | ||
![]() |
714011c81e | ||
![]() |
952ff4207b | ||
![]() |
150b16ec2c | ||
![]() |
c98bc4a243 | ||
![]() |
014f8cd693 | ||
![]() |
aea37e46e3 | ||
![]() |
31ab78ae8e | ||
![]() |
f82e1453e4 | ||
![]() |
a2b77c8813 | ||
![]() |
18add29472 | ||
![]() |
b111a8fe8d | ||
![]() |
3b23cf0258 | ||
![]() |
28e864e096 | ||
![]() |
1de19b921a | ||
![]() |
ff162b5a03 | ||
![]() |
d8e4705dd4 | ||
![]() |
338e1f5926 | ||
![]() |
a7fdfa08e1 | ||
![]() |
9703a401c5 | ||
![]() |
753a2aa462 | ||
![]() |
10990a0684 | ||
![]() |
91254e9211 | ||
![]() |
0f79287b04 | ||
![]() |
f2fac77d8c | ||
![]() |
81b7373637 | ||
![]() |
fa67c2548a | ||
![]() |
ea80587ddb | ||
![]() |
828f5f8384 | ||
![]() |
1295a1272a | ||
![]() |
66646d9276 | ||
![]() |
d0497dba92 | ||
![]() |
42914e8227 | ||
![]() |
59b49b7881 | ||
![]() |
5620f16330 | ||
![]() |
be024d4ad7 | ||
![]() |
75c740fe2b | ||
![]() |
6c8d86bb90 | ||
![]() |
b253a6b71e | ||
![]() |
ca7b4df812 | ||
![]() |
bc8dd57236 | ||
![]() |
f4f461b8bb | ||
![]() |
cbb9b6957f | ||
![]() |
f6b56c9317 | ||
![]() |
3717fb6c8d | ||
![]() |
f6abbc01bd | ||
![]() |
57a71c157d | ||
![]() |
cc76aeb7bb | ||
![]() |
811cabf8a9 | ||
![]() |
bf8d2f93d2 | ||
![]() |
07d8259ad6 | ||
![]() |
a00d412008 | ||
![]() |
5fb39658f1 | ||
![]() |
b0703b92c3 | ||
![]() |
dd9fd3d8a7 | ||
![]() |
cf0c59864f | ||
![]() |
4c0404c70d | ||
![]() |
573a413ee1 | ||
![]() |
f633e6ca49 | ||
![]() |
07b06d76be | ||
![]() |
856fe2da15 | ||
![]() |
f82aae65cd | ||
![]() |
3fbd11a104 | ||
![]() |
58a99f1907 | ||
![]() |
cf86dfd317 | ||
![]() |
a057b4f6d8 | ||
![]() |
62b03cfddf | ||
![]() |
18b827b979 | ||
![]() |
0a379fc514 | ||
![]() |
445c11b8d9 | ||
![]() |
8d290ad509 | ||
![]() |
b90c48b50f | ||
![]() |
d19e7db09e | ||
![]() |
9939904b02 | ||
![]() |
ca23b15f5c | ||
![]() |
ffa676f577 | ||
![]() |
6d023c4df3 | ||
![]() |
b31bd37a30 | ||
![]() |
78faee8c7c | ||
![]() |
40e2a703d0 | ||
![]() |
b01edcb9bc | ||
![]() |
f7fffc9be8 | ||
![]() |
50e8634097 | ||
![]() |
e3994e517e | ||
![]() |
2bb7785189 | ||
![]() |
90c8408111 | ||
![]() |
64786ec12a | ||
![]() |
b3c82f8886 | ||
![]() |
063259dc52 | ||
![]() |
b4c9d9c2a7 | ||
![]() |
fa2b59df4b | ||
![]() |
f41a169460 | ||
![]() |
f567083006 | ||
![]() |
a2a677e539 | ||
![]() |
9123c0b733 | ||
![]() |
788e3b31e1 | ||
![]() |
71f0ed8b74 | ||
![]() |
ac2e4e593d | ||
![]() |
edaa7d7748 | ||
![]() |
3cdf965fba | ||
![]() |
6b60d1e71f | ||
![]() |
7b7fb5acd5 | ||
![]() |
0a7d612f41 | ||
![]() |
38da76bbe0 | ||
![]() |
a13e045742 | ||
![]() |
811620c0a0 | ||
![]() |
504f5f7bdd | ||
![]() |
32bcad51b8 |
.travis.ymlAUTHORSINSTALLMakefile.amNEWSREADME.md
android
configure.acdoc
python/build
src
AudioFormat.cxxAudioFormat.hxxAudioParser.hxxDetachedSong.cxxDetachedSong.hxxIOThread.cxxIOThread.hxxIdleFlags.cxxIdleFlags.hxxInstance.hxxMain.cxxMapper.cxxMapper.hxxMixRampInfo.hxxMusicBuffer.cxxMusicBuffer.hxxMusicChunk.cxxMusicChunk.hxxMusicPipe.cxxMusicPipe.hxxPartition.hxxPermission.cxxPlaylistFile.cxxPlaylistSave.cxxReplayGainInfo.cxxReplayGainInfo.hxxReplayGainMode.cxxReplayGainMode.hxxSongFilter.cxxSongFilter.hxxStateFile.cxxStateFile.hxxTagStream.cxxls.cxxls.hxx
archive
client
command
CommandError.cxxFileCommands.cxxNeighborCommands.cxxNeighborCommands.hxxPlaylistCommands.cxxPlaylistCommands.hxxRequest.hxxStorageCommands.cxx
config
db
DatabaseLock.hxxDatabaseSong.hxxHelpers.cxxInterface.hxxLightDirectory.hxxLightSong.cxxLightSong.hxxPlaylistInfo.hxxPlaylistVector.cxxPlaylistVector.hxxRegistry.cxxRegistry.hxxSelection.cxxSelection.hxx
plugins
ProxyDatabasePlugin.cxx
simple
Directory.cxxDirectory.hxxDirectorySave.cxxSimpleDatabasePlugin.hxxSong.cxxSong.hxxSongSort.cxxSongSort.hxx
upnp
update
decoder
Bridge.cxxBridge.hxxClient.hxxDecoderBuffer.hxxDecoderControl.cxxDecoderControl.hxxDecoderList.cxxDecoderList.hxxDecoderPlugin.cxxDecoderPlugin.hxxDecoderThread.cxx
plugins
AudiofileDecoderPlugin.cxxDsdLib.cxxDsdLib.hxxFfmpegDecoderPlugin.cxxFfmpegMetaData.cxxFlacMetadata.cxxFlacMetadata.hxxGmeDecoderPlugin.cxxMadDecoderPlugin.cxxOpusDecoderPlugin.cxxOpusTags.cxxPcmDecoderPlugin.cxxSidplayDecoderPlugin.cxxSndfileDecoderPlugin.cxxVorbisDecoderPlugin.cxxWavpackDecoderPlugin.cxx
encoder
plugins
event
filter
fs
AllocatedPath.cxxAllocatedPath.hxxCharset.cxxCharset.hxxGlob.hxxPath.cxxPath.hxxPath2.cxxStandardDirectory.cxxStandardDirectory.hxxTraits.cxxTraits.hxx
io
input
AsyncInputStream.cxxAsyncInputStream.hxxInputStream.cxxInputStream.hxxProxyInputStream.cxxProxyInputStream.hxxThreadInputStream.cxxThreadInputStream.hxx
plugins
lib
curl
expat
ffmpeg
icu
nfs
upnp
mixer
neighbor
net
AllocatedSocketAddress.cxxAllocatedSocketAddress.hxxSocketAddress.cxxSocketAddress.hxxSocketError.cxxSocketError.hxxStaticSocketAddress.cxxStaticSocketAddress.hxxToString.cxxToString.hxx
output
Init.cxxInternal.cxxInternal.hxxMultipleOutputs.cxxMultipleOutputs.hxxOutputPlugin.cxxOutputPlugin.hxxOutputThread.cxxSharedPipeConsumer.cxxSharedPipeConsumer.hxxSource.cxxSource.hxxWrapper.hxx
plugins
pcm
ChannelsConverter.cxxChannelsConverter.hxxFloatConvert.hxxFormatConverter.cxxFormatConverter.hxxPcmExport.cxxPcmExport.hxxPcmFormat.cxxPcmFormat.hxxPcmUtils.hxxResampler.hxxSampleFormat.cxxSampleFormat.hxxSoxrResampler.cxxVolume.cxxVolume.hxx
player
playlist
protocol
queue
sticker
storage
CompositeStorage.cxxCompositeStorage.hxxConfigured.cxxConfigured.hxxFileInfo.hxxRegistry.cxxRegistry.hxxStorageInterface.cxxStorageInterface.hxx
plugins
system
tag
Aiff.cxxFormat.cxxFormat.hxxId3Load.cxxId3MusicBrainz.cxxId3MusicBrainz.hxxMixRamp.cxxReplayGain.cxxSet.cxxSet.hxxSettings.hxxTag.cxxTag.hxxTagBuilder.cxxTagBuilder.hxxTagId3.cxxTagString.cxxTagTable.cxxTagTable.hxxVorbisComment.cxxVorbisComment.hxx
thread
unix
util
ASCII.hxxConstBuffer.hxxFormatString.cxxHugeAllocator.cxxPeakBuffer.cxxPeakBuffer.hxxScopeExit.hxxStringAPI.hxxStringCompare.cxxStringCompare.hxxStringUtil.cxxStringUtil.hxxStringView.cxxStringView.hxxTimeParser.cxxTimeParser.hxxUTF8.cxxUTF8.hxxUriUtil.cxxUriUtil.hxxWStringAPI.hxxWStringCompare.cxxWStringCompare.hxx
test
FakeDecoderAPI.cxxFakeDecoderAPI.hxxdump_rva2.cxxread_mixer.cxxrun_output.cxxtest_byte_reverse.cxxtest_protocol.cxxtest_rewind.cxxtest_translate_song.cxx
win32
36
.travis.yml
Normal file
36
.travis.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
dist: trusty
|
||||
language: cpp
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcppunit-dev
|
||||
- libboost-dev
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j2"
|
||||
|
||||
before_install:
|
||||
# C++14
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo apt-get update -qq
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || brew update
|
||||
|
||||
install:
|
||||
# C++14
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo apt-get install -qq g++-5
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || brew install cppunit
|
||||
|
||||
script:
|
||||
- OPTIONS="--enable-test"
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || export CC=gcc-5 CXX=g++-5
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || OPTIONS="$OPTIONS --enable-osx"
|
||||
- ./autogen.sh
|
||||
- ./configure --disable-silent-rules --disable-dependency-tracking $OPTIONS
|
||||
- make
|
||||
- make check
|
1
AUTHORS
1
AUTHORS
@@ -30,3 +30,4 @@ The following people have contributed code to MPD:
|
||||
Jurgen Kramer <gtmkramer@xs4all.nl>
|
||||
Jean-Francois Dockes <jf@dockes.org>
|
||||
Yue Wang <yuleopen@gmail.com>
|
||||
Matthew Leon Grinshpun <ml@matthewleon.com>
|
||||
|
206
INSTALL
206
INSTALL
@@ -1,206 +0,0 @@
|
||||
Music Player Daemon (MPD) - INSTALL
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This document is a very small amount of documentation about what is needed to
|
||||
install MPD. If more information is desired, read the user manual:
|
||||
|
||||
http://www.musicpd.org/doc/user/
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
gcc 4.7 or later - http://gcc.gnu.org/
|
||||
clang 3.2 or later - http://clang.llvm.org/
|
||||
Any other C++11 compliant compiler should also work.
|
||||
|
||||
Boost 1.46 - http://www.boost.org/
|
||||
|
||||
|
||||
Optional Output Dependencies
|
||||
----------------------------
|
||||
|
||||
You will need at least one of these to compile MPD.
|
||||
|
||||
Most of these are available as packages on major distributions. Be sure to
|
||||
install both the library package as well as the development package.
|
||||
|
||||
AO - http://www.xiph.org/ao/
|
||||
A portable library that abstracts many audio output types as one API. Should
|
||||
be used only if there is no native plugin available or if the native plugin
|
||||
doesn't work. You will need libao.
|
||||
|
||||
ALSA - http://www.alsa-project.org/
|
||||
The Advanced Linux Sound Architecture. Recommended audio output if you use
|
||||
Linux. You will need libasound.
|
||||
|
||||
FIFO
|
||||
This is a mostly undocumented, developer plugin to transmit raw data.
|
||||
|
||||
OSS - http://www.opensound.com
|
||||
Open Sound System.
|
||||
|
||||
PulseAudio - http://www.pulseaudio.org/
|
||||
An advanced sound daemon. You will need libpulse.
|
||||
|
||||
JACK - http://www.jackaudio.org/
|
||||
A low-latency sound daemon.
|
||||
|
||||
libshout - http://www.icecast.org/
|
||||
For streaming to an Icecast or Shoutcast server.
|
||||
You also need an encoder: either libvorbisenc (ogg), or liblame (mp3).
|
||||
|
||||
OpenAL - http://kcat.strangesoft.net/openal.html
|
||||
Open Audio Library
|
||||
|
||||
|
||||
Optional Input Dependencies
|
||||
---------------------------
|
||||
|
||||
You will need at least one of these to compile MPD.
|
||||
|
||||
Most of these are available as packages on major distributions. Be sure to
|
||||
install both the library package as well as the development package.
|
||||
|
||||
MAD - http://www.underbit.com/products/mad/
|
||||
For MP3 support. You will need libmad, and optionally libid3tag if you want
|
||||
ID3 tag support.
|
||||
|
||||
libmpg123 - http://www.mpg123.de/
|
||||
Alternative for MP3 support.
|
||||
|
||||
Ogg Vorbis - http://www.xiph.org/ogg/vorbis/
|
||||
For Ogg Vorbis support. You will need libogg and libvorbis.
|
||||
|
||||
libopus - http://www.opus-codec.org/
|
||||
Opus codec support
|
||||
|
||||
FLAC - http://flac.sourceforge.net/
|
||||
For FLAC support. You will need version 1.2 or higher of libFLAC.
|
||||
|
||||
Audio File - http://www.68k.org/~michael/audiofile/
|
||||
For WAVE, AIFF, and AU support. You will need libaudiofile.
|
||||
|
||||
FAAD2 - http://www.audiocoding.com/
|
||||
For MP4/AAC support.
|
||||
|
||||
libmpcdec - http://www.musepack.net/
|
||||
For Musepack support.
|
||||
|
||||
MikMod - http://mikmod.raphnet.net/
|
||||
For MOD support. You will need libmikmod.
|
||||
|
||||
libavcodec, libavformat (ffmpeg or libav) - http://ffmpeg.mplayerhq.hu/ http://libav.org/
|
||||
Multi-codec library.
|
||||
|
||||
libsidplay2 - http://sidplay2.sourceforge.net/
|
||||
For C64 SID support.
|
||||
|
||||
libfluidsynth - http://fluidsynth.resonance.org/
|
||||
For MIDI support.
|
||||
|
||||
libwildmidi 0.2.3 - http://wildmidi.sourceforge.net/
|
||||
For MIDI support.
|
||||
|
||||
libsndfile - http://www.mega-nerd.com/libsndfile/
|
||||
WAVE, AIFF, and many others.
|
||||
|
||||
libwavpack - http://www.wavpack.com/
|
||||
For WavPack playback.
|
||||
|
||||
libadplug - http://adplug.sourceforge.net/
|
||||
For AdLib playback.
|
||||
|
||||
|
||||
Optional Miscellaneous Dependencies
|
||||
-----------------------------------
|
||||
|
||||
Avahi - http://www.avahi.org/
|
||||
For Zeroconf support.
|
||||
|
||||
libsamplerate - http://www.mega-nerd.com/SRC/
|
||||
For advanced samplerate conversions.
|
||||
|
||||
libcurl - http://curl.haxx.se/
|
||||
For playing HTTP streams.
|
||||
|
||||
libmms - https://launchpad.net/libmms
|
||||
For playing MMS streams.
|
||||
|
||||
SQLite - http://www.sqlite.org/
|
||||
For the sticker database.
|
||||
|
||||
libcdio - http://www.gnu.org/software/libcdio/
|
||||
For playing audio CDs.
|
||||
|
||||
libsystemd-daemon - http://freedesktop.org/wiki/Software/systemd/
|
||||
For systemd activation.
|
||||
|
||||
|
||||
pkg-config
|
||||
----------
|
||||
|
||||
MPD uses pkg-config to locate most external libraries. If you do not
|
||||
have pkg-config, or if your version of the library does not ship the
|
||||
".pc" file, you have to provide the library's build options in
|
||||
environment variables. These variables are documented in "./configure
|
||||
--help". Example:
|
||||
|
||||
FLAC_CFLAGS=-I/usr/include/FLAC FLAC_LIBS=-lFLAC ./configure
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Get the latest release from of MPD from <http://www.musicpd.org/>.
|
||||
|
||||
Compile
|
||||
-------
|
||||
|
||||
1) unpack the archive
|
||||
|
||||
$ tar xf mpd-x.x.x.tar.xz
|
||||
|
||||
2) change to directory created
|
||||
|
||||
$ cd mpd-x.x.x
|
||||
|
||||
3) Run configure script (this will determine what dependencies you have)
|
||||
|
||||
$ ./configure
|
||||
|
||||
4) Compile
|
||||
|
||||
$ make
|
||||
|
||||
Install (Optional)
|
||||
-------
|
||||
|
||||
(as root)
|
||||
$ make install
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
1) run mpd:
|
||||
|
||||
$ mpd <config file>
|
||||
|
||||
First default is $XDG_CONFIG_HOME/mpd/mpd.conf then ~/.mpdconf then
|
||||
~/.mpd/mpd.conf then /etc/mpd.conf. If neither of these exist a mpd
|
||||
configuration file must be specified at runtime.
|
||||
|
||||
A sample config file is included with the source of MPD, mpdconf.example.
|
||||
|
||||
The first time MPD is run it will attempt to discover all music in your
|
||||
music root, recursively. This can be affected by the symbolic link
|
||||
options specified in the example mpd.conf.
|
||||
|
||||
Using MPD
|
||||
---------
|
||||
|
||||
You can download many different interfaces for MPD at
|
||||
|
||||
http://www.musicpd.org/clients/
|
@@ -243,6 +243,7 @@ CURL_SOURCES = \
|
||||
src/lib/curl/Slist.hxx
|
||||
|
||||
UPNP_SOURCES = \
|
||||
src/lib/upnp/Compat.hxx \
|
||||
src/lib/upnp/Init.cxx src/lib/upnp/Init.hxx \
|
||||
src/lib/upnp/ClientInit.cxx src/lib/upnp/ClientInit.hxx \
|
||||
src/lib/upnp/Device.cxx src/lib/upnp/Device.hxx \
|
||||
@@ -518,6 +519,8 @@ libevent_a_SOURCES = \
|
||||
# UTF-8 library
|
||||
|
||||
libicu_a_SOURCES = \
|
||||
src/lib/icu/CaseFold.cxx src/lib/icu/CaseFold.hxx \
|
||||
src/lib/icu/Compare.cxx src/lib/icu/Compare.hxx \
|
||||
src/lib/icu/Collate.cxx src/lib/icu/Collate.hxx \
|
||||
src/lib/icu/Converter.cxx src/lib/icu/Converter.hxx
|
||||
|
||||
@@ -923,6 +926,7 @@ libtag_a_SOURCES =\
|
||||
src/tag/ReplayGain.cxx src/tag/ReplayGain.hxx \
|
||||
src/tag/MixRamp.cxx src/tag/MixRamp.hxx \
|
||||
src/tag/Generic.cxx src/tag/Generic.hxx \
|
||||
src/tag/Id3MusicBrainz.cxx src/tag/Id3MusicBrainz.hxx \
|
||||
src/tag/ApeLoader.cxx src/tag/ApeLoader.hxx \
|
||||
src/tag/ApeReplayGain.cxx src/tag/ApeReplayGain.hxx \
|
||||
src/tag/ApeTag.cxx src/tag/ApeTag.hxx
|
||||
@@ -1489,6 +1493,8 @@ liboutput_plugins_a_SOURCES += \
|
||||
src/output/plugins/OSXOutputPlugin.cxx \
|
||||
src/output/plugins/OSXOutputPlugin.hxx
|
||||
endif
|
||||
libmixer_plugins_a_SOURCES += \
|
||||
src/mixer/plugins/OSXMixerPlugin.cxx
|
||||
|
||||
if ENABLE_PULSE
|
||||
liboutput_plugins_a_SOURCES += \
|
||||
|
59
NEWS
59
NEWS
@@ -1,3 +1,62 @@
|
||||
ver 0.20.12 (2017/11/25)
|
||||
* database
|
||||
- upnp: adapt to libupnp 1.8 API changes
|
||||
* input
|
||||
- cdio_paranoia, ffmpeg, file, smbclient: reduce lock contention,
|
||||
fixing lots of xrun problems
|
||||
- curl: fix seeking
|
||||
* decoder
|
||||
- ffmpeg: fix GCC 8 warning
|
||||
- vorbis: fix Tremor support
|
||||
* player
|
||||
- log message when decoder is too slow
|
||||
* encoder
|
||||
- vorbis: default to quality 3
|
||||
* output
|
||||
- fix hanging playback with soxr resampler
|
||||
- httpd: flush encoder after tag; fixes corrupt Vorbis stream
|
||||
|
||||
ver 0.20.11 (2017/10/18)
|
||||
* storage
|
||||
- curl: support Content-Type application/xml
|
||||
* decoder
|
||||
- ffmpeg: more reliable song duration
|
||||
- gme: fix track numbering
|
||||
* improve random song order when switching songs manually
|
||||
* fix case insensitive search without libicu
|
||||
* fix Unicode file names in playlists on Windows
|
||||
* fix endless loop when accessing malformed file names in ZIP files
|
||||
|
||||
ver 0.20.10 (2017/08/24)
|
||||
* decoder
|
||||
- ffmpeg: support MusicBrainz ID3v2 tags
|
||||
* tags
|
||||
- aiff: fix FORM chunk size endianess (is big-endian)
|
||||
* mixer
|
||||
- osx: add a mixer for OSX.
|
||||
* fix crash when resuming playback before decoder is ready
|
||||
* fix crash on Windows
|
||||
|
||||
ver 0.20.9 (2017/06/04)
|
||||
* decoder
|
||||
- ffmpeg: support *.adx
|
||||
* fix byte order detection on FreeBSD/aarch64
|
||||
* fix more random crashes when compiled with clang
|
||||
|
||||
ver 0.20.8 (2017/05/19)
|
||||
* output
|
||||
- osx: fix build failure due to missing "noexcept"
|
||||
* playlist
|
||||
- m3u: support MIME type `audio/mpegurl`
|
||||
* fix build failure with GCC 4.x
|
||||
|
||||
ver 0.20.7 (2017/05/15)
|
||||
* database
|
||||
- simple: fix false positive directory loop detection with NFS
|
||||
* enforce a reasonable minimum audio_buffer_size setting
|
||||
* cap buffer_before_play at 80% to prevent deadlock
|
||||
* fix random crashes when compiled with clang
|
||||
|
||||
ver 0.20.6 (2017/03/10)
|
||||
* input
|
||||
- curl: fix headers after HTTP redirect to Shoutcast server
|
||||
|
@@ -7,14 +7,15 @@ server's audio device. The daemon stores info about all available music,
|
||||
and this info can be easily searched and retrieved. Player control, info
|
||||
retrieval, and playlist management can all be managed remotely.
|
||||
|
||||
For basic installation information see the INSTALL file.
|
||||
For basic installation instructions
|
||||
[read the manual](https://www.musicpd.org/doc/user/install.html).
|
||||
|
||||
# Users
|
||||
|
||||
- [Manual](http://www.musicpd.org/doc/user/)
|
||||
- [Forum](http://forum.musicpd.org/)
|
||||
- [IRC](irc://chat.freenode.net/#mpd)
|
||||
- [Bug tracker](http://bugs.musicpd.org/)
|
||||
- [Bug tracker](https://github.com/MusicPlayerDaemon/MPD/issues/)
|
||||
|
||||
# Developers
|
||||
|
||||
|
@@ -154,5 +154,9 @@ configure = [
|
||||
|
||||
] + configure_args
|
||||
|
||||
from build.cmdline import concatenate_cmdline_variables
|
||||
configure = concatenate_cmdline_variables(configure,
|
||||
set(('CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'LIBS')))
|
||||
|
||||
subprocess.check_call(configure, env=toolchain.env)
|
||||
subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'], env=toolchain.env)
|
||||
|
10
configure.ac
10
configure.ac
@@ -1,10 +1,10 @@
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT(mpd, 0.20.6, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.20.12, musicpd-dev-team@lists.sourceforge.net)
|
||||
|
||||
VERSION_MAJOR=0
|
||||
VERSION_MINOR=20
|
||||
VERSION_REVISION=6
|
||||
VERSION_REVISION=12
|
||||
VERSION_EXTRA=0
|
||||
|
||||
AC_CONFIG_SRCDIR([src/Main.cxx])
|
||||
@@ -241,6 +241,7 @@ AC_CHECK_FUNCS(getpwnam_r getpwuid_r)
|
||||
AC_CHECK_FUNCS(initgroups)
|
||||
AC_CHECK_FUNCS(fnmatch)
|
||||
AC_CHECK_FUNCS(strndup)
|
||||
AC_CHECK_FUNCS(strcasestr)
|
||||
|
||||
if test x$host_is_linux = xyes; then
|
||||
MPD_OPTIONAL_FUNC(eventfd, eventfd, USE_EVENTFD)
|
||||
@@ -1384,6 +1385,11 @@ then
|
||||
AX_APPEND_COMPILE_FLAGS([-Wcast-qual])
|
||||
AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
|
||||
AX_APPEND_COMPILE_FLAGS([-Wsign-compare])
|
||||
|
||||
dnl This GCC8 warning for C++17 ABI compatibility is of no
|
||||
dnl interest for us, because we're not a shared library.
|
||||
AX_APPEND_COMPILE_FLAGS([-Wno-noexcept-type])
|
||||
|
||||
AC_LANG_POP
|
||||
fi
|
||||
|
||||
|
@@ -97,20 +97,20 @@ Foo(const char *abc, int xyz)
|
||||
|
||||
<para>
|
||||
MPD sources are managed in a git repository on <ulink
|
||||
url="http://git.musicpd.org/">git.musicpd.org</ulink>.
|
||||
url="https://github.com/MusicPlayerDaemon/">GitHub</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Always write your code against the latest git:
|
||||
</para>
|
||||
|
||||
<programlisting>git clone git://git.musicpd.org/master/mpd.git</programlisting>
|
||||
<programlisting>git clone git://github.com/MusicPlayerDaemon/MPD</programlisting>
|
||||
|
||||
<para>
|
||||
If you already have a clone, update it:
|
||||
</para>
|
||||
|
||||
<programlisting>git pull --rebase git://git.musicpd.org/master/mpd.git master</programlisting>
|
||||
<programlisting>git pull --rebase git://github.com/MusicPlayerDaemon/MPD master</programlisting>
|
||||
|
||||
<para>
|
||||
You can do without "--rebase", but we recommend that you rebase
|
||||
@@ -188,17 +188,7 @@ Foo(const char *abc, int xyz)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<command>git pull</command> requests are preferred. Regular
|
||||
contributors can get <ulink
|
||||
url="http://git.musicpd.org/account-policy.html">an account on
|
||||
git.musicpd.org</ulink>, but any public git repository will do.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There is <ulink url="https://github.com/MaxKellermann/MPD">a
|
||||
mirror of the <application>MPD</application> git repository on
|
||||
GitHub</ulink>, and you can use that as well to submit pull
|
||||
requests.
|
||||
<command>git pull</command> requests are preferred.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
|
@@ -48,7 +48,7 @@ mpd.conf(5), mpc(1)
|
||||
.SH BUGS
|
||||
If you find a bug, please report it at
|
||||
.br
|
||||
<\fBhttp://bugs.musicpd.org/bug_report_page.php\fP>.
|
||||
<\fBhttps://github.com/MusicPlayerDaemon/MPD/issues/\fP>.
|
||||
.SH AUTHORS
|
||||
Max Kellermann <max.kellermann@gmail.com>
|
||||
|
||||
|
@@ -403,6 +403,15 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Change events accumulate, even while the connection is
|
||||
not in "idle" mode; no events gets lost while the client
|
||||
is doing something else with the connection. If an
|
||||
event had already occurred since the last call, the new
|
||||
<command>idle</command> command will return immediately.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While a client is waiting for <command>idle</command>
|
||||
results, the server disables timeouts, allowing a client
|
||||
@@ -436,7 +445,9 @@
|
||||
<listitem>
|
||||
<para>
|
||||
<varname>volume</varname>:
|
||||
<returnvalue>0-100</returnvalue>
|
||||
<returnvalue>0-100</returnvalue> or
|
||||
<returnvalue>-1</returnvalue> if the volume cannot
|
||||
be determined
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
251
doc/user.xml
251
doc/user.xml
@@ -80,13 +80,40 @@
|
||||
cd mpd-version</programlisting>
|
||||
|
||||
<para>
|
||||
Make sure that all the required libraries and build tools are
|
||||
installed. The <filename>INSTALL</filename> file has a list.
|
||||
In any case, you need:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
a C++14 compiler (e.g. <ulink
|
||||
url="http://gcc.gnu.org/">gcc 4.9</ulink> or <ulink
|
||||
url="http://clang.llvm.org/">clang 3.9</ulink>)
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.boost.org/">Boost 1.46</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="https://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Each plugin usually needs a codec library, which you also need
|
||||
to install. Check the plugin reference for details about
|
||||
required libraries.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, the following installs a fairly complete list of
|
||||
build dependencies on Debian Wheezy:
|
||||
build dependencies on Debian Jessie:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
@@ -98,19 +125,20 @@ apt-get install g++ \
|
||||
libmpcdec-dev libwavpack-dev libwildmidi-dev \
|
||||
libsidplay2-dev libsidutils-dev libresid-builder-dev \
|
||||
libavcodec-dev libavformat-dev \
|
||||
libmp3lame-dev \
|
||||
libmp3lame-dev libtwolame-dev libshine-dev \
|
||||
libsamplerate0-dev libsoxr-dev \
|
||||
libbz2-dev libcdio-paranoia-dev libiso9660-dev libmms-dev \
|
||||
libzzip-dev \
|
||||
libcurl4-gnutls-dev libyajl-dev libexpat-dev \
|
||||
libasound2-dev libao-dev libjack-jackd2-dev libopenal-dev \
|
||||
libpulse-dev libroar-dev libshout3-dev \
|
||||
libsndio-dev \
|
||||
libmpdclient-dev \
|
||||
libnfs-dev libsmbclient-dev \
|
||||
libupnp-dev \
|
||||
libavahi-client-dev \
|
||||
libsqlite3-dev \
|
||||
libsystemd-daemon-dev libwrap0-dev \
|
||||
libsystemd-dev libwrap0-dev \
|
||||
libcppunit-dev xmlto \
|
||||
libboost-dev \
|
||||
libicu-dev
|
||||
@@ -1035,6 +1063,40 @@ systemctl start mpd.socket</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="stickers">
|
||||
<title>The Sticker Database</title>
|
||||
|
||||
<para>
|
||||
"Stickers" are pieces of information attached to songs.
|
||||
Some clients use them to store ratings and other volatile
|
||||
data. This feature requires <ulink
|
||||
url="http://www.sqlite.org/">SQLite</ulink>, compile-time
|
||||
configure option <parameter>--enable-sqlite</parameter>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>sticker_file</varname>
|
||||
<parameter>PATH</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
The location of the sticker database.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Resource Limitations</title>
|
||||
|
||||
@@ -1165,6 +1227,55 @@ systemctl start mpd.socket</programlisting>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="zeroconf">
|
||||
<title>Zeroconf</title>
|
||||
|
||||
<para>
|
||||
If Zeroconf support (<ulink
|
||||
url="http://avahi.org/">Avahi</ulink> or Apple's Bonjour)
|
||||
was enabled at compile time with
|
||||
<parameter>--with-zeroconf=...</parameter>, MPD can announce
|
||||
its presence on the network. The following settings control
|
||||
this feature:
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>zeroconf_enabled</varname>
|
||||
<parameter>yes|no</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
Enables or disables this feature. Default is
|
||||
<parameter>yes</parameter>.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>zeroconf_name</varname>
|
||||
<parameter>NAME</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
The service name to publish via Zeroconf. The
|
||||
default is "<parameter>Music Player</parameter>".
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -1747,7 +1858,7 @@ buffer_size: 16384</programlisting>
|
||||
<para>
|
||||
If you believe you found a bug in
|
||||
<application>MPD</application>, report it on <ulink
|
||||
url="https://bugs.musicpd.org/my_view_page.php">the bug
|
||||
url="https://github.com/MusicPlayerDaemon/MPD/issues/">the bug
|
||||
tracker</ulink>.
|
||||
</para>
|
||||
|
||||
@@ -2078,7 +2189,9 @@ run</programlisting>
|
||||
<title><varname>cdio_paranoia</varname></title>
|
||||
|
||||
<para>
|
||||
Plays audio CDs. The URI has the form:
|
||||
Plays audio CDs using <ulink
|
||||
url="http://www.gnu.org/software/libcdio/"><filename>libcdio</filename></ulink>.
|
||||
The URI has the form:
|
||||
"<filename>cdda://[DEVICE][/TRACK]</filename>". The
|
||||
simplest form <filename>cdda://</filename> plays the whole
|
||||
disc in the default drive.
|
||||
@@ -2114,7 +2227,8 @@ run</programlisting>
|
||||
<title><varname>curl</varname></title>
|
||||
|
||||
<para>
|
||||
Opens remote files or streams over HTTP.
|
||||
Opens remote files or streams over HTTP using <ulink
|
||||
url="http://curl.haxx.se/"><filename>libcurl</filename></ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -2207,7 +2321,8 @@ run</programlisting>
|
||||
<title><varname>mms</varname></title>
|
||||
|
||||
<para>
|
||||
Plays streams with the MMS protocol.
|
||||
Plays streams with the MMS protocol using <ulink
|
||||
url="https://launchpad.net/libmms"><filename>libmms</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2263,7 +2378,8 @@ run</programlisting>
|
||||
<title><varname>adplug</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes AdLib files.
|
||||
Decodes AdLib files using <ulink
|
||||
url="http://adplug.sourceforge.net/">libadplug</ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2294,8 +2410,8 @@ run</programlisting>
|
||||
<title><varname>audiofile</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes WAV and AIFF files using
|
||||
<filename>libaudiofile</filename>.
|
||||
Decodes WAV and AIFF files using <ulink
|
||||
url="http://audiofile.68k.org/"><filename>libaudiofile</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2303,7 +2419,8 @@ run</programlisting>
|
||||
<title><varname>faad</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes AAC files using <filename>libfaad</filename>.
|
||||
Decodes AAC files using <ulink
|
||||
url="http://www.audiocoding.com/"><filename>libfaad</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2311,8 +2428,8 @@ run</programlisting>
|
||||
<title><varname>ffmpeg</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes various codecs using
|
||||
<application>FFmpeg</application>.
|
||||
Decodes various codecs using <ulink
|
||||
url="https://ffmpeg.org/"><application>FFmpeg</application></ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2363,7 +2480,7 @@ run</programlisting>
|
||||
|
||||
<para>
|
||||
Decodes FLAC files using
|
||||
<application>libFLAC</application>.
|
||||
<ulink url="https://xiph.org/flac/"><application>libFLAC</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2483,7 +2600,8 @@ run</programlisting>
|
||||
<title><varname>mad</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes MP3 files using <application>libmad</application>.
|
||||
Decodes MP3 files using <ulink
|
||||
url="http://www.underbit.com/products/mad/"><application>libmad</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2563,8 +2681,8 @@ run</programlisting>
|
||||
<title><varname>mpcdec</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Musepack files using
|
||||
<application>libmpcdec</application>.
|
||||
Decodes Musepack files using <ulink
|
||||
url="http://www.musepack.net/"><application>libmpcdec</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2572,7 +2690,17 @@ run</programlisting>
|
||||
<title><varname>mpg123</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes MP3 files using <application>libmpg123</application>.
|
||||
Decodes MP3 files using <ulink
|
||||
url="http://www.mpg123.de/"><application>libmpg123</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="opus_decoder">
|
||||
<title><varname>opus</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Opus files using <ulink
|
||||
url="http://www.opus-codec.org/"><application>libopus</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2592,8 +2720,8 @@ run</programlisting>
|
||||
<title><varname>sidplay</varname></title>
|
||||
|
||||
<para>
|
||||
C64 SID decoder based on
|
||||
<application>libsidplay</application>.
|
||||
C64 SID decoder based on <ulink
|
||||
url="http://sidplay2.sourceforge.net/"><application>libsidplay</application></ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2649,8 +2777,8 @@ run</programlisting>
|
||||
<title><varname>sndfile</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes WAV and AIFF files using
|
||||
<filename>libsndfile</filename>.
|
||||
Decodes WAV and AIFF files using <ulink
|
||||
url="http://www.mega-nerd.com/libsndfile/"><filename>libsndfile</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2658,8 +2786,8 @@ run</programlisting>
|
||||
<title><varname>vorbis</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Ogg-Vorbis files using
|
||||
<application>libvorbis</application>.
|
||||
Decodes Ogg-Vorbis files using <ulink
|
||||
url="http://www.xiph.org/ogg/vorbis/"><application>libvorbis</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2668,7 +2796,7 @@ run</programlisting>
|
||||
|
||||
<para>
|
||||
Decodes WavPack files using
|
||||
<application>libwavpack</application>.
|
||||
<ulink url="http://www.wavpack.com/"><application>libwavpack</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2863,6 +2991,60 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="opus_encoder">
|
||||
<title><varname>opus</varname></title>
|
||||
|
||||
<para>
|
||||
Encodes into <ulink
|
||||
url="http://www.opus-codec.org/">Ogg Opus</ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>bitrate</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the data rate in bit per second. The special
|
||||
value "auto" lets <application>libopus</application>
|
||||
choose a rate (which is the default), and "max" uses
|
||||
the maximum possible data rate.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>complexity</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the <ulink
|
||||
url="https://wiki.xiph.org/OpusFAQ#What_is_the_complexity_of_Opus.3F">Opus
|
||||
complexity</ulink>.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>signal</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the Opus signal type. Valid values are "auto"
|
||||
(the default), "voice" and "music".
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="vorbis_encoder">
|
||||
<title><varname>vorbis</varname></title>
|
||||
|
||||
@@ -2886,8 +3068,8 @@ run</programlisting>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the quality for VBR. -1 is the lowest quality,
|
||||
10 is the highest quality. Cannot be used with
|
||||
<varname>bitrate</varname>.
|
||||
10 is the highest quality. Defaults to 3. Cannot
|
||||
be used with <varname>bitrate</varname>.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -3492,7 +3674,7 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section id="jack_output">
|
||||
<title><varname>jack</varname></title>
|
||||
|
||||
<para>
|
||||
@@ -3772,7 +3954,7 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section id="openal_output">
|
||||
<title><varname>openal</varname></title>
|
||||
|
||||
<para>
|
||||
@@ -3923,7 +4105,7 @@ run</programlisting>
|
||||
<para>
|
||||
The <varname>pulse</varname> plugin connects to a <ulink
|
||||
url="http://www.freedesktop.org/wiki/Software/PulseAudio/"><application>PulseAudio</application></ulink>
|
||||
server.
|
||||
server. Requires <filename>libpulse</filename>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -4080,7 +4262,7 @@ run</programlisting>
|
||||
(logical "and") can be used to select portions of
|
||||
the format string depending on the existing tag
|
||||
values. Example:
|
||||
<parameter>~/.mpd/recorder/[%title|%name%].ogg</parameter>
|
||||
<parameter>~/.mpd/recorder/[%title%|%name%].ogg</parameter>
|
||||
(use the "name" tag if no title exists)
|
||||
</para>
|
||||
</entry>
|
||||
@@ -4111,7 +4293,8 @@ run</programlisting>
|
||||
url="http://www.shoutcast.com/"><application>ShoutCast</application></ulink>
|
||||
or <ulink
|
||||
url="http://icecast.org/"><application>IceCast</application></ulink>
|
||||
server. It forwards tags to this server.
|
||||
server using <filename>libshout</filename>. It forwards
|
||||
tags to this server.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
29
python/build/cmdline.py
Normal file
29
python/build/cmdline.py
Normal file
@@ -0,0 +1,29 @@
|
||||
def concatenate_cmdline_variables(src, names):
|
||||
"""Find duplicate variable declarations on the given source list, and
|
||||
concatenate the values of those in the 'names' list."""
|
||||
|
||||
# the result list being constructed
|
||||
dest = []
|
||||
|
||||
# a map of variable name to destination list index
|
||||
positions = {}
|
||||
|
||||
for item in src:
|
||||
i = item.find('=')
|
||||
if i > 0:
|
||||
# it's a variable
|
||||
name = item[:i]
|
||||
if name in names:
|
||||
# it's a known variable
|
||||
if name in positions:
|
||||
# already specified: concatenate instead of
|
||||
# appending it
|
||||
dest[positions[name]] += ' ' + item[i + 1:]
|
||||
continue
|
||||
else:
|
||||
# not yet seen: append it and remember the list
|
||||
# index
|
||||
positions[name] = len(dest)
|
||||
dest.append(item)
|
||||
|
||||
return dest
|
@@ -19,8 +19,8 @@ libvorbis = AutotoolsProject(
|
||||
)
|
||||
|
||||
opus = AutotoolsProject(
|
||||
'http://downloads.xiph.org/releases/opus/opus-1.1.4.tar.gz',
|
||||
'9122b6b380081dd2665189f97bfd777f04f92dc3ab6698eea1dbb27ad59d8692',
|
||||
'https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz',
|
||||
'cfafd339ccd9c5ef8d6ab15d7e1a412c054bf4cb4ecbbbcc78c12ef2def70732',
|
||||
'lib/libopus.a',
|
||||
['--disable-shared', '--enable-static'],
|
||||
)
|
||||
@@ -36,8 +36,8 @@ flac = AutotoolsProject(
|
||||
)
|
||||
|
||||
zlib = ZlibProject(
|
||||
'http://zlib.net/zlib-1.2.8.tar.xz',
|
||||
'28f1205d8dd2001f26fec1e8c2cebe37',
|
||||
'http://zlib.net/zlib-1.2.11.tar.xz',
|
||||
'4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066',
|
||||
'lib/libz.a',
|
||||
)
|
||||
|
||||
@@ -57,9 +57,20 @@ libmad = AutotoolsProject(
|
||||
autogen=True,
|
||||
)
|
||||
|
||||
liblame = AutotoolsProject(
|
||||
'http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz',
|
||||
'24346b4158e4af3bd9f2e194bb23eb473c75fb7377011523353196b19b9a23ff',
|
||||
'lib/libmp3lame.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
'--disable-gtktest', '--disable-analyzer-hooks',
|
||||
'--disable-decoder', '--disable-frontend',
|
||||
],
|
||||
)
|
||||
|
||||
ffmpeg = FfmpegProject(
|
||||
'http://ffmpeg.org/releases/ffmpeg-3.2.4.tar.xz',
|
||||
'6e38ff14f080c98b58cf5967573501b8cb586e3a173b591f3807d8f0660daf7a',
|
||||
'http://ffmpeg.org/releases/ffmpeg-3.3.3.tar.xz',
|
||||
'd2a9002cdc6b533b59728827186c044ad02ba64841f1b7cd6c21779875453a1e',
|
||||
'lib/libavcodec.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
@@ -82,8 +93,8 @@ ffmpeg = FfmpegProject(
|
||||
)
|
||||
|
||||
curl = AutotoolsProject(
|
||||
'http://curl.haxx.se/download/curl-7.52.1.tar.lzma',
|
||||
'44286d4b825936e2430fc44ad730ce899afb736a5d328cbb8b5d42462f3f2365',
|
||||
'http://curl.haxx.se/download/curl-7.55.1.tar.xz',
|
||||
'3eafca6e84ecb4af5f35795dee84e643d5428287e88c041122bb8dac18676bb7',
|
||||
'lib/libcurl.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
@@ -103,7 +114,7 @@ curl = AutotoolsProject(
|
||||
)
|
||||
|
||||
boost = BoostProject(
|
||||
'http://downloads.sourceforge.net/project/boost/boost/1.63.0/boost_1_63_0.tar.bz2',
|
||||
'beae2529f759f6b3bf3f4969a19c2e9d6f0c503edcb2de4a61d1428519fcb3b0',
|
||||
'http://downloads.sourceforge.net/project/boost/boost/1.65.0/boost_1_65_0.tar.bz2',
|
||||
'ea26712742e2fb079c2a566a31f3266973b76e38222b9f88b387e3c8b2f9902c',
|
||||
'include/boost/version.hpp',
|
||||
)
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
AudioFormat::ApplyMask(AudioFormat mask)
|
||||
AudioFormat::ApplyMask(AudioFormat mask) noexcept
|
||||
{
|
||||
assert(IsValid());
|
||||
assert(mask.IsMaskValid());
|
||||
@@ -42,7 +42,7 @@ AudioFormat::ApplyMask(AudioFormat mask)
|
||||
}
|
||||
|
||||
StringBuffer<24>
|
||||
ToString(const AudioFormat af)
|
||||
ToString(const AudioFormat af) noexcept
|
||||
{
|
||||
StringBuffer<24> buffer;
|
||||
|
||||
|
@@ -124,10 +124,10 @@ struct AudioFormat {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void ApplyMask(AudioFormat mask);
|
||||
void ApplyMask(AudioFormat mask) noexcept;
|
||||
|
||||
gcc_pure
|
||||
AudioFormat WithMask(AudioFormat mask) const {
|
||||
AudioFormat WithMask(AudioFormat mask) const noexcept {
|
||||
AudioFormat result = *this;
|
||||
result.ApplyMask(mask);
|
||||
return result;
|
||||
@@ -223,6 +223,6 @@ AudioFormat::GetTimeToSize() const
|
||||
*/
|
||||
gcc_const
|
||||
StringBuffer<24>
|
||||
ToString(AudioFormat af);
|
||||
ToString(AudioFormat af) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -25,8 +25,6 @@
|
||||
#ifndef MPD_AUDIO_PARSER_HXX
|
||||
#define MPD_AUDIO_PARSER_HXX
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
struct AudioFormat;
|
||||
|
||||
/**
|
||||
@@ -38,7 +36,6 @@ struct AudioFormat;
|
||||
* @param src the input string
|
||||
* @param mask if true, then "*" is allowed for any number of items
|
||||
*/
|
||||
gcc_pure
|
||||
AudioFormat
|
||||
ParseAudioFormat(const char *src, bool mask);
|
||||
|
||||
|
@@ -37,19 +37,19 @@ DetachedSong::~DetachedSong()
|
||||
}
|
||||
|
||||
bool
|
||||
DetachedSong::IsRemote() const
|
||||
DetachedSong::IsRemote() const noexcept
|
||||
{
|
||||
return uri_has_scheme(GetRealURI());
|
||||
}
|
||||
|
||||
bool
|
||||
DetachedSong::IsAbsoluteFile() const
|
||||
DetachedSong::IsAbsoluteFile() const noexcept
|
||||
{
|
||||
return PathTraitsUTF8::IsAbsolute(GetRealURI());
|
||||
}
|
||||
|
||||
bool
|
||||
DetachedSong::IsInDatabase() const
|
||||
DetachedSong::IsInDatabase() const noexcept
|
||||
{
|
||||
/* here, we use GetURI() and not GetRealURI() because
|
||||
GetRealURI() is never relative */
|
||||
@@ -59,7 +59,7 @@ DetachedSong::IsInDatabase() const
|
||||
}
|
||||
|
||||
SignedSongTime
|
||||
DetachedSong::GetDuration() const
|
||||
DetachedSong::GetDuration() const noexcept
|
||||
{
|
||||
SongTime a = start_time, b = end_time;
|
||||
if (!b.IsPositive()) {
|
||||
|
@@ -100,7 +100,7 @@ public:
|
||||
~DetachedSong();
|
||||
|
||||
gcc_pure
|
||||
const char *GetURI() const {
|
||||
const char *GetURI() const noexcept {
|
||||
return uri.c_str();
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
* displayed URI?
|
||||
*/
|
||||
gcc_pure
|
||||
bool HasRealURI() const {
|
||||
bool HasRealURI() const noexcept {
|
||||
return !real_uri.empty();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
* GetURI().
|
||||
*/
|
||||
gcc_pure
|
||||
const char *GetRealURI() const {
|
||||
const char *GetRealURI() const noexcept {
|
||||
return (HasRealURI() ? real_uri : uri).c_str();
|
||||
}
|
||||
|
||||
@@ -137,36 +137,36 @@ public:
|
||||
* song.
|
||||
*/
|
||||
gcc_pure
|
||||
bool IsSame(const DetachedSong &other) const {
|
||||
bool IsSame(const DetachedSong &other) const noexcept {
|
||||
return uri == other.uri &&
|
||||
start_time == other.start_time &&
|
||||
end_time == other.end_time;
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
bool IsURI(const char *other_uri) const {
|
||||
bool IsURI(const char *other_uri) const noexcept {
|
||||
return uri == other_uri;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsRemote() const;
|
||||
bool IsRemote() const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool IsFile() const {
|
||||
bool IsFile() const noexcept {
|
||||
return !IsRemote();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsAbsoluteFile() const;
|
||||
bool IsAbsoluteFile() const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool IsInDatabase() const;
|
||||
bool IsInDatabase() const noexcept;
|
||||
|
||||
const Tag &GetTag() const {
|
||||
const Tag &GetTag() const noexcept {
|
||||
return tag;
|
||||
}
|
||||
|
||||
Tag &WritableTag() {
|
||||
Tag &WritableTag() noexcept {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SignedSongTime GetDuration() const;
|
||||
SignedSongTime GetDuration() const noexcept;
|
||||
|
||||
/**
|
||||
* Update the #tag and #mtime.
|
||||
|
@@ -96,7 +96,7 @@ io_thread_deinit(void)
|
||||
}
|
||||
|
||||
EventLoop &
|
||||
io_thread_get()
|
||||
io_thread_get() noexcept
|
||||
{
|
||||
assert(io.loop != nullptr);
|
||||
|
||||
@@ -104,7 +104,7 @@ io_thread_get()
|
||||
}
|
||||
|
||||
bool
|
||||
io_thread_inside(void)
|
||||
io_thread_inside() noexcept
|
||||
{
|
||||
return io.thread.IsInside();
|
||||
}
|
||||
|
@@ -51,13 +51,13 @@ io_thread_deinit();
|
||||
|
||||
gcc_const
|
||||
EventLoop &
|
||||
io_thread_get();
|
||||
io_thread_get() noexcept;
|
||||
|
||||
/**
|
||||
* Is the current thread the I/O thread?
|
||||
*/
|
||||
gcc_pure
|
||||
bool
|
||||
io_thread_inside();
|
||||
io_thread_inside() noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -46,13 +46,13 @@ static const char *const idle_names[] = {
|
||||
};
|
||||
|
||||
const char*const*
|
||||
idle_get_names(void)
|
||||
idle_get_names() noexcept
|
||||
{
|
||||
return idle_names;
|
||||
}
|
||||
|
||||
unsigned
|
||||
idle_parse_name(const char *name)
|
||||
idle_parse_name(const char *name) noexcept
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
|
@@ -70,8 +70,9 @@ static constexpr unsigned IDLE_MOUNT = 0x1000;
|
||||
/**
|
||||
* Get idle names
|
||||
*/
|
||||
gcc_const
|
||||
const char*const*
|
||||
idle_get_names();
|
||||
idle_get_names() noexcept;
|
||||
|
||||
/**
|
||||
* Parse an idle name and return its mask. Returns 0 if the given
|
||||
@@ -79,6 +80,6 @@ idle_get_names();
|
||||
*/
|
||||
gcc_nonnull_all gcc_pure
|
||||
unsigned
|
||||
idle_parse_name(const char *name);
|
||||
idle_parse_name(const char *name) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -117,7 +117,6 @@ struct Instance final
|
||||
* DatabaseError if this MPD configuration has no database (no
|
||||
* music_directory was configured).
|
||||
*/
|
||||
gcc_pure
|
||||
const Database &GetDatabaseOrThrow() const;
|
||||
#endif
|
||||
|
||||
|
41
src/Main.cxx
41
src/Main.cxx
@@ -117,7 +117,21 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
static constexpr unsigned DEFAULT_BUFFER_SIZE = 4096;
|
||||
static constexpr size_t KILOBYTE = 1024;
|
||||
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
|
||||
|
||||
static constexpr size_t DEFAULT_BUFFER_SIZE = 4 * MEGABYTE;
|
||||
|
||||
static
|
||||
#if GCC_OLDER_THAN(5,0)
|
||||
/* gcc 4.x has no "constexpr" for std::max() */
|
||||
const
|
||||
#else
|
||||
constexpr
|
||||
#endif
|
||||
size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
|
||||
64 * KILOBYTE);
|
||||
|
||||
static constexpr unsigned DEFAULT_BUFFER_BEFORE_PLAY = 10;
|
||||
|
||||
#ifdef ANDROID
|
||||
@@ -130,7 +144,6 @@ struct Config {
|
||||
ReplayGainConfig replay_gain;
|
||||
};
|
||||
|
||||
gcc_const
|
||||
static Config
|
||||
LoadConfig()
|
||||
{
|
||||
@@ -307,12 +320,17 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
|
||||
FormatFatalError("buffer size \"%s\" is not a "
|
||||
"positive integer, line %i",
|
||||
param->value.c_str(), param->line);
|
||||
buffer_size = tmp;
|
||||
buffer_size = tmp * KILOBYTE;
|
||||
|
||||
if (buffer_size < MIN_BUFFER_SIZE) {
|
||||
FormatWarning(config_domain, "buffer size %lu is too small, using %lu bytes instead",
|
||||
(unsigned long)buffer_size,
|
||||
(unsigned long)MIN_BUFFER_SIZE);
|
||||
buffer_size = MIN_BUFFER_SIZE;
|
||||
}
|
||||
} else
|
||||
buffer_size = DEFAULT_BUFFER_SIZE;
|
||||
|
||||
buffer_size *= 1024;
|
||||
|
||||
const unsigned buffered_chunks = buffer_size / CHUNK_SIZE;
|
||||
|
||||
if (buffered_chunks >= 1 << 15)
|
||||
@@ -330,6 +348,19 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
|
||||
"than 100 percent, line %i",
|
||||
param->value.c_str(), param->line);
|
||||
}
|
||||
|
||||
if (perc > 80) {
|
||||
/* this upper limit should avoid deadlocks
|
||||
which can occur because the DecoderThread
|
||||
cannot ever fill the music buffer to
|
||||
exactly 100%; a few chunks always need to
|
||||
be available to generate silence in
|
||||
Player::SendSilence() */
|
||||
FormatError(config_domain,
|
||||
"buffer_before_play is too large (%f%%), capping at 80%%; please fix your configuration",
|
||||
perc);
|
||||
perc = 80;
|
||||
}
|
||||
} else
|
||||
perc = DEFAULT_BUFFER_BEFORE_PLAY;
|
||||
|
||||
|
@@ -59,14 +59,14 @@ mapper_init(AllocatedPath &&_playlist_dir)
|
||||
}
|
||||
|
||||
void
|
||||
mapper_finish()
|
||||
mapper_finish() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
|
||||
AllocatedPath
|
||||
map_uri_fs(const char *uri)
|
||||
map_uri_fs(const char *uri) noexcept
|
||||
{
|
||||
assert(uri != nullptr);
|
||||
assert(*uri != '/');
|
||||
@@ -86,7 +86,7 @@ map_uri_fs(const char *uri)
|
||||
}
|
||||
|
||||
std::string
|
||||
map_fs_to_utf8(Path path_fs)
|
||||
map_fs_to_utf8(Path path_fs) noexcept
|
||||
{
|
||||
if (path_fs.IsAbsolute()) {
|
||||
if (instance->storage == nullptr)
|
||||
@@ -109,13 +109,13 @@ map_fs_to_utf8(Path path_fs)
|
||||
#endif
|
||||
|
||||
const AllocatedPath &
|
||||
map_spl_path()
|
||||
map_spl_path() noexcept
|
||||
{
|
||||
return playlist_dir_fs;
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
map_spl_utf8_to_fs(const char *name)
|
||||
map_spl_utf8_to_fs(const char *name) noexcept
|
||||
{
|
||||
if (playlist_dir_fs.IsNull())
|
||||
return AllocatedPath::Null();
|
||||
|
@@ -37,7 +37,7 @@ void
|
||||
mapper_init(AllocatedPath &&playlist_dir);
|
||||
|
||||
void
|
||||
mapper_finish();
|
||||
mapper_finish() noexcept;
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
|
||||
@@ -48,7 +48,7 @@ mapper_finish();
|
||||
*/
|
||||
gcc_pure
|
||||
AllocatedPath
|
||||
map_uri_fs(const char *uri);
|
||||
map_uri_fs(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Maps a file system path (relative to the music directory or
|
||||
@@ -60,7 +60,7 @@ map_uri_fs(const char *uri);
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
map_fs_to_utf8(Path path_fs);
|
||||
map_fs_to_utf8(Path path_fs) noexcept;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,7 @@ map_fs_to_utf8(Path path_fs);
|
||||
*/
|
||||
gcc_const
|
||||
const AllocatedPath &
|
||||
map_spl_path();
|
||||
map_spl_path() noexcept;
|
||||
|
||||
/**
|
||||
* Maps a playlist name (without the ".m3u" suffix) to a file system
|
||||
@@ -79,6 +79,6 @@ map_spl_path();
|
||||
*/
|
||||
gcc_pure
|
||||
AllocatedPath
|
||||
map_spl_utf8_to_fs(const char *name);
|
||||
map_spl_utf8_to_fs(const char *name) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -31,45 +31,45 @@ class MixRampInfo {
|
||||
public:
|
||||
MixRampInfo() = default;
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
start.clear();
|
||||
end.clear();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsDefined() const {
|
||||
bool IsDefined() const noexcept {
|
||||
return !start.empty() || !end.empty();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetStart() const {
|
||||
const char *GetStart() const noexcept {
|
||||
return start.empty() ? nullptr : start.c_str();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetEnd() const {
|
||||
const char *GetEnd() const noexcept {
|
||||
return end.empty() ? nullptr : end.c_str();
|
||||
}
|
||||
|
||||
void SetStart(const char *new_value) {
|
||||
void SetStart(const char *new_value) noexcept {
|
||||
if (new_value == nullptr)
|
||||
start.clear();
|
||||
else
|
||||
start = new_value;
|
||||
}
|
||||
|
||||
void SetStart(std::string &&new_value) {
|
||||
void SetStart(std::string &&new_value) noexcept {
|
||||
start = std::move(new_value);
|
||||
}
|
||||
|
||||
void SetEnd(const char *new_value) {
|
||||
void SetEnd(const char *new_value) noexcept {
|
||||
if (new_value == nullptr)
|
||||
end.clear();
|
||||
else
|
||||
end = new_value;
|
||||
}
|
||||
|
||||
void SetEnd(std::string &&new_value) {
|
||||
void SetEnd(std::string &&new_value) noexcept {
|
||||
end = std::move(new_value);
|
||||
}
|
||||
};
|
||||
|
@@ -23,19 +23,19 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
MusicBuffer::MusicBuffer(unsigned num_chunks)
|
||||
MusicBuffer::MusicBuffer(unsigned num_chunks) noexcept
|
||||
:buffer(num_chunks) {
|
||||
}
|
||||
|
||||
MusicChunk *
|
||||
MusicBuffer::Allocate()
|
||||
MusicBuffer::Allocate() noexcept
|
||||
{
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
return buffer.Allocate();
|
||||
}
|
||||
|
||||
void
|
||||
MusicBuffer::Return(MusicChunk *chunk)
|
||||
MusicBuffer::Return(MusicChunk *chunk) noexcept
|
||||
{
|
||||
assert(chunk != nullptr);
|
||||
|
||||
|
@@ -41,7 +41,7 @@ public:
|
||||
* @param num_chunks the number of #MusicChunk reserved in
|
||||
* this buffer
|
||||
*/
|
||||
MusicBuffer(unsigned num_chunks);
|
||||
MusicBuffer(unsigned num_chunks) noexcept;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
* music_buffer_new().
|
||||
*/
|
||||
gcc_pure
|
||||
unsigned GetSize() const {
|
||||
unsigned GetSize() const noexcept {
|
||||
return buffer.GetCapacity();
|
||||
}
|
||||
|
||||
@@ -71,13 +71,13 @@ public:
|
||||
* @return an empty chunk or nullptr if there are no chunks
|
||||
* available
|
||||
*/
|
||||
MusicChunk *Allocate();
|
||||
MusicChunk *Allocate() noexcept;
|
||||
|
||||
/**
|
||||
* Returns a chunk to the buffer. It can be reused by
|
||||
* Allocate() then.
|
||||
*/
|
||||
void Return(MusicChunk *chunk);
|
||||
void Return(MusicChunk *chunk) noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -31,7 +31,7 @@ MusicChunk::~MusicChunk()
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool
|
||||
MusicChunk::CheckFormat(const AudioFormat other_format) const
|
||||
MusicChunk::CheckFormat(const AudioFormat other_format) const noexcept
|
||||
{
|
||||
assert(other_format.IsValid());
|
||||
|
||||
@@ -41,7 +41,7 @@ MusicChunk::CheckFormat(const AudioFormat other_format) const
|
||||
|
||||
WritableBuffer<void>
|
||||
MusicChunk::Write(const AudioFormat af,
|
||||
SongTime data_time, uint16_t _bit_rate)
|
||||
SongTime data_time, uint16_t _bit_rate) noexcept
|
||||
{
|
||||
assert(CheckFormat(af));
|
||||
assert(length == 0 || audio_format.IsValid());
|
||||
@@ -64,7 +64,7 @@ MusicChunk::Write(const AudioFormat af,
|
||||
}
|
||||
|
||||
bool
|
||||
MusicChunk::Expand(const AudioFormat af, size_t _length)
|
||||
MusicChunk::Expand(const AudioFormat af, size_t _length) noexcept
|
||||
{
|
||||
const size_t frame_size = af.GetFrameSize();
|
||||
|
||||
|
@@ -111,7 +111,7 @@ struct MusicChunk {
|
||||
* specified audio_format.
|
||||
*/
|
||||
gcc_pure
|
||||
bool CheckFormat(AudioFormat audio_format) const;
|
||||
bool CheckFormat(AudioFormat audio_format) const noexcept;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -127,7 +127,7 @@ struct MusicChunk {
|
||||
*/
|
||||
WritableBuffer<void> Write(AudioFormat af,
|
||||
SongTime data_time,
|
||||
uint16_t bit_rate);
|
||||
uint16_t bit_rate) noexcept;
|
||||
|
||||
/**
|
||||
* Increases the length of the chunk after the caller has written to
|
||||
@@ -138,7 +138,7 @@ struct MusicChunk {
|
||||
* @param length the number of bytes which were appended
|
||||
* @return true if the chunk is full
|
||||
*/
|
||||
bool Expand(AudioFormat af, size_t length);
|
||||
bool Expand(AudioFormat af, size_t length) noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#ifndef NDEBUG
|
||||
|
||||
bool
|
||||
MusicPipe::Contains(const MusicChunk *chunk) const
|
||||
MusicPipe::Contains(const MusicChunk *chunk) const noexcept
|
||||
{
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
|
||||
@@ -39,7 +39,7 @@ MusicPipe::Contains(const MusicChunk *chunk) const
|
||||
#endif
|
||||
|
||||
MusicChunk *
|
||||
MusicPipe::Shift()
|
||||
MusicPipe::Shift() noexcept
|
||||
{
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
|
||||
@@ -73,7 +73,7 @@ MusicPipe::Shift()
|
||||
}
|
||||
|
||||
void
|
||||
MusicPipe::Clear(MusicBuffer &buffer)
|
||||
MusicPipe::Clear(MusicBuffer &buffer) noexcept
|
||||
{
|
||||
MusicChunk *chunk;
|
||||
|
||||
@@ -82,7 +82,7 @@ MusicPipe::Clear(MusicBuffer &buffer)
|
||||
}
|
||||
|
||||
void
|
||||
MusicPipe::Push(MusicChunk *chunk)
|
||||
MusicPipe::Push(MusicChunk *chunk) noexcept
|
||||
{
|
||||
assert(!chunk->IsEmpty());
|
||||
assert(chunk->length == 0 || chunk->audio_format.IsValid());
|
||||
|
@@ -77,7 +77,7 @@ public:
|
||||
* audio_format.
|
||||
*/
|
||||
gcc_pure
|
||||
bool CheckFormat(AudioFormat other) const {
|
||||
bool CheckFormat(AudioFormat other) const noexcept {
|
||||
return !audio_format.IsDefined() ||
|
||||
audio_format == other;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
* Checks if the specified chunk is enqueued in the music pipe.
|
||||
*/
|
||||
gcc_pure
|
||||
bool Contains(const MusicChunk *chunk) const;
|
||||
bool Contains(const MusicChunk *chunk) const noexcept;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -94,37 +94,37 @@ public:
|
||||
* nullptr if the pipe is empty.
|
||||
*/
|
||||
gcc_pure
|
||||
const MusicChunk *Peek() const {
|
||||
const MusicChunk *Peek() const noexcept {
|
||||
return head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first chunk from the head, and returns it.
|
||||
*/
|
||||
MusicChunk *Shift();
|
||||
MusicChunk *Shift() noexcept;
|
||||
|
||||
/**
|
||||
* Clears the whole pipe and returns the chunks to the buffer.
|
||||
*
|
||||
* @param buffer the buffer object to return the chunks to
|
||||
*/
|
||||
void Clear(MusicBuffer &buffer);
|
||||
void Clear(MusicBuffer &buffer) noexcept;
|
||||
|
||||
/**
|
||||
* Pushes a chunk to the tail of the pipe.
|
||||
*/
|
||||
void Push(MusicChunk *chunk);
|
||||
void Push(MusicChunk *chunk) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of chunks currently in this pipe.
|
||||
*/
|
||||
gcc_pure
|
||||
unsigned GetSize() const {
|
||||
unsigned GetSize() const noexcept {
|
||||
return size;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return GetSize() == 0;
|
||||
}
|
||||
};
|
||||
|
@@ -200,7 +200,6 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
||||
*/
|
||||
const Database *GetDatabase() const;
|
||||
|
||||
gcc_pure
|
||||
const Database &GetDatabaseOrThrow() const;
|
||||
|
||||
/**
|
||||
|
@@ -49,7 +49,6 @@ static std::map<std::string, unsigned> permission_passwords;
|
||||
|
||||
static unsigned permission_default;
|
||||
|
||||
gcc_pure
|
||||
static unsigned
|
||||
ParsePermission(const char *p)
|
||||
{
|
||||
|
@@ -207,13 +207,12 @@ try {
|
||||
continue;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t buffer[MAX_PATH];
|
||||
auto result = MultiByteToWideChar(CP_ACP, 0, s, -1,
|
||||
buffer, ARRAY_SIZE(buffer));
|
||||
if (result <= 0)
|
||||
/* on Windows, playlists always contain UTF-8, because
|
||||
its "narrow" charset (i.e. CP_ACP) is incapable of
|
||||
storing all Unicode paths */
|
||||
const auto path = AllocatedPath::FromUTF8(s);
|
||||
if (path.IsNull())
|
||||
continue;
|
||||
|
||||
const Path path = Path::FromFS(buffer);
|
||||
#else
|
||||
const Path path = Path::FromFS(s);
|
||||
#endif
|
||||
|
@@ -28,13 +28,25 @@
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "fs/NarrowPath.hxx"
|
||||
#include "fs/io/FileOutputStream.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
static void
|
||||
playlist_print_path(BufferedOutputStream &os, const Path path)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
/* on Windows, playlists always contain UTF-8, because its
|
||||
"narrow" charset (i.e. CP_ACP) is incapable of storing all
|
||||
Unicode paths */
|
||||
os.Format("%s\n", path.ToUTF8().c_str());
|
||||
#else
|
||||
os.Format("%s\n", path.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
|
||||
{
|
||||
@@ -44,7 +56,7 @@ playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
|
||||
|
||||
try {
|
||||
const auto uri_fs = AllocatedPath::FromUTF8Throw(uri_utf8);
|
||||
os.Format("%s\n", NarrowPath(uri_fs).c_str());
|
||||
playlist_print_path(os, uri_fs);
|
||||
} catch (const std::runtime_error &) {
|
||||
}
|
||||
}
|
||||
@@ -63,7 +75,7 @@ playlist_print_uri(BufferedOutputStream &os, const char *uri)
|
||||
AllocatedPath::FromUTF8Throw(uri);
|
||||
|
||||
if (!path.IsNull())
|
||||
os.Format("%s\n", NarrowPath(path).c_str());
|
||||
playlist_print_path(os, path);
|
||||
} catch (const std::runtime_error &) {
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include <math.h>
|
||||
|
||||
float
|
||||
ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const
|
||||
ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept
|
||||
{
|
||||
float scale;
|
||||
|
||||
|
@@ -40,23 +40,23 @@ struct ReplayGainTuple {
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
float CalculateScale(const ReplayGainConfig &config) const;
|
||||
float CalculateScale(const ReplayGainConfig &config) const noexcept;
|
||||
};
|
||||
|
||||
struct ReplayGainInfo {
|
||||
ReplayGainTuple track, album;
|
||||
|
||||
constexpr bool IsDefined() const {
|
||||
constexpr bool IsDefined() const noexcept {
|
||||
return track.IsDefined() || album.IsDefined();
|
||||
}
|
||||
|
||||
const ReplayGainTuple &Get(ReplayGainMode mode) const {
|
||||
const ReplayGainTuple &Get(ReplayGainMode mode) const noexcept {
|
||||
return mode == ReplayGainMode::ALBUM
|
||||
? (album.IsDefined() ? album : track)
|
||||
: (track.IsDefined() ? track : album);
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
track.Clear();
|
||||
album.Clear();
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
const char *
|
||||
ToString(ReplayGainMode mode)
|
||||
ToString(ReplayGainMode mode) noexcept
|
||||
{
|
||||
switch (mode) {
|
||||
case ReplayGainMode::AUTO:
|
||||
|
@@ -36,13 +36,12 @@ enum class ReplayGainMode : uint8_t {
|
||||
*/
|
||||
gcc_pure
|
||||
const char *
|
||||
ToString(ReplayGainMode mode);
|
||||
ToString(ReplayGainMode mode) noexcept;
|
||||
|
||||
/**
|
||||
* Parse a string to a #ReplayGainMode. Throws std::runtime_error on
|
||||
* error.
|
||||
*/
|
||||
gcc_pure
|
||||
ReplayGainMode
|
||||
FromString(const char *s);
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/TimeParser.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "lib/icu/Collate.hxx"
|
||||
#include "lib/icu/CaseFold.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define LOCATE_TAG_ANY_KEY "any"
|
||||
|
||||
unsigned
|
||||
locate_parse_type(const char *str)
|
||||
locate_parse_type(const char *str) noexcept
|
||||
{
|
||||
if (StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY) ||
|
||||
StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY_OLD))
|
||||
@@ -57,18 +57,10 @@ locate_parse_type(const char *str)
|
||||
return tag_name_parse_i(str);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static AllocatedString<>
|
||||
ImportString(const char *p, bool fold_case)
|
||||
{
|
||||
return fold_case
|
||||
? IcuCaseFold(p)
|
||||
: AllocatedString<>::Duplicate(p);
|
||||
}
|
||||
|
||||
SongFilter::Item::Item(unsigned _tag, const char *_value, bool _fold_case)
|
||||
:tag(_tag), fold_case(_fold_case),
|
||||
value(ImportString(_value, _fold_case))
|
||||
:tag(_tag),
|
||||
value(AllocatedString<>::Duplicate(_value)),
|
||||
fold_case(_fold_case ? IcuCompare(value.c_str()) : IcuCompare())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,7 +70,7 @@ SongFilter::Item::Item(unsigned _tag, time_t _time)
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::StringMatch(const char *s) const
|
||||
SongFilter::Item::StringMatch(const char *s) const noexcept
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
@@ -88,23 +80,21 @@ SongFilter::Item::StringMatch(const char *s) const
|
||||
assert(tag != LOCATE_TAG_MODIFIED_SINCE);
|
||||
|
||||
if (fold_case) {
|
||||
const auto folded = IcuCaseFold(s);
|
||||
assert(!folded.IsNull());
|
||||
return StringFind(folded.c_str(), value.c_str()) != nullptr;
|
||||
return fold_case.IsIn(s);
|
||||
} else {
|
||||
return StringIsEqual(s, value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const TagItem &item) const
|
||||
SongFilter::Item::Match(const TagItem &item) const noexcept
|
||||
{
|
||||
return (tag == LOCATE_TAG_ANY_TYPE || (unsigned)item.type == tag) &&
|
||||
StringMatch(item.value);
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const Tag &_tag) const
|
||||
SongFilter::Item::Match(const Tag &_tag) const noexcept
|
||||
{
|
||||
bool visited_types[TAG_NUM_OF_ITEM_TYPES];
|
||||
std::fill_n(visited_types, size_t(TAG_NUM_OF_ITEM_TYPES), false);
|
||||
@@ -140,7 +130,7 @@ SongFilter::Item::Match(const Tag &_tag) const
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const DetachedSong &song) const
|
||||
SongFilter::Item::Match(const DetachedSong &song) const noexcept
|
||||
{
|
||||
if (tag == LOCATE_TAG_BASE_TYPE)
|
||||
return uri_is_child_or_same(value.c_str(), song.GetURI());
|
||||
@@ -155,7 +145,7 @@ SongFilter::Item::Match(const DetachedSong &song) const
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const LightSong &song) const
|
||||
SongFilter::Item::Match(const LightSong &song) const noexcept
|
||||
{
|
||||
if (tag == LOCATE_TAG_BASE_TYPE) {
|
||||
const auto uri = song.GetURI();
|
||||
@@ -185,7 +175,7 @@ SongFilter::~SongFilter()
|
||||
|
||||
gcc_pure
|
||||
static time_t
|
||||
ParseTimeStamp(const char *s)
|
||||
ParseTimeStamp(const char *s) noexcept
|
||||
{
|
||||
assert(s != nullptr);
|
||||
|
||||
@@ -246,7 +236,7 @@ SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case)
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Match(const DetachedSong &song) const
|
||||
SongFilter::Match(const DetachedSong &song) const noexcept
|
||||
{
|
||||
for (const auto &i : items)
|
||||
if (!i.Match(song))
|
||||
@@ -256,7 +246,7 @@ SongFilter::Match(const DetachedSong &song) const
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Match(const LightSong &song) const
|
||||
SongFilter::Match(const LightSong &song) const noexcept
|
||||
{
|
||||
for (const auto &i : items)
|
||||
if (!i.Match(song))
|
||||
@@ -266,7 +256,7 @@ SongFilter::Match(const LightSong &song) const
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::HasOtherThanBase() const
|
||||
SongFilter::HasOtherThanBase() const noexcept
|
||||
{
|
||||
for (const auto &i : items)
|
||||
if (i.GetTag() != LOCATE_TAG_BASE_TYPE)
|
||||
@@ -276,7 +266,7 @@ SongFilter::HasOtherThanBase() const
|
||||
}
|
||||
|
||||
const char *
|
||||
SongFilter::GetBase() const
|
||||
SongFilter::GetBase() const noexcept
|
||||
{
|
||||
for (const auto &i : items)
|
||||
if (i.GetTag() == LOCATE_TAG_BASE_TYPE)
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#ifndef MPD_SONG_FILTER_HXX
|
||||
#define MPD_SONG_FILTER_HXX
|
||||
|
||||
#include "lib/icu/Compare.hxx"
|
||||
#include "util/AllocatedString.hxx"
|
||||
#include "Compiler.h"
|
||||
|
||||
@@ -48,10 +49,13 @@ public:
|
||||
class Item {
|
||||
uint8_t tag;
|
||||
|
||||
bool fold_case;
|
||||
|
||||
AllocatedString<> value;
|
||||
|
||||
/**
|
||||
* This value is only set if case folding is enabled.
|
||||
*/
|
||||
IcuCompare fold_case;
|
||||
|
||||
/**
|
||||
* For #LOCATE_TAG_MODIFIED_SINCE
|
||||
*/
|
||||
@@ -80,19 +84,19 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull(2)
|
||||
bool StringMatch(const char *s) const;
|
||||
bool StringMatch(const char *s) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const TagItem &tag_item) const;
|
||||
bool Match(const TagItem &tag_item) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const Tag &tag) const;
|
||||
bool Match(const Tag &tag) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const DetachedSong &song) const;
|
||||
bool Match(const DetachedSong &song) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const LightSong &song) const;
|
||||
bool Match(const LightSong &song) const noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -112,20 +116,20 @@ public:
|
||||
bool Parse(ConstBuffer<const char *> args, bool fold_case=false);
|
||||
|
||||
gcc_pure
|
||||
bool Match(const Tag &tag) const;
|
||||
bool Match(const Tag &tag) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const DetachedSong &song) const;
|
||||
bool Match(const DetachedSong &song) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const LightSong &song) const;
|
||||
bool Match(const LightSong &song) const noexcept;
|
||||
|
||||
const std::list<Item> &GetItems() const {
|
||||
const std::list<Item> &GetItems() const noexcept {
|
||||
return items;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return items.empty();
|
||||
}
|
||||
|
||||
@@ -133,7 +137,7 @@ public:
|
||||
* Is there at least one item with "fold case" enabled?
|
||||
*/
|
||||
gcc_pure
|
||||
bool HasFoldCase() const {
|
||||
bool HasFoldCase() const noexcept {
|
||||
for (const auto &i : items)
|
||||
if (i.GetFoldCase())
|
||||
return true;
|
||||
@@ -145,14 +149,14 @@ public:
|
||||
* Does this filter contain constraints other than "base"?
|
||||
*/
|
||||
gcc_pure
|
||||
bool HasOtherThanBase() const;
|
||||
bool HasOtherThanBase() const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the "base" specification (if there is one) or
|
||||
* nullptr.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *GetBase() const;
|
||||
const char *GetBase() const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -160,6 +164,6 @@ public:
|
||||
*/
|
||||
gcc_pure
|
||||
unsigned
|
||||
locate_parse_type(const char *str);
|
||||
locate_parse_type(const char *str) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -50,7 +50,7 @@ StateFile::StateFile(AllocatedPath &&_path,
|
||||
}
|
||||
|
||||
void
|
||||
StateFile::RememberVersions()
|
||||
StateFile::RememberVersions() noexcept
|
||||
{
|
||||
prev_volume_version = sw_volume_state_get_hash();
|
||||
prev_output_version = audio_output_state_get_version();
|
||||
@@ -59,7 +59,7 @@ StateFile::RememberVersions()
|
||||
}
|
||||
|
||||
bool
|
||||
StateFile::IsModified() const
|
||||
StateFile::IsModified() const noexcept
|
||||
{
|
||||
return prev_volume_version != sw_volume_state_get_hash() ||
|
||||
prev_output_version != audio_output_state_get_version() ||
|
||||
|
@@ -67,14 +67,14 @@ private:
|
||||
/**
|
||||
* Save the current state versions for use with IsModified().
|
||||
*/
|
||||
void RememberVersions();
|
||||
void RememberVersions() noexcept;
|
||||
|
||||
/**
|
||||
* Check if MPD's state was modified since the last
|
||||
* RememberVersions() call.
|
||||
*/
|
||||
gcc_pure
|
||||
bool IsModified() const;
|
||||
bool IsModified() const noexcept;
|
||||
|
||||
/* virtual methods from TimeoutMonitor */
|
||||
void OnTimeout() override;
|
||||
|
@@ -40,7 +40,7 @@
|
||||
gcc_pure
|
||||
static bool
|
||||
CheckDecoderPlugin(const DecoderPlugin &plugin,
|
||||
const char *suffix, const char *mime)
|
||||
const char *suffix, const char *mime) noexcept
|
||||
{
|
||||
return (mime != nullptr && plugin.SupportsMimeType(mime)) ||
|
||||
(suffix != nullptr && plugin.SupportsSuffix(suffix));
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
gcc_pure
|
||||
static char *
|
||||
FindSlash(char *p, size_t i)
|
||||
FindSlash(char *p, size_t i) noexcept
|
||||
{
|
||||
for (; i > 0; --i)
|
||||
if (p[i] == '/')
|
||||
@@ -39,7 +39,7 @@ FindSlash(char *p, size_t i)
|
||||
|
||||
gcc_pure
|
||||
static const char *
|
||||
FindSuffix(const char *p, const char *i)
|
||||
FindSuffix(const char *p, const char *i) noexcept
|
||||
{
|
||||
for (; i > p; --i) {
|
||||
if (*i == '.')
|
||||
|
@@ -93,7 +93,7 @@ public:
|
||||
~Bzip2InputStream();
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool IsEOF() override;
|
||||
bool IsEOF() noexcept override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
|
||||
private:
|
||||
@@ -205,7 +205,7 @@ Bzip2InputStream::Read(void *ptr, size_t length)
|
||||
}
|
||||
|
||||
bool
|
||||
Bzip2InputStream::IsEOF()
|
||||
Bzip2InputStream::IsEOF() noexcept
|
||||
{
|
||||
return eof;
|
||||
}
|
||||
|
@@ -162,7 +162,7 @@ public:
|
||||
}
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool IsEOF() override;
|
||||
bool IsEOF() noexcept override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
};
|
||||
|
||||
@@ -213,7 +213,7 @@ Iso9660InputStream::Read(void *ptr, size_t read_size)
|
||||
}
|
||||
|
||||
bool
|
||||
Iso9660InputStream::IsEOF()
|
||||
Iso9660InputStream::IsEOF() noexcept
|
||||
{
|
||||
return offset == size;
|
||||
}
|
||||
|
@@ -116,7 +116,7 @@ struct ZzipInputStream final : public InputStream {
|
||||
}
|
||||
|
||||
/* virtual methods from InputStream */
|
||||
bool IsEOF() override;
|
||||
bool IsEOF() noexcept override;
|
||||
size_t Read(void *ptr, size_t size) override;
|
||||
void Seek(offset_type offset) override;
|
||||
};
|
||||
@@ -147,7 +147,7 @@ ZzipInputStream::Read(void *ptr, size_t read_size)
|
||||
}
|
||||
|
||||
bool
|
||||
ZzipInputStream::IsEOF()
|
||||
ZzipInputStream::IsEOF() noexcept
|
||||
{
|
||||
return offset_type(zzip_tell(file)) == size;
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ const Domain client_domain("client");
|
||||
#ifdef ENABLE_DATABASE
|
||||
|
||||
const Database *
|
||||
Client::GetDatabase() const
|
||||
Client::GetDatabase() const noexcept
|
||||
{
|
||||
return partition.instance.GetDatabase();
|
||||
}
|
||||
@@ -40,7 +40,7 @@ Client::GetDatabaseOrThrow() const
|
||||
}
|
||||
|
||||
const Storage *
|
||||
Client::GetStorage() const
|
||||
Client::GetStorage() const noexcept
|
||||
{
|
||||
return partition.instance.storage;
|
||||
}
|
||||
|
@@ -100,7 +100,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsExpired() const {
|
||||
bool IsExpired() const noexcept {
|
||||
return !FullyBufferedSocket::IsDefined();
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
};
|
||||
|
||||
gcc_pure
|
||||
bool IsSubscribed(const char *channel_name) const {
|
||||
bool IsSubscribed(const char *channel_name) const noexcept {
|
||||
return subscriptions.find(channel_name) != subscriptions.end();
|
||||
}
|
||||
|
||||
@@ -186,16 +186,15 @@ public:
|
||||
* Wrapper for Instance::GetDatabase().
|
||||
*/
|
||||
gcc_pure
|
||||
const Database *GetDatabase() const;
|
||||
const Database *GetDatabase() const noexcept;
|
||||
|
||||
/**
|
||||
* Wrapper for Instance::GetDatabaseOrThrow().
|
||||
*/
|
||||
gcc_pure
|
||||
const Database &GetDatabaseOrThrow() const;
|
||||
|
||||
gcc_pure
|
||||
const Storage *GetStorage() const;
|
||||
const Storage *GetStorage() const noexcept;
|
||||
|
||||
private:
|
||||
/* virtual methods from class BufferedSocket */
|
||||
|
@@ -23,14 +23,14 @@
|
||||
|
||||
gcc_const
|
||||
static bool
|
||||
valid_channel_char(const char ch)
|
||||
valid_channel_char(const char ch) noexcept
|
||||
{
|
||||
return IsAlphaNumericASCII(ch) ||
|
||||
ch == '_' || ch == '-' || ch == '.' || ch == ':';
|
||||
}
|
||||
|
||||
bool
|
||||
client_message_valid_channel_name(const char *name)
|
||||
client_message_valid_channel_name(const char *name) noexcept
|
||||
{
|
||||
do {
|
||||
if (!valid_channel_char(*name))
|
||||
|
@@ -53,6 +53,6 @@ public:
|
||||
|
||||
gcc_pure
|
||||
bool
|
||||
client_message_valid_channel_name(const char *name);
|
||||
client_message_valid_channel_name(const char *name) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -54,7 +54,7 @@
|
||||
|
||||
gcc_const
|
||||
static enum ack
|
||||
ToAck(PlaylistResult result)
|
||||
ToAck(PlaylistResult result) noexcept
|
||||
{
|
||||
switch (result) {
|
||||
case PlaylistResult::SUCCESS:
|
||||
@@ -90,7 +90,7 @@ ToAck(PlaylistResult result)
|
||||
#ifdef ENABLE_DATABASE
|
||||
gcc_const
|
||||
static enum ack
|
||||
ToAck(DatabaseErrorCode code)
|
||||
ToAck(DatabaseErrorCode code) noexcept
|
||||
{
|
||||
switch (code) {
|
||||
case DatabaseErrorCode::DISABLED:
|
||||
@@ -107,7 +107,7 @@ ToAck(DatabaseErrorCode code)
|
||||
|
||||
gcc_pure
|
||||
static enum ack
|
||||
ToAck(std::exception_ptr ep)
|
||||
ToAck(std::exception_ptr ep) noexcept
|
||||
{
|
||||
try {
|
||||
std::rethrow_exception(ep);
|
||||
|
@@ -44,7 +44,7 @@
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
|
||||
SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept
|
||||
{
|
||||
return name_fs[0] == '.' &&
|
||||
(name_fs[1] == 0 ||
|
||||
@@ -53,7 +53,7 @@ SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
skip_path(Path name_fs)
|
||||
skip_path(Path name_fs) noexcept
|
||||
{
|
||||
return name_fs.HasNewline();
|
||||
}
|
||||
@@ -107,7 +107,7 @@ handle_listfiles_local(Response &r, Path path_fs)
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidName(const char *p)
|
||||
IsValidName(const char *p) noexcept
|
||||
{
|
||||
if (!IsAlphaASCII(*p))
|
||||
return false;
|
||||
@@ -123,7 +123,7 @@ IsValidName(const char *p)
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidValue(const char *p)
|
||||
IsValidValue(const char *p) noexcept
|
||||
{
|
||||
while (*p) {
|
||||
const char ch = *p++;
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include <string>
|
||||
|
||||
bool
|
||||
neighbor_commands_available(const Instance &instance)
|
||||
neighbor_commands_available(const Instance &instance) noexcept
|
||||
{
|
||||
return instance.neighbors != nullptr;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ class Response;
|
||||
|
||||
gcc_pure
|
||||
bool
|
||||
neighbor_commands_available(const Instance &instance);
|
||||
neighbor_commands_available(const Instance &instance) noexcept;
|
||||
|
||||
CommandResult
|
||||
handle_listneighbors(Client &client, Request request, Response &response);
|
||||
|
@@ -39,7 +39,7 @@
|
||||
#include "util/ConstBuffer.hxx"
|
||||
|
||||
bool
|
||||
playlist_commands_available()
|
||||
playlist_commands_available() noexcept
|
||||
{
|
||||
return !map_spl_path().IsNull();
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ class Response;
|
||||
|
||||
gcc_const
|
||||
bool
|
||||
playlist_commands_available();
|
||||
playlist_commands_available() noexcept;
|
||||
|
||||
CommandResult
|
||||
handle_save(Client &client, Request request, Response &response);
|
||||
|
@@ -45,68 +45,57 @@ public:
|
||||
: default_value;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseInt(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseInt(unsigned idx, int min_value, int max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx], min_value, max_value);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseUnsigned(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseUnsigned(unsigned idx, unsigned max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx], max_value);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool ParseBool(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgBool(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
RangeArg ParseRange(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgRange(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
float ParseFloat(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgFloat(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SongTime ParseSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSongTime(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SignedSongTime ParseSignedSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSignedSongTime(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseOptional(unsigned idx, int default_value) const {
|
||||
return idx < size
|
||||
? ParseInt(idx)
|
||||
: default_value;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
RangeArg ParseOptional(unsigned idx, RangeArg default_value) const {
|
||||
return idx < size
|
||||
? ParseRange(idx)
|
||||
|
@@ -45,7 +45,7 @@
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
skip_path(const char *name_utf8)
|
||||
skip_path(const char *name_utf8) noexcept
|
||||
{
|
||||
return strchr(name_utf8, '\n') != nullptr;
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ ConfigBlock::~ConfigBlock()
|
||||
}
|
||||
|
||||
const BlockParam *
|
||||
ConfigBlock::GetBlockParam(const char *name) const
|
||||
ConfigBlock::GetBlockParam(const char *name) const noexcept
|
||||
{
|
||||
for (const auto &i : block_params) {
|
||||
if (i.name == name) {
|
||||
@@ -81,7 +81,8 @@ ConfigBlock::GetBlockParam(const char *name) const
|
||||
}
|
||||
|
||||
const char *
|
||||
ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
|
||||
ConfigBlock::GetBlockValue(const char *name,
|
||||
const char *default_value) const noexcept
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
@@ -128,7 +129,6 @@ ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
|
||||
return bp->GetUnsignedValue();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool
|
||||
ConfigBlock::GetBlockValue(const char *name, bool default_value) const
|
||||
{
|
||||
|
@@ -44,13 +44,10 @@ struct BlockParam {
|
||||
BlockParam(const char *_name, const char *_value, int _line=-1)
|
||||
:name(_name), value(_value), line(_line), used(false) {}
|
||||
|
||||
gcc_pure
|
||||
int GetIntValue() const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetUnsignedValue() const;
|
||||
|
||||
gcc_pure
|
||||
bool GetBoolValue() const;
|
||||
};
|
||||
|
||||
@@ -85,12 +82,12 @@ struct ConfigBlock {
|
||||
* object that was synthesized and not loaded from a
|
||||
* configuration file.
|
||||
*/
|
||||
bool IsNull() const {
|
||||
bool IsNull() const noexcept {
|
||||
return line < 0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return block_params.empty();
|
||||
}
|
||||
|
||||
@@ -101,11 +98,11 @@ struct ConfigBlock {
|
||||
}
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
const BlockParam *GetBlockParam(const char *_name) const;
|
||||
const BlockParam *GetBlockParam(const char *_name) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
const char *GetBlockValue(const char *name,
|
||||
const char *default_value=nullptr) const;
|
||||
const char *default_value=nullptr) const noexcept;
|
||||
|
||||
/**
|
||||
* Same as config_get_path(), but looks up the setting in the
|
||||
@@ -116,13 +113,10 @@ struct ConfigBlock {
|
||||
AllocatedPath GetPath(const char *name,
|
||||
const char *default_value=nullptr) const;
|
||||
|
||||
gcc_pure
|
||||
int GetBlockValue(const char *name, int default_value) const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetBlockValue(const char *name, unsigned default_value) const;
|
||||
|
||||
gcc_pure
|
||||
bool GetBlockValue(const char *name, bool default_value) const;
|
||||
};
|
||||
|
||||
|
@@ -75,7 +75,7 @@ void config_global_check(void)
|
||||
}
|
||||
|
||||
const ConfigParam *
|
||||
config_get_param(ConfigOption option)
|
||||
config_get_param(ConfigOption option) noexcept
|
||||
{
|
||||
auto *param = config_data.params[unsigned(option)];
|
||||
if (param != nullptr)
|
||||
@@ -84,7 +84,7 @@ config_get_param(ConfigOption option)
|
||||
}
|
||||
|
||||
const ConfigBlock *
|
||||
config_get_block(ConfigBlockOption option)
|
||||
config_get_block(ConfigBlockOption option) noexcept
|
||||
{
|
||||
ConfigBlock *block = config_data.blocks[unsigned(option)];
|
||||
if (block != nullptr)
|
||||
@@ -110,7 +110,7 @@ config_find_block(ConfigBlockOption option, const char *key, const char *value)
|
||||
}
|
||||
|
||||
const char *
|
||||
config_get_string(ConfigOption option, const char *default_value)
|
||||
config_get_string(ConfigOption option, const char *default_value) noexcept
|
||||
{
|
||||
const auto *param = config_get_param(option);
|
||||
|
||||
|
@@ -48,11 +48,11 @@ ReadConfigFile(Path path);
|
||||
|
||||
gcc_pure
|
||||
const ConfigParam *
|
||||
config_get_param(enum ConfigOption option);
|
||||
config_get_param(enum ConfigOption option) noexcept;
|
||||
|
||||
gcc_pure
|
||||
const ConfigBlock *
|
||||
config_get_block(enum ConfigBlockOption option);
|
||||
config_get_block(enum ConfigBlockOption option) noexcept;
|
||||
|
||||
/**
|
||||
* Find a block with a matching attribute.
|
||||
@@ -61,20 +61,12 @@ config_get_block(enum ConfigBlockOption option);
|
||||
* @param key the attribute name
|
||||
* @param value the expected attribute value
|
||||
*/
|
||||
gcc_pure
|
||||
const ConfigBlock *
|
||||
config_find_block(ConfigBlockOption option, const char *key, const char *value);
|
||||
|
||||
/* Note on gcc_pure: Some of the functions declared pure are not
|
||||
really pure in strict sense. They have side effect such that they
|
||||
validate parameter's value and signal an error if it's invalid.
|
||||
However, if the argument was already validated or we don't care
|
||||
about the argument at all, this may be ignored so in the end, we
|
||||
should be fine with calling those functions pure. */
|
||||
|
||||
gcc_pure
|
||||
const char *
|
||||
config_get_string(enum ConfigOption option, const char *default_value=nullptr);
|
||||
config_get_string(enum ConfigOption option,
|
||||
const char *default_value=nullptr) noexcept;
|
||||
|
||||
/**
|
||||
* Returns an optional configuration variable which contains an
|
||||
@@ -86,11 +78,9 @@ config_get_string(enum ConfigOption option, const char *default_value=nullptr);
|
||||
AllocatedPath
|
||||
config_get_path(enum ConfigOption option);
|
||||
|
||||
gcc_pure
|
||||
unsigned
|
||||
config_get_unsigned(enum ConfigOption option, unsigned default_value);
|
||||
|
||||
gcc_pure
|
||||
static inline std::chrono::steady_clock::duration
|
||||
config_get_unsigned(ConfigOption option,
|
||||
std::chrono::steady_clock::duration default_value)
|
||||
@@ -100,11 +90,9 @@ config_get_unsigned(ConfigOption option,
|
||||
return std::chrono::steady_clock::duration(u);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
unsigned
|
||||
config_get_positive(enum ConfigOption option, unsigned default_value);
|
||||
|
||||
gcc_pure
|
||||
static inline std::chrono::steady_clock::duration
|
||||
config_get_positive(ConfigOption option,
|
||||
std::chrono::steady_clock::duration default_value)
|
||||
@@ -114,7 +102,6 @@ config_get_positive(ConfigOption option,
|
||||
return std::chrono::steady_clock::duration(u);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool config_get_bool(enum ConfigOption option, bool default_value);
|
||||
|
||||
#endif
|
||||
|
@@ -102,13 +102,13 @@ enum class ConfigBlockOption {
|
||||
*/
|
||||
gcc_pure
|
||||
enum ConfigOption
|
||||
ParseConfigOptionName(const char *name);
|
||||
ParseConfigOptionName(const char *name) noexcept;
|
||||
|
||||
/**
|
||||
* @return #ConfigOption::MAX if not found
|
||||
*/
|
||||
gcc_pure
|
||||
enum ConfigBlockOption
|
||||
ParseConfigBlockOptionName(const char *name);
|
||||
ParseConfigBlockOptionName(const char *name) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -101,7 +101,7 @@ static_assert(n_config_block_templates == unsigned(ConfigBlockOption::MAX),
|
||||
gcc_pure
|
||||
static inline unsigned
|
||||
ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
|
||||
const char *name)
|
||||
const char *name) noexcept
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (; i < count; ++i)
|
||||
@@ -112,7 +112,7 @@ ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
|
||||
}
|
||||
|
||||
ConfigOption
|
||||
ParseConfigOptionName(const char *name)
|
||||
ParseConfigOptionName(const char *name) noexcept
|
||||
{
|
||||
return ConfigOption(ParseConfigTemplateName(config_param_templates,
|
||||
n_config_param_templates,
|
||||
@@ -120,7 +120,7 @@ ParseConfigOptionName(const char *name)
|
||||
}
|
||||
|
||||
ConfigBlockOption
|
||||
ParseConfigBlockOptionName(const char *name)
|
||||
ParseConfigBlockOptionName(const char *name) noexcept
|
||||
{
|
||||
return ConfigBlockOption(ParseConfigTemplateName(config_block_templates,
|
||||
n_config_block_templates,
|
||||
|
@@ -71,7 +71,6 @@ struct ConfigParam {
|
||||
*
|
||||
* Throws #std::runtime_error on error.
|
||||
*/
|
||||
gcc_pure
|
||||
AllocatedPath GetPath() const;
|
||||
};
|
||||
|
||||
|
@@ -45,7 +45,7 @@ extern ThreadId db_mutex_holder;
|
||||
*/
|
||||
gcc_pure
|
||||
static inline bool
|
||||
holding_db_lock(void)
|
||||
holding_db_lock() noexcept
|
||||
{
|
||||
return db_mutex_holder.IsInside();
|
||||
}
|
||||
|
@@ -31,7 +31,6 @@ class DetachedSong;
|
||||
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
|
||||
* instance.
|
||||
*/
|
||||
gcc_pure
|
||||
DetachedSong
|
||||
DatabaseDetachSong(const Storage &storage, const LightSong &song);
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
struct StringLess {
|
||||
gcc_pure
|
||||
bool operator()(const char *a, const char *b) const {
|
||||
bool operator()(const char *a, const char *b) const noexcept {
|
||||
return strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
@@ -106,7 +106,6 @@ public:
|
||||
TagType tag_type, tag_mask_t group_mask,
|
||||
VisitTag visit_tag) const = 0;
|
||||
|
||||
gcc_pure
|
||||
virtual DatabaseStats GetStats(const DatabaseSelection &selection) const = 0;
|
||||
|
||||
/**
|
||||
@@ -127,7 +126,7 @@ public:
|
||||
* Returns 0 if that is not not known/available.
|
||||
*/
|
||||
gcc_pure
|
||||
virtual time_t GetUpdateStamp() const = 0;
|
||||
virtual time_t GetUpdateStamp() const noexcept = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -44,16 +44,16 @@ struct LightDirectory {
|
||||
constexpr LightDirectory(const char *_uri, time_t _mtime)
|
||||
:uri(_uri), mtime(_mtime) {}
|
||||
|
||||
static constexpr LightDirectory Root() {
|
||||
static constexpr LightDirectory Root() noexcept {
|
||||
return LightDirectory("", 0);
|
||||
}
|
||||
|
||||
bool IsRoot() const {
|
||||
bool IsRoot() const noexcept {
|
||||
return *uri == 0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetPath() const {
|
||||
const char *GetPath() const noexcept {
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#include "tag/Tag.hxx"
|
||||
|
||||
SignedSongTime
|
||||
LightSong::GetDuration() const
|
||||
LightSong::GetDuration() const noexcept
|
||||
{
|
||||
SongTime a = start_time, b = end_time;
|
||||
if (!b.IsPositive()) {
|
||||
|
@@ -76,7 +76,7 @@ struct LightSong {
|
||||
SongTime end_time;
|
||||
|
||||
gcc_pure
|
||||
std::string GetURI() const {
|
||||
std::string GetURI() const noexcept {
|
||||
if (directory == nullptr)
|
||||
return std::string(uri);
|
||||
|
||||
@@ -87,7 +87,7 @@ struct LightSong {
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SignedSongTime GetDuration() const;
|
||||
SignedSongTime GetDuration() const noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -45,7 +45,7 @@ struct PlaylistInfo {
|
||||
constexpr CompareName(const char *_name):name(_name) {}
|
||||
|
||||
gcc_pure
|
||||
bool operator()(const PlaylistInfo &pi) const {
|
||||
bool operator()(const PlaylistInfo &pi) const noexcept {
|
||||
return pi.name.compare(name) == 0;
|
||||
}
|
||||
};
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
PlaylistVector::iterator
|
||||
PlaylistVector::find(const char *name)
|
||||
PlaylistVector::find(const char *name) noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(name != nullptr);
|
||||
|
@@ -31,7 +31,7 @@ protected:
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
gcc_pure
|
||||
iterator find(const char *name);
|
||||
iterator find(const char *name) noexcept;
|
||||
|
||||
public:
|
||||
using std::list<PlaylistInfo>::empty;
|
||||
|
@@ -38,7 +38,7 @@ const DatabasePlugin *const database_plugins[] = {
|
||||
};
|
||||
|
||||
const DatabasePlugin *
|
||||
GetDatabasePluginByName(const char *name)
|
||||
GetDatabasePluginByName(const char *name) noexcept
|
||||
{
|
||||
for (auto i = database_plugins; *i != nullptr; ++i)
|
||||
if (strcmp((*i)->name, name) == 0)
|
||||
|
@@ -32,6 +32,6 @@ extern const DatabasePlugin *const database_plugins[];
|
||||
|
||||
gcc_pure
|
||||
const DatabasePlugin *
|
||||
GetDatabasePluginByName(const char *name);
|
||||
GetDatabasePluginByName(const char *name) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -17,6 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "Selection.hxx"
|
||||
#include "SongFilter.hxx"
|
||||
|
||||
@@ -34,19 +35,19 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive,
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseSelection::IsEmpty() const
|
||||
DatabaseSelection::IsEmpty() const noexcept
|
||||
{
|
||||
return uri.empty() && (filter == nullptr || filter->IsEmpty());
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseSelection::HasOtherThanBase() const
|
||||
DatabaseSelection::HasOtherThanBase() const noexcept
|
||||
{
|
||||
return filter != nullptr && filter->HasOtherThanBase();
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseSelection::Match(const LightSong &song) const
|
||||
DatabaseSelection::Match(const LightSong &song) const noexcept
|
||||
{
|
||||
return filter == nullptr || filter->Match(song);
|
||||
}
|
||||
|
@@ -45,16 +45,16 @@ struct DatabaseSelection {
|
||||
const SongFilter *_filter=nullptr);
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const;
|
||||
bool IsEmpty() const noexcept;
|
||||
|
||||
/**
|
||||
* Does this selection contain constraints other than "base"?
|
||||
*/
|
||||
gcc_pure
|
||||
bool HasOtherThanBase() const;
|
||||
bool HasOtherThanBase() const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const LightSong &song) const;
|
||||
bool Match(const LightSong &song) const noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -127,7 +127,7 @@ public:
|
||||
|
||||
unsigned Update(const char *uri_utf8, bool discard) override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return update_stamp;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ ProxySong::ProxySong(const mpd_song *song)
|
||||
|
||||
gcc_const
|
||||
static enum mpd_tag_type
|
||||
Convert(TagType tag_type)
|
||||
Convert(TagType tag_type) noexcept
|
||||
{
|
||||
for (auto i = &tag_table[0]; i->d != TAG_NUM_OF_ITEM_TYPES; ++i)
|
||||
if (i->d == tag_type)
|
||||
@@ -574,7 +574,7 @@ Visit(struct mpd_connection *connection,
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
Match(const SongFilter *filter, const LightSong &song)
|
||||
Match(const SongFilter *filter, const LightSong &song) noexcept
|
||||
{
|
||||
return filter == nullptr || filter->Match(song);
|
||||
}
|
||||
@@ -717,7 +717,7 @@ SearchSongs(struct mpd_connection *connection,
|
||||
*/
|
||||
gcc_pure
|
||||
static bool
|
||||
ServerSupportsSearchBase(const struct mpd_connection *connection)
|
||||
ServerSupportsSearchBase(const struct mpd_connection *connection) noexcept
|
||||
{
|
||||
#if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
|
||||
return mpd_connection_cmp_server_version(connection, 0, 18, 0) >= 0;
|
||||
|
@@ -65,7 +65,7 @@ Directory::Delete()
|
||||
}
|
||||
|
||||
const char *
|
||||
Directory::GetName() const
|
||||
Directory::GetName() const noexcept
|
||||
{
|
||||
assert(!IsRoot());
|
||||
|
||||
@@ -89,7 +89,7 @@ Directory::CreateChild(const char *name_utf8)
|
||||
}
|
||||
|
||||
const Directory *
|
||||
Directory::FindChild(const char *name) const
|
||||
Directory::FindChild(const char *name) const noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
@@ -101,7 +101,7 @@ Directory::FindChild(const char *name) const
|
||||
}
|
||||
|
||||
void
|
||||
Directory::PruneEmpty()
|
||||
Directory::PruneEmpty() noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
@@ -118,7 +118,7 @@ Directory::PruneEmpty()
|
||||
}
|
||||
|
||||
Directory::LookupResult
|
||||
Directory::LookupDirectory(const char *uri)
|
||||
Directory::LookupDirectory(const char *uri) noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(uri != nullptr);
|
||||
@@ -173,7 +173,7 @@ Directory::AddSong(Song *song)
|
||||
}
|
||||
|
||||
void
|
||||
Directory::RemoveSong(Song *song)
|
||||
Directory::RemoveSong(Song *song) noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(song != nullptr);
|
||||
@@ -183,7 +183,7 @@ Directory::RemoveSong(Song *song)
|
||||
}
|
||||
|
||||
const Song *
|
||||
Directory::FindSong(const char *name_utf8) const
|
||||
Directory::FindSong(const char *name_utf8) const noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(name_utf8 != nullptr);
|
||||
@@ -200,13 +200,13 @@ Directory::FindSong(const char *name_utf8) const
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
directory_cmp(const Directory &a, const Directory &b)
|
||||
directory_cmp(const Directory &a, const Directory &b) noexcept
|
||||
{
|
||||
return IcuCollate(a.path.c_str(), b.path.c_str()) < 0;
|
||||
}
|
||||
|
||||
void
|
||||
Directory::Sort()
|
||||
Directory::Sort() noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
@@ -261,7 +261,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
|
||||
}
|
||||
|
||||
LightDirectory
|
||||
Directory::Export() const
|
||||
Directory::Export() const noexcept
|
||||
{
|
||||
return LightDirectory(GetPath(), mtime);
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ struct Directory {
|
||||
|
||||
Directory *parent;
|
||||
time_t mtime;
|
||||
unsigned inode, device;
|
||||
uint64_t inode, device;
|
||||
|
||||
std::string path;
|
||||
|
||||
@@ -134,10 +134,10 @@ public:
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
gcc_pure
|
||||
const Directory *FindChild(const char *name) const;
|
||||
const Directory *FindChild(const char *name) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
Directory *FindChild(const char *name) {
|
||||
Directory *FindChild(const char *name) noexcept {
|
||||
const Directory *cthis = this;
|
||||
return const_cast<Directory *>(cthis->FindChild(name));
|
||||
}
|
||||
@@ -177,17 +177,17 @@ public:
|
||||
* @return the Directory, or nullptr if none was found
|
||||
*/
|
||||
gcc_pure
|
||||
LookupResult LookupDirectory(const char *uri);
|
||||
LookupResult LookupDirectory(const char *uri) noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return children.empty() &&
|
||||
songs.empty() &&
|
||||
playlists.empty();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetPath() const {
|
||||
const char *GetPath() const noexcept {
|
||||
return path.c_str();
|
||||
}
|
||||
|
||||
@@ -195,13 +195,13 @@ public:
|
||||
* Returns the base name of the directory.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *GetName() const;
|
||||
const char *GetName() const noexcept;
|
||||
|
||||
/**
|
||||
* Is this the root directory of the music database?
|
||||
*/
|
||||
gcc_pure
|
||||
bool IsRoot() const {
|
||||
bool IsRoot() const noexcept {
|
||||
return parent == nullptr;
|
||||
}
|
||||
|
||||
@@ -229,10 +229,10 @@ public:
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
gcc_pure
|
||||
const Song *FindSong(const char *name_utf8) const;
|
||||
const Song *FindSong(const char *name_utf8) const noexcept;
|
||||
|
||||
gcc_pure
|
||||
Song *FindSong(const char *name_utf8) {
|
||||
Song *FindSong(const char *name_utf8) noexcept {
|
||||
const Directory *cthis = this;
|
||||
return const_cast<Song *>(cthis->FindSong(name_utf8));
|
||||
}
|
||||
@@ -248,19 +248,19 @@ public:
|
||||
* invalidates the song object, because the "parent" attribute becomes
|
||||
* stale), but does not free it.
|
||||
*/
|
||||
void RemoveSong(Song *song);
|
||||
void RemoveSong(Song *song) noexcept;
|
||||
|
||||
/**
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
void PruneEmpty();
|
||||
void PruneEmpty() noexcept;
|
||||
|
||||
/**
|
||||
* Sort all directory entries recursively.
|
||||
*
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
void Sort();
|
||||
void Sort() noexcept;
|
||||
|
||||
/**
|
||||
* Caller must lock #db_mutex.
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
VisitPlaylist visit_playlist) const;
|
||||
|
||||
gcc_pure
|
||||
LightDirectory Export() const;
|
||||
LightDirectory Export() const noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -40,7 +40,7 @@
|
||||
|
||||
gcc_const
|
||||
static const char *
|
||||
DeviceToTypeString(unsigned device)
|
||||
DeviceToTypeString(unsigned device) noexcept
|
||||
{
|
||||
switch (device) {
|
||||
case DEVICE_INARCHIVE:
|
||||
@@ -56,7 +56,7 @@ DeviceToTypeString(unsigned device)
|
||||
|
||||
gcc_pure
|
||||
static unsigned
|
||||
ParseTypeString(const char *type)
|
||||
ParseTypeString(const char *type) noexcept
|
||||
{
|
||||
if (strcmp(type, "archive") == 0)
|
||||
return DEVICE_INARCHIVE;
|
||||
|
@@ -76,7 +76,7 @@ public:
|
||||
const ConfigBlock &block);
|
||||
|
||||
gcc_pure
|
||||
Directory &GetRoot() {
|
||||
Directory &GetRoot() noexcept {
|
||||
assert(root != NULL);
|
||||
|
||||
return *root;
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
|
||||
DatabaseStats GetStats(const DatabaseSelection &selection) const override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return mtime;
|
||||
}
|
||||
|
||||
|
@@ -77,7 +77,7 @@ Song::Free()
|
||||
}
|
||||
|
||||
std::string
|
||||
Song::GetURI() const
|
||||
Song::GetURI() const noexcept
|
||||
{
|
||||
assert(*uri);
|
||||
|
||||
@@ -96,7 +96,7 @@ Song::GetURI() const
|
||||
}
|
||||
|
||||
LightSong
|
||||
Song::Export() const
|
||||
Song::Export() const noexcept
|
||||
{
|
||||
LightSong dest;
|
||||
dest.directory = parent->IsRoot()
|
||||
|
@@ -123,10 +123,10 @@ struct Song {
|
||||
* location within the music directory.
|
||||
*/
|
||||
gcc_pure
|
||||
std::string GetURI() const;
|
||||
std::string GetURI() const noexcept;
|
||||
|
||||
gcc_pure
|
||||
LightSong Export() const;
|
||||
LightSong Export() const noexcept;
|
||||
};
|
||||
|
||||
typedef boost::intrusive::list<Song,
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
static int
|
||||
compare_utf8_string(const char *a, const char *b)
|
||||
compare_utf8_string(const char *a, const char *b) noexcept
|
||||
{
|
||||
if (a == nullptr)
|
||||
return b == nullptr ? 0 : -1;
|
||||
@@ -42,8 +42,7 @@ compare_utf8_string(const char *a, const char *b)
|
||||
* nullptr.
|
||||
*/
|
||||
static int
|
||||
compare_string_tag_item(const Tag &a, const Tag &b,
|
||||
TagType type)
|
||||
compare_string_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
|
||||
{
|
||||
return compare_utf8_string(a.GetValue(type),
|
||||
b.GetValue(type));
|
||||
@@ -54,7 +53,7 @@ compare_string_tag_item(const Tag &a, const Tag &b,
|
||||
* (e.g. disc or track number). Either one may be nullptr.
|
||||
*/
|
||||
static int
|
||||
compare_number_string(const char *a, const char *b)
|
||||
compare_number_string(const char *a, const char *b) noexcept
|
||||
{
|
||||
long ai = a == nullptr ? 0 : strtol(a, nullptr, 10);
|
||||
long bi = b == nullptr ? 0 : strtol(b, nullptr, 10);
|
||||
@@ -69,7 +68,7 @@ compare_number_string(const char *a, const char *b)
|
||||
}
|
||||
|
||||
static int
|
||||
compare_tag_item(const Tag &a, const Tag &b, TagType type)
|
||||
compare_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
|
||||
{
|
||||
return compare_number_string(a.GetValue(type),
|
||||
b.GetValue(type));
|
||||
@@ -78,7 +77,7 @@ compare_tag_item(const Tag &a, const Tag &b, TagType type)
|
||||
/* Only used for sorting/searchin a songvec, not general purpose compares */
|
||||
gcc_pure
|
||||
static bool
|
||||
song_cmp(const Song &a, const Song &b)
|
||||
song_cmp(const Song &a, const Song &b) noexcept
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -102,7 +101,7 @@ song_cmp(const Song &a, const Song &b)
|
||||
}
|
||||
|
||||
void
|
||||
song_list_sort(SongList &songs)
|
||||
song_list_sort(SongList &songs) noexcept
|
||||
{
|
||||
songs.sort(song_cmp);
|
||||
}
|
||||
|
@@ -23,6 +23,6 @@
|
||||
#include "Song.hxx"
|
||||
|
||||
void
|
||||
song_list_sort(SongList &songs);
|
||||
song_list_sort(SongList &songs) noexcept;
|
||||
|
||||
#endif
|
||||
|
@@ -39,7 +39,7 @@ UPnPDirContent::~UPnPDirContent()
|
||||
|
||||
gcc_pure
|
||||
static UPnPDirObject::ItemClass
|
||||
ParseItemClass(StringView name)
|
||||
ParseItemClass(StringView name) noexcept
|
||||
{
|
||||
if (name.EqualsLiteral("object.item.audioItem.musicTrack"))
|
||||
return UPnPDirObject::ItemClass::MUSIC;
|
||||
@@ -51,7 +51,7 @@ ParseItemClass(StringView name)
|
||||
|
||||
gcc_pure
|
||||
static SignedSongTime
|
||||
ParseDuration(const char *duration)
|
||||
ParseDuration(const char *duration) noexcept
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
@@ -81,7 +81,7 @@ ParseDuration(const char *duration)
|
||||
*/
|
||||
gcc_pure
|
||||
static std::string &&
|
||||
TitleToPathSegment(std::string &&s)
|
||||
TitleToPathSegment(std::string &&s) noexcept
|
||||
{
|
||||
std::replace(s.begin(), s.end(), '/', '_');
|
||||
return std::move(s);
|
||||
|
@@ -40,7 +40,7 @@ public:
|
||||
~UPnPDirContent();
|
||||
|
||||
gcc_pure
|
||||
UPnPDirObject *FindObject(const char *name) {
|
||||
UPnPDirObject *FindObject(const char *name) noexcept {
|
||||
for (auto &o : objects)
|
||||
if (o.name == name)
|
||||
return &o;
|
||||
|
@@ -60,7 +60,7 @@ public:
|
||||
* Parent's ObjectId
|
||||
*/
|
||||
std::string parent_id;
|
||||
|
||||
|
||||
std::string url;
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
UPnPDirObject &operator=(UPnPDirObject &&) = default;
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
id.clear();
|
||||
parent_id.clear();
|
||||
url.clear();
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool Check() const {
|
||||
bool Check() const noexcept {
|
||||
return !id.empty() && !parent_id.empty() && !name.empty() &&
|
||||
(type != UPnPDirObject::Type::ITEM ||
|
||||
item_class != UPnPDirObject::ItemClass::UNKNOWN);
|
||||
|
@@ -93,7 +93,7 @@ public:
|
||||
|
||||
DatabaseStats GetStats(const DatabaseSelection &selection) const override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
ExcludeList::LoadFile(Path path_fs)
|
||||
ExcludeList::LoadFile(Path path_fs) noexcept
|
||||
try {
|
||||
#ifdef HAVE_CLASS_GLOB
|
||||
TextFile file(path_fs);
|
||||
@@ -67,7 +67,7 @@ try {
|
||||
}
|
||||
|
||||
bool
|
||||
ExcludeList::Check(Path name_fs) const
|
||||
ExcludeList::Check(Path name_fs) const noexcept
|
||||
{
|
||||
assert(!name_fs.IsNull());
|
||||
|
||||
|
@@ -50,7 +50,7 @@ public:
|
||||
:parent(&_parent) {}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
#ifdef HAVE_CLASS_GLOB
|
||||
return ((parent == nullptr) || parent->IsEmpty()) && patterns.empty();
|
||||
#else
|
||||
@@ -62,13 +62,13 @@ public:
|
||||
/**
|
||||
* Loads and parses a .mpdignore file.
|
||||
*/
|
||||
bool LoadFile(Path path_fs);
|
||||
bool LoadFile(Path path_fs) noexcept;
|
||||
|
||||
/**
|
||||
* Checks whether one of the patterns in the .mpdignore file matches
|
||||
* the specified file name.
|
||||
*/
|
||||
bool Check(Path name_fs) const;
|
||||
bool Check(Path name_fs) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -56,7 +56,7 @@ InotifyQueue::OnTimeout()
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
path_in(const char *path, const char *possible_parent)
|
||||
path_in(const char *path, const char *possible_parent) noexcept
|
||||
{
|
||||
if (StringIsEmpty(path))
|
||||
return true;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user