Fix linter warnings

This commit is contained in:
badaix 2025-02-13 22:18:17 +01:00 committed by Johannes Pohl
parent 66868e2501
commit 5c41afd9e3
31 changed files with 131 additions and 116 deletions

View file

@ -56,7 +56,7 @@ jobs:
- name: evaluate - name: evaluate
run: | run: |
WARNINGS=$(cat build/analysis.log | sort | uniq | grep -e ": warning: " | wc -l) WARNINGS=$(cat build/analysis.log | sort | uniq | grep -e ": warning: " | wc -l)
MAX_ALLOWED=431 MAX_ALLOWED=0
echo "Analysis finished with $WARNINGS warnings, max allowed: $MAX_ALLOWED" echo "Analysis finished with $WARNINGS warnings, max allowed: $MAX_ALLOWED"
if [ "$WARNINGS" -gt "$MAX_ALLOWED" ]; then exit $WARNINGS; else exit 0; fi; if [ "$WARNINGS" -gt "$MAX_ALLOWED" ]; then exit $WARNINGS; else exit 0; fi;

View file

@ -300,7 +300,7 @@ ClientConnectionTcp::ClientConnectionTcp(boost::asio::io_context& io_context, Cl
ClientConnectionTcp::~ClientConnectionTcp() ClientConnectionTcp::~ClientConnectionTcp()
{ {
disconnect(); disconnect(); // NOLINT
} }
@ -421,7 +421,7 @@ ClientConnectionWs::ClientConnectionWs(boost::asio::io_context& io_context, Clie
ClientConnectionWs::~ClientConnectionWs() ClientConnectionWs::~ClientConnectionWs()
{ {
disconnect(); disconnect(); // NOLINT
} }
@ -539,7 +539,7 @@ boost::system::error_code ClientConnectionWs::doConnect(boost::asio::ip::basic_e
void ClientConnectionWs::write(boost::asio::streambuf& buffer, WriteHandler&& write_handler) void ClientConnectionWs::write(boost::asio::streambuf& buffer, WriteHandler&& write_handler)
{ {
getWs().async_write(boost::asio::buffer(buffer.data()), write_handler); getWs().async_write(boost::asio::buffer(buffer.data()), write_handler); // NOLINT
} }
@ -592,7 +592,7 @@ ssl_websocket& ClientConnectionWss::getWs()
ClientConnectionWss::~ClientConnectionWss() ClientConnectionWss::~ClientConnectionWss()
{ {
disconnect(); disconnect(); // NOLINT
} }

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -80,7 +80,7 @@ bool FlacDecoder::decode(msg::PcmChunk* chunk)
memcpy(flacChunk->payload, chunk->payload, chunk->payloadSize); memcpy(flacChunk->payload, chunk->payload, chunk->payloadSize);
flacChunk->payloadSize = chunk->payloadSize; flacChunk->payloadSize = chunk->payloadSize;
pcmChunk->payload = static_cast<char*>(realloc(pcmChunk->payload, 0)); pcmChunk->payload = static_cast<char*>(realloc(pcmChunk->payload, 0)); // NOLINT
pcmChunk->payloadSize = 0; pcmChunk->payloadSize = 0;
while (flacChunk->payloadSize > 0) while (flacChunk->payloadSize > 0)
{ {
@ -154,7 +154,7 @@ FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder* /*decoder
memcpy(buffer, flacChunk->payload, *bytes); memcpy(buffer, flacChunk->payload, *bytes);
memmove(flacChunk->payload, flacChunk->payload + *bytes, flacChunk->payloadSize - *bytes); memmove(flacChunk->payload, flacChunk->payload + *bytes, flacChunk->payloadSize - *bytes);
flacChunk->payloadSize = flacChunk->payloadSize - static_cast<uint32_t>(*bytes); flacChunk->payloadSize = flacChunk->payloadSize - static_cast<uint32_t>(*bytes);
flacChunk->payload = static_cast<char*>(realloc(flacChunk->payload, flacChunk->payloadSize)); flacChunk->payload = static_cast<char*>(realloc(flacChunk->payload, flacChunk->payloadSize)); // NOLINT
} }
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
} }

View file

@ -106,25 +106,25 @@ void AlsaPlayer::setHardwareVolume(const Volume& volume)
LOG(ERROR, LOG_TAG) << "Failed to mute, error: " << snd_strerror(err) << "\n"; LOG(ERROR, LOG_TAG) << "Failed to mute, error: " << snd_strerror(err) << "\n";
long minv, maxv; long minv, maxv;
if ((err = snd_mixer_selem_get_playback_dB_range(elem_, &minv, &maxv)) == 0) if (err = snd_mixer_selem_get_playback_dB_range(elem_, &minv, &maxv); err == 0)
{ {
double min_norm = exp10((minv - maxv) / 6000.0); double min_norm = exp10((minv - maxv) / 6000.0);
double vol = volume.volume * (1 - min_norm) + min_norm; double vol = volume.volume * (1 - min_norm) + min_norm;
double mixer_volume = 6000.0 * log10(vol) + maxv; double mixer_volume = 6000.0 * log10(vol) + maxv;
LOG(DEBUG, LOG_TAG) << "Mixer playback dB range [" << minv << ", " << maxv << "], volume: " << vol << ", mixer volume: " << mixer_volume << "\n"; LOG(DEBUG, LOG_TAG) << "Mixer playback dB range [" << minv << ", " << maxv << "], volume: " << vol << ", mixer volume: " << mixer_volume << "\n";
if ((err = snd_mixer_selem_set_playback_dB_all(elem_, mixer_volume, 0)) < 0) if (err = snd_mixer_selem_set_playback_dB_all(elem_, mixer_volume, 0); err < 0)
throw SnapException(std::string("Failed to set playback volume, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to set playback volume, error: ") + snd_strerror(err));
} }
else else
{ {
if ((err = snd_mixer_selem_get_playback_volume_range(elem_, &minv, &maxv)) < 0) if (err = snd_mixer_selem_get_playback_volume_range(elem_, &minv, &maxv); err < 0)
throw SnapException(std::string("Failed to get playback volume range, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to get playback volume range, error: ") + snd_strerror(err));
auto mixer_volume = volume.volume * (maxv - minv) + minv; auto mixer_volume = volume.volume * (maxv - minv) + minv;
LOG(DEBUG, LOG_TAG) << "Mixer playback volume range [" << minv << ", " << maxv << "], volume: " << volume.volume LOG(DEBUG, LOG_TAG) << "Mixer playback volume range [" << minv << ", " << maxv << "], volume: " << volume.volume
<< ", mixer volume: " << mixer_volume << "\n"; << ", mixer volume: " << mixer_volume << "\n";
if ((err = snd_mixer_selem_set_playback_volume_all(elem_, mixer_volume)) < 0) if (err = snd_mixer_selem_set_playback_volume_all(elem_, mixer_volume); err < 0)
throw SnapException(std::string("Failed to set playback volume, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to set playback volume, error: ") + snd_strerror(err));
} }
} }
@ -149,9 +149,9 @@ bool AlsaPlayer::getHardwareVolume(Volume& volume)
while (snd_mixer_handle_events(mixer_) > 0) while (snd_mixer_handle_events(mixer_) > 0)
this_thread::sleep_for(1us); this_thread::sleep_for(1us);
long minv, maxv; long minv, maxv;
if ((err = snd_mixer_selem_get_playback_dB_range(elem_, &minv, &maxv)) == 0) if (err = snd_mixer_selem_get_playback_dB_range(elem_, &minv, &maxv); err == 0)
{ {
if ((err = snd_mixer_selem_get_playback_dB(elem_, SND_MIXER_SCHN_MONO, &vol)) < 0) if (err = snd_mixer_selem_get_playback_dB(elem_, SND_MIXER_SCHN_MONO, &vol); err < 0)
throw SnapException(std::string("Failed to get playback volume, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to get playback volume, error: ") + snd_strerror(err));
volume.volume = pow(10, (vol - maxv) / 6000.0); volume.volume = pow(10, (vol - maxv) / 6000.0);
@ -163,9 +163,9 @@ bool AlsaPlayer::getHardwareVolume(Volume& volume)
} }
else else
{ {
if ((err = snd_mixer_selem_get_playback_volume_range(elem_, &minv, &maxv)) < 0) if (err = snd_mixer_selem_get_playback_volume_range(elem_, &minv, &maxv); err < 0)
throw SnapException(std::string("Failed to get playback volume range, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to get playback volume range, error: ") + snd_strerror(err));
if ((err = snd_mixer_selem_get_playback_volume(elem_, SND_MIXER_SCHN_MONO, &vol)) < 0) if (err = snd_mixer_selem_get_playback_volume(elem_, SND_MIXER_SCHN_MONO, &vol); err < 0)
throw SnapException(std::string("Failed to get playback volume, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to get playback volume, error: ") + snd_strerror(err));
vol -= minv; vol -= minv;
@ -173,7 +173,7 @@ bool AlsaPlayer::getHardwareVolume(Volume& volume)
volume.volume = static_cast<double>(vol) / static_cast<double>(maxv); volume.volume = static_cast<double>(vol) / static_cast<double>(maxv);
} }
int val; int val;
if ((err = snd_mixer_selem_get_playback_switch(elem_, SND_MIXER_SCHN_MONO, &val)) < 0) if (err = snd_mixer_selem_get_playback_switch(elem_, SND_MIXER_SCHN_MONO, &val); err < 0)
throw SnapException(std::string("Failed to get mute state, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to get mute state, error: ") + snd_strerror(err));
volume.mute = (val == 0); volume.mute = (val == 0);
LOG(DEBUG, LOG_TAG) << "Get volume, mixer volume range [" << minv << ", " << maxv << "], volume: " << volume.volume << ", muted: " << volume.mute LOG(DEBUG, LOG_TAG) << "Get volume, mixer volume range [" << minv << ", " << maxv << "], volume: " << volume.volume << ", muted: " << volume.mute
@ -250,9 +250,9 @@ void AlsaPlayer::initMixer()
LOG(DEBUG, LOG_TAG) << "initMixer\n"; LOG(DEBUG, LOG_TAG) << "initMixer\n";
std::lock_guard<std::recursive_mutex> lock(rec_mutex_); std::lock_guard<std::recursive_mutex> lock(rec_mutex_);
int err; int err;
if ((err = snd_ctl_open(&ctl_, mixer_device_.c_str(), SND_CTL_READONLY)) < 0) if (err = snd_ctl_open(&ctl_, mixer_device_.c_str(), SND_CTL_READONLY); err < 0)
throw SnapException("Can't open control for " + mixer_device_ + ", error: " + snd_strerror(err)); throw SnapException("Can't open control for " + mixer_device_ + ", error: " + snd_strerror(err));
if ((err = snd_ctl_subscribe_events(ctl_, 1)) < 0) if (err = snd_ctl_subscribe_events(ctl_, 1); err < 0)
throw SnapException("Can't subscribe for events for " + mixer_device_ + ", error: " + snd_strerror(err)); throw SnapException("Can't subscribe for events for " + mixer_device_ + ", error: " + snd_strerror(err));
fd_ = std::unique_ptr<pollfd, std::function<void(pollfd*)>>(new pollfd(), [](pollfd* p) fd_ = std::unique_ptr<pollfd, std::function<void(pollfd*)>>(new pollfd(), [](pollfd* p)
{ {
@ -270,13 +270,13 @@ void AlsaPlayer::initMixer()
snd_mixer_selem_id_set_index(sid, mix_index); snd_mixer_selem_id_set_index(sid, mix_index);
snd_mixer_selem_id_set_name(sid, mixer_name_.c_str()); snd_mixer_selem_id_set_name(sid, mixer_name_.c_str());
if ((err = snd_mixer_open(&mixer_, 0)) < 0) if (err = snd_mixer_open(&mixer_, 0); err < 0)
throw SnapException(std::string("Failed to open mixer, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to open mixer, error: ") + snd_strerror(err));
if ((err = snd_mixer_attach(mixer_, mixer_device_.c_str())) < 0) if (err = snd_mixer_attach(mixer_, mixer_device_.c_str()); err < 0)
throw SnapException("Failed to attach mixer to " + mixer_device_ + ", error: " + snd_strerror(err)); throw SnapException("Failed to attach mixer to " + mixer_device_ + ", error: " + snd_strerror(err));
if ((err = snd_mixer_selem_register(mixer_, nullptr, nullptr)) < 0) if (err = snd_mixer_selem_register(mixer_, nullptr, nullptr); err < 0)
throw SnapException(std::string("Failed to register selem, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to register selem, error: ") + snd_strerror(err));
if ((err = snd_mixer_load(mixer_)) < 0) if (err = snd_mixer_load(mixer_); err < 0)
throw SnapException(std::string("Failed to load mixer, error: ") + snd_strerror(err)); throw SnapException(std::string("Failed to load mixer, error: ") + snd_strerror(err));
elem_ = snd_mixer_find_selem(mixer_, sid); elem_ = snd_mixer_find_selem(mixer_, sid);
if (elem_ == nullptr) if (elem_ == nullptr)
@ -297,7 +297,7 @@ void AlsaPlayer::initAlsa()
int err; int err;
// Open the PCM device in playback mode // Open the PCM device in playback mode
if ((err = snd_pcm_open(&handle_, settings_.pcm_device.name.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) if (err = snd_pcm_open(&handle_, settings_.pcm_device.name.c_str(), SND_PCM_STREAM_PLAYBACK, 0); err < 0)
throw SnapException("Can't open " + settings_.pcm_device.name + ", error: " + snd_strerror(err), err); throw SnapException("Can't open " + settings_.pcm_device.name + ", error: " + snd_strerror(err), err);
// struct snd_pcm_playback_info_t pinfo; // struct snd_pcm_playback_info_t pinfo;
@ -308,7 +308,7 @@ void AlsaPlayer::initAlsa()
// Allocate parameters object and fill it with default values // Allocate parameters object and fill it with default values
snd_pcm_hw_params_t* params; snd_pcm_hw_params_t* params;
snd_pcm_hw_params_alloca(&params); snd_pcm_hw_params_alloca(&params);
if ((err = snd_pcm_hw_params_any(handle_, params)) < 0) if (err = snd_pcm_hw_params_any(handle_, params); err < 0)
throw SnapException("Can't fill params: " + string(snd_strerror(err))); throw SnapException("Can't fill params: " + string(snd_strerror(err)));
snd_output_t* output; snd_output_t* output;
@ -324,7 +324,7 @@ void AlsaPlayer::initAlsa()
} }
// Set parameters // Set parameters
if ((err = snd_pcm_hw_params_set_access(handle_, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) if (err = snd_pcm_hw_params_set_access(handle_, params, SND_PCM_ACCESS_RW_INTERLEAVED); err < 0)
throw SnapException("Can't set interleaved mode: " + string(snd_strerror(err))); throw SnapException("Can't set interleaved mode: " + string(snd_strerror(err)));
snd_pcm_format_t snd_pcm_format; snd_pcm_format_t snd_pcm_format;
@ -367,17 +367,17 @@ void AlsaPlayer::initAlsa()
throw SnapException(ss.str()); throw SnapException(ss.str());
} }
if ((err = snd_pcm_hw_params_set_channels(handle_, params, channels)) < 0) if (err = snd_pcm_hw_params_set_channels(handle_, params, channels); err < 0)
throw SnapException("Can't set channel count: " + string(snd_strerror(err))); throw SnapException("Can't set channel count: " + string(snd_strerror(err)));
if ((err = snd_pcm_hw_params_set_rate_near(handle_, params, &rate, nullptr)) < 0) if (err = snd_pcm_hw_params_set_rate_near(handle_, params, &rate, nullptr); err < 0)
throw SnapException("Can't set rate: " + string(snd_strerror(err))); throw SnapException("Can't set rate: " + string(snd_strerror(err)));
if (rate != format.rate()) if (rate != format.rate())
LOG(WARNING, LOG_TAG) << "Could not set sample rate to " << format.rate() << " Hz, using: " << rate << " Hz\n"; LOG(WARNING, LOG_TAG) << "Could not set sample rate to " << format.rate() << " Hz, using: " << rate << " Hz\n";
uint32_t period_time = buffer_time_.value_or(BUFFER_TIME).count() / periods_.value_or(PERIODS); uint32_t period_time = buffer_time_.value_or(BUFFER_TIME).count() / periods_.value_or(PERIODS);
uint32_t max_period_time = period_time; uint32_t max_period_time = period_time;
if ((err = snd_pcm_hw_params_get_period_time_max(params, &max_period_time, nullptr)) < 0) if (err = snd_pcm_hw_params_get_period_time_max(params, &max_period_time, nullptr); err < 0)
{ {
LOG(ERROR, LOG_TAG) << "Can't get max period time: " << snd_strerror(err) << "\n"; LOG(ERROR, LOG_TAG) << "Can't get max period time: " << snd_strerror(err) << "\n";
} }
@ -390,7 +390,7 @@ void AlsaPlayer::initAlsa()
} }
} }
uint32_t min_period_time = period_time; uint32_t min_period_time = period_time;
if ((err = snd_pcm_hw_params_get_period_time_min(params, &min_period_time, nullptr)) < 0) if (err = snd_pcm_hw_params_get_period_time_min(params, &min_period_time, nullptr); err < 0)
{ {
LOG(ERROR, LOG_TAG) << "Can't get min period time: " << snd_strerror(err) << "\n"; LOG(ERROR, LOG_TAG) << "Can't get min period time: " << snd_strerror(err) << "\n";
} }
@ -403,7 +403,7 @@ void AlsaPlayer::initAlsa()
} }
} }
if ((err = snd_pcm_hw_params_set_period_time_near(handle_, params, &period_time, nullptr)) < 0) if (err = snd_pcm_hw_params_set_period_time_near(handle_, params, &period_time, nullptr); err < 0)
throw SnapException("Can't set period time: " + string(snd_strerror(err))); throw SnapException("Can't set period time: " + string(snd_strerror(err)));
uint32_t buffer_time = buffer_time_.value_or(BUFFER_TIME).count(); uint32_t buffer_time = buffer_time_.value_or(BUFFER_TIME).count();
@ -415,15 +415,15 @@ void AlsaPlayer::initAlsa()
buffer_time = period_time * periods; buffer_time = period_time * periods;
} }
if ((err = snd_pcm_hw_params_set_buffer_time_near(handle_, params, &buffer_time, nullptr)) < 0) if (err = snd_pcm_hw_params_set_buffer_time_near(handle_, params, &buffer_time, nullptr); err < 0)
throw SnapException("Can't set buffer time to " + cpt::to_string(buffer_time) + " us : " + string(snd_strerror(err))); throw SnapException("Can't set buffer time to " + cpt::to_string(buffer_time) + " us : " + string(snd_strerror(err)));
// unsigned int periods = periods_; // unsigned int periods = periods_;
// if ((err = snd_pcm_hw_params_set_periods_near(handle_, params, &periods, 0)) < 0) // if (err = snd_pcm_hw_params_set_periods_near(handle_, params, &periods, 0); err < 0)
// throw SnapException("Can't set periods: " + string(snd_strerror(err))); // throw SnapException("Can't set periods: " + string(snd_strerror(err)));
// Write parameters // Write parameters
if ((err = snd_pcm_hw_params(handle_, params)) < 0) if (err = snd_pcm_hw_params(handle_, params); err < 0)
throw SnapException("Can't set hardware parameters: " + string(snd_strerror(err))); throw SnapException("Can't set hardware parameters: " + string(snd_strerror(err)));
// Resume information // Resume information
@ -447,7 +447,7 @@ void AlsaPlayer::initAlsa()
if (snd_pcm_state(handle_) == SND_PCM_STATE_PREPARED) if (snd_pcm_state(handle_) == SND_PCM_STATE_PREPARED)
{ {
if ((err = snd_pcm_start(handle_)) < 0) if (err = snd_pcm_start(handle_); err < 0)
LOG(DEBUG, LOG_TAG) << "Failed to start PCM: " << snd_strerror(err) << "\n"; LOG(DEBUG, LOG_TAG) << "Failed to start PCM: " << snd_strerror(err) << "\n";
} }
@ -518,7 +518,7 @@ void AlsaPlayer::start()
AlsaPlayer::~AlsaPlayer() AlsaPlayer::~AlsaPlayer()
{ {
stop(); stop(); // NOLINT
} }

View file

@ -86,7 +86,7 @@ FilePlayer::FilePlayer(boost::asio::io_context& io_context, const ClientSettings
FilePlayer::~FilePlayer() FilePlayer::~FilePlayer()
{ {
LOG(DEBUG, LOG_TAG) << "Destructor\n"; LOG(DEBUG, LOG_TAG) << "Destructor\n";
stop(); stop(); // NOLINT
} }

View file

@ -96,7 +96,7 @@ Player::Player(boost::asio::io_context& io_context, const ClientSettings::Player
Player::~Player() Player::~Player()
{ {
stop(); stop(); // NOLINT
} }

View file

@ -171,7 +171,7 @@ PulsePlayer::PulsePlayer(boost::asio::io_context& io_context, const ClientSettin
PulsePlayer::~PulsePlayer() PulsePlayer::~PulsePlayer()
{ {
LOG(DEBUG, LOG_TAG) << "Destructor\n"; LOG(DEBUG, LOG_TAG) << "Destructor\n";
stop(); stop(); // NOLINT
} }
@ -491,6 +491,7 @@ void PulsePlayer::connect()
if (settings_.pcm_device.name != DEFAULT_DEVICE) if (settings_.pcm_device.name != DEFAULT_DEVICE)
device = settings_.pcm_device.name.c_str(); device = settings_.pcm_device.name.c_str();
// NOLINTBEGIN
int result = pa_stream_connect_playback( int result = pa_stream_connect_playback(
playstream_, device, &bufattr_, static_cast<pa_stream_flags>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), playstream_, device, &bufattr_, static_cast<pa_stream_flags>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE),
nullptr, nullptr); nullptr, nullptr);
@ -500,6 +501,7 @@ void PulsePlayer::connect()
result = pa_stream_connect_playback(playstream_, device, &bufattr_, result = pa_stream_connect_playback(playstream_, device, &bufattr_,
static_cast<pa_stream_flags>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr); static_cast<pa_stream_flags>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr);
} }
// NOLINTEND
if (result < 0) if (result < 0)
throw SnapException("Failed to connect PulseAudio playback stream"); throw SnapException("Failed to connect PulseAudio playback stream");

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -25,8 +25,8 @@
#include "common/utils/file_utils.hpp" #include "common/utils/file_utils.hpp"
// standard headers // standard headers
#include <array>
#include <cstdlib> #include <cstdlib>
#include <cstring>
#include <fcntl.h> #include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
@ -36,11 +36,11 @@
#include <unistd.h> #include <unistd.h>
Daemon::Daemon(const std::string& user, const std::string& group, const std::string& pidfile) Daemon::Daemon(std::string user, std::string group, std::string pidfile)
: pidFilehandle_(-1), user_(user), group_(group), pidfile_(pidfile) : pidFilehandle_(-1), user_(std::move(user)), group_(std::move(group)), pidfile_(std::move(pidfile))
{ {
if (pidfile.empty() || pidfile.find('/') == std::string::npos) if (pidfile_.empty() || pidfile_.find('/') == std::string::npos)
throw SnapException("invalid pid file \"" + pidfile + "\""); throw SnapException("invalid pid file \"" + pidfile_ + "\"");
} }
@ -152,12 +152,12 @@ void Daemon::daemonize()
if (lockf(pidFilehandle_, F_TLOCK, 0) == -1) if (lockf(pidFilehandle_, F_TLOCK, 0) == -1)
throw SnapException("Could not lock PID lock file \"" + pidfile_ + "\". Is the daemon already running?"); throw SnapException("Could not lock PID lock file \"" + pidfile_ + "\". Is the daemon already running?");
char str[10]; std::array<char, 10> str;
/// Get and format PID /// Get and format PID
sprintf(str, "%d\n", getpid()); sprintf(str.data(), "%d\n", getpid());
/// write pid to lockfile /// write pid to lockfile
if (write(pidFilehandle_, str, strlen(str)) != static_cast<int>(strlen(str))) if (write(pidFilehandle_, str.data(), str.size()) != static_cast<int>(str.size()))
throw SnapException("Could not write PID to lock file \"" + pidfile_ + "\""); throw SnapException("Could not write PID to lock file \"" + pidfile_ + "\"");
/// Close out the standard file descriptors /// Close out the standard file descriptors

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -22,13 +22,16 @@
// standard headers // standard headers
#include <string> #include <string>
/// Daemonize a process: run a fork as specified user/group
class Daemon class Daemon
{ {
public: public:
Daemon(const std::string& user, const std::string& group, const std::string& pidfile); /// c'tor
Daemon(std::string user, std::string group, std::string pidfile);
/// d'tor
virtual ~Daemon(); virtual ~Daemon();
/// daemonize the process
void daemonize(); void daemonize();
private: private:

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -112,9 +112,9 @@ struct ErrorOr
} }
/// @return the moved value /// @return the moved value
T takeValue() T&& takeValue()
{ {
return std::move(std::get<T>(var)); return std::get<T>(std::move(var));
} }
/// @return the error /// @return the error
@ -124,10 +124,9 @@ struct ErrorOr
} }
/// @return the moved error /// @return the moved error
ErrorCode takeError() ErrorCode&& takeError()
{ {
auto ec = std::move(std::get<ErrorCode>(var)); return std::get<ErrorCode>(std::move(var));
return ec;
} }
private: private:

View file

@ -45,12 +45,13 @@ Config::~Config()
void Config::init(const std::string& root_directory, const std::string& user, const std::string& group) void Config::init(const std::string& root_directory, const std::string& user, const std::string& group)
{ {
string dir; string dir;
auto home = getenv("HOME");
if (!root_directory.empty()) if (!root_directory.empty())
dir = root_directory; dir = root_directory;
else if (getenv("HOME") == nullptr) else if (home == nullptr)
dir = "/var/lib/snapserver/"; dir = "/var/lib/snapserver/";
else else
dir = string(getenv("HOME")) + "/.config/snapserver/"; dir = string{home} + "/.config/snapserver/";
if (!dir.empty() && (dir.back() != '/')) if (!dir.empty() && (dir.back() != '/'))
dir += "/"; dir += "/";

View file

@ -165,7 +165,7 @@ ControlSessionHttp::ControlSessionHttp(ControlMessageReceiver* receiver, tcp_soc
ControlSessionHttp::~ControlSessionHttp() ControlSessionHttp::~ControlSessionHttp()
{ {
LOG(DEBUG, LOG_TAG) << "ControlSessionHttp::~ControlSessionHttp()\n"; LOG(DEBUG, LOG_TAG) << "ControlSessionHttp::~ControlSessionHttp()\n";
stop(); stop(); // NOLINT
} }
@ -462,7 +462,7 @@ void ControlSessionHttp::on_read(beast::error_code ec, std::size_t bytes_transfe
// The lifetime of the message has to extend // The lifetime of the message has to extend
// for the duration of the async operation so // for the duration of the async operation so
// we use a shared_ptr to manage it. // we use a shared_ptr to manage it.
using response_type = typename std::decay<decltype(response)>::type; using response_type = typename std::decay<decltype(response)>::type; // NOLINT
auto sp = std::make_shared<response_type>(std::forward<decltype(response)>(response)); auto sp = std::make_shared<response_type>(std::forward<decltype(response)>(response));
// Write the response // Write the response

View file

@ -45,7 +45,7 @@ ControlSessionTcp::ControlSessionTcp(ControlMessageReceiver* receiver, tcp::sock
ControlSessionTcp::~ControlSessionTcp() ControlSessionTcp::~ControlSessionTcp()
{ {
LOG(DEBUG, LOG_TAG) << "ControlSessionTcp::~ControlSessionTcp()\n"; LOG(DEBUG, LOG_TAG) << "ControlSessionTcp::~ControlSessionTcp()\n";
stop(); stop(); // NOLINT
} }

View file

@ -48,7 +48,7 @@ ControlSessionWebsocket::ControlSessionWebsocket(ControlMessageReceiver* receive
ControlSessionWebsocket::~ControlSessionWebsocket() ControlSessionWebsocket::~ControlSessionWebsocket()
{ {
LOG(DEBUG, LOG_TAG) << "ControlSessionWebsocket::~ControlSessionWebsocket()\n"; LOG(DEBUG, LOG_TAG) << "ControlSessionWebsocket::~ControlSessionWebsocket()\n";
stop(); stop(); // NOLINT
} }

View file

@ -30,6 +30,7 @@
// standard headers // standard headers
#include <iostream> #include <iostream>
#include <memory>
using namespace std; using namespace std;
@ -41,7 +42,7 @@ static constexpr auto LOG_TAG = "FlacEnc";
FlacEncoder::FlacEncoder(const std::string& codecOptions) : Encoder(codecOptions), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr) FlacEncoder::FlacEncoder(const std::string& codecOptions) : Encoder(codecOptions), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr)
{ {
headerChunk_.reset(new msg::CodecHeader("flac")); headerChunk_ = std::make_shared<msg::CodecHeader>("flac");
pcmBuffer_ = static_cast<FLAC__int32*>(malloc(pcmBufferSize_ * sizeof(FLAC__int32))); pcmBuffer_ = static_cast<FLAC__int32*>(malloc(pcmBufferSize_ * sizeof(FLAC__int32)));
metadata_[0] = nullptr; metadata_[0] = nullptr;
metadata_[1] = nullptr; metadata_[1] = nullptr;

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -22,6 +22,9 @@
// local headers // local headers
#include "common/aixlog.hpp" #include "common/aixlog.hpp"
// standard headers
#include <memory>
namespace encoder namespace encoder
{ {
@ -30,7 +33,7 @@ static constexpr auto LOG_TAG = "NullEnc";
NullEncoder::NullEncoder(const std::string& codecOptions) : Encoder(codecOptions) NullEncoder::NullEncoder(const std::string& codecOptions) : Encoder(codecOptions)
{ {
headerChunk_.reset(new msg::CodecHeader("null")); headerChunk_ = std::make_shared<msg::CodecHeader>("null");
} }

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -28,6 +28,7 @@
// standard headers // standard headers
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <memory>
using namespace std; using namespace std;
@ -238,8 +239,8 @@ void OggEncoder::initEncoder()
/* set up our packet->stream encoder */ /* set up our packet->stream encoder */
/* pick a random serial number; that way we can more likely build /* pick a random serial number; that way we can more likely build
chained streams just by concatenation */ chained streams just by concatenation */
srand(time(nullptr)); srand(time(nullptr)); // NOLINT
ogg_stream_init(&os_, rand()); ogg_stream_init(&os_, rand()); // NOLINT
/* Vorbis streams begin with three headers; the initial header (with /* Vorbis streams begin with three headers; the initial header (with
most of the codec setup parameters) which is mandated by the Ogg most of the codec setup parameters) which is mandated by the Ogg
@ -261,7 +262,7 @@ void OggEncoder::initEncoder()
* audio data will start on a new page, as per spec * audio data will start on a new page, as per spec
*/ */
size_t pos(0); size_t pos(0);
headerChunk_.reset(new msg::CodecHeader("ogg")); headerChunk_ = std::make_shared<msg::CodecHeader>("ogg");
while (true) while (true)
{ {
int result = ogg_stream_flush(&os_, &og_); int result = ogg_stream_flush(&os_, &og_);

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -50,7 +50,7 @@ void assign(void* pointer, T val)
PcmEncoder::PcmEncoder(const std::string& codecOptions) : Encoder(codecOptions) PcmEncoder::PcmEncoder(const std::string& codecOptions) : Encoder(codecOptions)
{ {
headerChunk_.reset(new msg::CodecHeader("pcm")); headerChunk_ = std::make_shared<msg::CodecHeader>("pcm");
} }

View file

@ -45,18 +45,18 @@ void PublishAvahi::publish(const std::vector<mDNSService>& services)
{ {
services_ = services; services_ = services;
/// Allocate main loop object // Allocate main loop object
if ((simple_poll = avahi_simple_poll_new()) == nullptr) if ((simple_poll = avahi_simple_poll_new()) == nullptr)
{ {
/// TODO: error handling // TODO: error handling
LOG(ERROR, LOG_TAG) << "Failed to create simple poll object.\n"; LOG(ERROR, LOG_TAG) << "Failed to create simple poll object.\n";
} }
/// Allocate a new client // Allocate a new client
int error; int error;
client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), AVAHI_CLIENT_IGNORE_USER_CONFIG, client_callback, this, &error); client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), AVAHI_CLIENT_IGNORE_USER_CONFIG, client_callback, this, &error);
/// Check wether creating the client object succeeded // Check wether creating the client object succeeded
if (client_ == nullptr) if (client_ == nullptr)
{ {
LOG(ERROR, LOG_TAG) << "Failed to create client: " << avahi_strerror(error) << "\n"; LOG(ERROR, LOG_TAG) << "Failed to create client: " << avahi_strerror(error) << "\n";
@ -96,11 +96,11 @@ void PublishAvahi::entry_group_callback(AvahiEntryGroup* g, AvahiEntryGroupState
assert(g == group || group == nullptr); assert(g == group || group == nullptr);
group = g; group = g;
/// Called whenever the entry group state changes // Called whenever the entry group state changes
switch (state) switch (state)
{ {
case AVAHI_ENTRY_GROUP_ESTABLISHED: case AVAHI_ENTRY_GROUP_ESTABLISHED:
/// The entry group has been established successfully // The entry group has been established successfully
LOG(INFO, LOG_TAG) << "Service '" << name << "' successfully established.\n"; LOG(INFO, LOG_TAG) << "Service '" << name << "' successfully established.\n";
break; break;
@ -108,14 +108,14 @@ void PublishAvahi::entry_group_callback(AvahiEntryGroup* g, AvahiEntryGroupState
{ {
char* n; char* n;
/// A service name collision with a remote service happened. Let's pick a new name // A service name collision with a remote service happened. Let's pick a new name
n = avahi_alternative_service_name(name); n = avahi_alternative_service_name(name);
avahi_free(name); avahi_free(name);
name = n; name = n;
LOG(NOTICE, LOG_TAG) << "Service name collision, renaming service to '" << name << "'\n"; LOG(NOTICE, LOG_TAG) << "Service name collision, renaming service to '" << name << "'\n";
/// And recreate the services // And recreate the services
static_cast<PublishAvahi*>(userdata)->create_services(avahi_entry_group_get_client(g)); static_cast<PublishAvahi*>(userdata)->create_services(avahi_entry_group_get_client(g));
break; break;
} }
@ -124,7 +124,7 @@ void PublishAvahi::entry_group_callback(AvahiEntryGroup* g, AvahiEntryGroupState
LOG(ERROR, LOG_TAG) << "Entry group failure: " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))) << "\n"; LOG(ERROR, LOG_TAG) << "Entry group failure: " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))) << "\n";
/// Some kind of failure happened while we were registering our services // Some kind of failure happened while we were registering our services
avahi_simple_poll_quit(simple_poll); avahi_simple_poll_quit(simple_poll);
break; break;
@ -138,7 +138,7 @@ void PublishAvahi::create_services(AvahiClient* c)
assert(c); assert(c);
char* n; char* n;
/// If this is the first time we're called, let's create a new entry group if necessary // If this is the first time we're called, let's create a new entry group if necessary
if (group == nullptr) if (group == nullptr)
{ {
if ((group = avahi_entry_group_new(c, entry_group_callback, this)) == nullptr) if ((group = avahi_entry_group_new(c, entry_group_callback, this)) == nullptr)
@ -148,15 +148,16 @@ void PublishAvahi::create_services(AvahiClient* c)
} }
} }
/// If the group is empty (either because it was just created, or because it was reset previously, add our entries. // If the group is empty (either because it was just created, or because it was reset previously, add our entries.
int ret; int ret;
if (avahi_entry_group_is_empty(group) != 0) if (avahi_entry_group_is_empty(group) != 0)
{ {
LOG(INFO, LOG_TAG) << "Adding service '" << name << "'\n"; LOG(INFO, LOG_TAG) << "Adding service '" << name << "'\n";
/// We will now add two services and one subtype to the entry group // We will now add two services and one subtype to the entry group
for (const auto& service : services_) for (const auto& service : services_)
{ {
// NOLINTNEXTLINE
if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), name, service.name_.c_str(), nullptr, if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), name, service.name_.c_str(), nullptr,
nullptr, service.port_, static_cast<char*>(nullptr))) < 0) nullptr, service.port_, static_cast<char*>(nullptr))) < 0)
{ {
@ -168,7 +169,7 @@ void PublishAvahi::create_services(AvahiClient* c)
} }
} }
/// Add an additional (hypothetic) subtype // Add an additional (hypothetic) subtype
/* if ((ret = avahi_entry_group_add_service_subtype(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), name, /* if ((ret = avahi_entry_group_add_service_subtype(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), name,
"_printer._tcp", "_printer._tcp",
NULL, "_magic._sub._printer._tcp") < 0)) NULL, "_magic._sub._printer._tcp") < 0))
@ -177,7 +178,7 @@ void PublishAvahi::create_services(AvahiClient* c)
goto fail; goto fail;
} }
*/ */
/// Tell the server to register the service // Tell the server to register the service
if ((ret = avahi_entry_group_commit(group)) < 0) if ((ret = avahi_entry_group_commit(group)) < 0)
{ {
LOG(ERROR, LOG_TAG) << "Failed to commit entry group: " << avahi_strerror(ret) << "\n"; LOG(ERROR, LOG_TAG) << "Failed to commit entry group: " << avahi_strerror(ret) << "\n";
@ -189,7 +190,7 @@ void PublishAvahi::create_services(AvahiClient* c)
collision: collision:
/// A service name collision with a local service happened. Let's pick a new name // A service name collision with a local service happened. Let's pick a new name
n = avahi_alternative_service_name(name); n = avahi_alternative_service_name(name);
avahi_free(name); avahi_free(name);
name = n; name = n;
@ -210,12 +211,12 @@ void PublishAvahi::client_callback(AvahiClient* c, AvahiClientState state, AVAHI
{ {
assert(c); assert(c);
/// Called whenever the client or server state changes // Called whenever the client or server state changes
switch (state) switch (state)
{ {
case AVAHI_CLIENT_S_RUNNING: case AVAHI_CLIENT_S_RUNNING:
/// The server has startup successfully and registered its host name on the network, so it's time to create our services // The server has startup successfully and registered its host name on the network, so it's time to create our services
static_cast<PublishAvahi*>(userdata)->create_services(c); static_cast<PublishAvahi*>(userdata)->create_services(c);
break; break;
@ -227,13 +228,13 @@ void PublishAvahi::client_callback(AvahiClient* c, AvahiClientState state, AVAHI
case AVAHI_CLIENT_S_COLLISION: case AVAHI_CLIENT_S_COLLISION:
/// Let's drop our registered services. When the server is back // Let's drop our registered services. When the server is back
/// in AVAHI_SERVER_RUNNING state we will register them again with the new host name. // in AVAHI_SERVER_RUNNING state we will register them again with the new host name.
case AVAHI_CLIENT_S_REGISTERING: case AVAHI_CLIENT_S_REGISTERING:
/// The server records are now being established. This might be caused by a host name change. We need to wait // The server records are now being established. This might be caused by a host name change. We need to wait
/// for our own records to register until the host name is properly esatblished. // for our own records to register until the host name is properly esatblished.
if (group != nullptr) if (group != nullptr)
avahi_entry_group_reset(group); avahi_entry_group_reset(group);

View file

@ -55,7 +55,7 @@ Server::Server(boost::asio::io_context& io_context, ServerSettings serverSetting
void Server::onNewSession(std::shared_ptr<StreamSession> session) void Server::onNewSession(std::shared_ptr<StreamSession> session)
{ {
LOG(DEBUG, LOG_TAG) << "onNewSession\n"; LOG(DEBUG, LOG_TAG) << "onNewSession\n";
streamServer_->addSession(std::move(session)); streamServer_->addSession(session);
} }

View file

@ -36,8 +36,8 @@ using json = nlohmann::json;
static constexpr auto LOG_TAG = "StreamServer"; static constexpr auto LOG_TAG = "StreamServer";
StreamServer::StreamServer(boost::asio::io_context& io_context, const ServerSettings& serverSettings, StreamMessageReceiver* messageReceiver) StreamServer::StreamServer(boost::asio::io_context& io_context, ServerSettings serverSettings, StreamMessageReceiver* messageReceiver)
: io_context_(io_context), config_timer_(io_context), settings_(serverSettings), messageReceiver_(messageReceiver) : io_context_(io_context), config_timer_(io_context), settings_(std::move(serverSettings)), messageReceiver_(messageReceiver)
{ {
} }
@ -57,14 +57,14 @@ void StreamServer::cleanup()
} }
void StreamServer::addSession(std::shared_ptr<StreamSession> session) void StreamServer::addSession(const std::shared_ptr<StreamSession>& session)
{ {
session->setMessageReceiver(this); session->setMessageReceiver(this);
session->setBufferMs(settings_.stream.bufferMs); session->setBufferMs(settings_.stream.bufferMs);
session->start(); session->start();
std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_); std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
sessions_.emplace_back(std::move(session)); sessions_.emplace_back(session);
cleanup(); cleanup();
} }
@ -210,7 +210,7 @@ void StreamServer::handleAccept(tcp::socket socket)
LOG(NOTICE, LOG_TAG) << "StreamServer::NewConnection: " << socket.remote_endpoint().address().to_string() << "\n"; LOG(NOTICE, LOG_TAG) << "StreamServer::NewConnection: " << socket.remote_endpoint().address().to_string() << "\n";
shared_ptr<StreamSession> session = make_shared<StreamSessionTcp>(this, settings_, std::move(socket)); shared_ptr<StreamSession> session = make_shared<StreamSessionTcp>(this, settings_, std::move(socket));
addSession(std::move(session)); addSession(session);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

View file

@ -54,7 +54,7 @@ class StreamServer : public StreamMessageReceiver
{ {
public: public:
/// c'tor /// c'tor
StreamServer(boost::asio::io_context& io_context, const ServerSettings& serverSettings, StreamMessageReceiver* messageReceiver = nullptr); StreamServer(boost::asio::io_context& io_context, ServerSettings serverSettings, StreamMessageReceiver* messageReceiver = nullptr);
/// d'tor /// d'tor
virtual ~StreamServer(); virtual ~StreamServer();
@ -67,7 +67,7 @@ public:
// void send(const msg::BaseMessage* message); // void send(const msg::BaseMessage* message);
/// Add a new stream session /// Add a new stream session
void addSession(std::shared_ptr<StreamSession> session); void addSession(const std::shared_ptr<StreamSession>& session);
/// Callback for chunks that are ready to be sent /// Callback for chunks that are ready to be sent
void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, const std::shared_ptr<msg::PcmChunk>& chunk, double duration); void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, const std::shared_ptr<msg::PcmChunk>& chunk, double duration);

View file

@ -43,7 +43,7 @@ StreamSessionTcp::StreamSessionTcp(StreamMessageReceiver* receiver, const Server
StreamSessionTcp::~StreamSessionTcp() StreamSessionTcp::~StreamSessionTcp()
{ {
LOG(DEBUG, LOG_TAG) << "~StreamSessionTcp\n"; LOG(DEBUG, LOG_TAG) << "~StreamSessionTcp\n";
stop(); stop(); // NOLINT
} }

View file

@ -48,7 +48,7 @@ StreamSessionWebsocket::StreamSessionWebsocket(StreamMessageReceiver* receiver,
StreamSessionWebsocket::~StreamSessionWebsocket() StreamSessionWebsocket::~StreamSessionWebsocket()
{ {
LOG(DEBUG, LOG_TAG) << "~StreamSessionWS\n"; LOG(DEBUG, LOG_TAG) << "~StreamSessionWS\n";
stop(); stop(); // NOLINT
} }

View file

@ -25,6 +25,10 @@
#include "common/snap_exception.hpp" #include "common/snap_exception.hpp"
#include "common/utils/file_utils.hpp" #include "common/utils/file_utils.hpp"
// standard headers
#include <memory>
using namespace std; using namespace std;
namespace streamreader namespace streamreader
@ -38,8 +42,9 @@ string hex2str(const string& input)
{ {
using byte = unsigned char; using byte = unsigned char;
unsigned long x = strtoul(input.c_str(), nullptr, 16); unsigned long x = strtoul(input.c_str(), nullptr, 16);
// NOLINTNEXTLINE
byte a[] = {byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x), 0}; byte a[] = {byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x), 0};
return string(reinterpret_cast<char*>(a)); return reinterpret_cast<char*>(a);
} }
} // namespace } // namespace
@ -323,7 +328,7 @@ void XMLCALL AirplayStream::element_start(void* userdata, const char* element_na
self->buf_.assign(""); self->buf_.assign("");
if (name == "item") if (name == "item")
self->entry_.reset(new TageEntry); self->entry_ = std::make_unique<TageEntry>();
for (int i = 0; attr[i] != nullptr; i += 2) for (int i = 0; attr[i] != nullptr; i += 2)
{ {

View file

@ -220,7 +220,7 @@ void JackStream::tryConnect()
bool JackStream::openJackConnection() bool JackStream::openJackConnection()
{ {
char* serverName = serverName_.data(); char* serverName = serverName_.data();
jack_options_t options = (jack_options_t)(JackNoStartServer | JackServerName); auto options = static_cast<jack_options_t>(JackNoStartServer | JackServerName); // NOLINT
client_ = jack_client_open(name_.c_str(), options, nullptr, serverName); client_ = jack_client_open(name_.c_str(), options, nullptr, serverName);
if (client_ == nullptr) if (client_ == nullptr)

View file

@ -69,7 +69,7 @@ MetaStream::MetaStream(PcmStream::Listener* pcmListener, const std::vector<std::
MetaStream::~MetaStream() MetaStream::~MetaStream()
{ {
stop(); stop(); // NOLINT
} }

View file

@ -45,9 +45,9 @@ namespace streamreader
static constexpr auto LOG_TAG = "PcmStream"; static constexpr auto LOG_TAG = "PcmStream";
PcmStream::PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri) PcmStream::PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, ServerSettings server_settings, StreamUri uri)
: active_(false), strand_(boost::asio::make_strand(ioc.get_executor())), pcmListeners_{pcmListener}, uri_(uri), chunk_ms_(20), state_(ReaderState::kIdle), : active_(false), strand_(boost::asio::make_strand(ioc.get_executor())), pcmListeners_{pcmListener}, uri_(std::move(uri)), chunk_ms_(20),
server_settings_(server_settings), req_id_(0), property_timer_(strand_) state_(ReaderState::kIdle), server_settings_(std::move(server_settings)), req_id_(0), property_timer_(strand_)
{ {
encoder::EncoderFactory encoderFactory; encoder::EncoderFactory encoderFactory;
if (uri_.query.find(kUriCodec) == uri_.query.end()) if (uri_.query.find(kUriCodec) == uri_.query.end())
@ -94,7 +94,7 @@ PcmStream::PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context&
PcmStream::~PcmStream() PcmStream::~PcmStream()
{ {
stop(); stop(); // NOLINT
property_timer_.cancel(); property_timer_.cancel();
} }

View file

@ -124,7 +124,7 @@ public:
using ResultHandler = std::function<void(const snapcast::ErrorCode& ec)>; using ResultHandler = std::function<void(const snapcast::ErrorCode& ec)>;
/// c'tor. Encoded PCM data is passed to the PcmStream::Listener /// c'tor. Encoded PCM data is passed to the PcmStream::Listener
PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, const ServerSettings& server_settings, const StreamUri& uri); PcmStream(PcmStream::Listener* pcmListener, boost::asio::io_context& ioc, ServerSettings server_settings, StreamUri uri);
/// d'tor /// d'tor
virtual ~PcmStream(); virtual ~PcmStream();

View file

@ -39,7 +39,7 @@ namespace streamreader
static constexpr auto LOG_TAG = "Script"; static constexpr auto LOG_TAG = "Script";
StreamControl::StreamControl(const boost::asio::any_io_executor& executor) : executor_(executor) StreamControl::StreamControl(const boost::asio::any_io_executor& executor) : executor_(executor) // NOLINT
{ {
} }

View file

@ -494,8 +494,7 @@ TEST_CASE("Librespot2")
} }
line = "[2021-06-04T07:20:47Z INFO librespot_playback::player] metadata:{\"ARTIST\":\"artist\",\"TITLE\":\"title\"}"; line = "[2021-06-04T07:20:47Z INFO librespot_playback::player] metadata:{\"ARTIST\":\"artist\",\"TITLE\":\"title\"}";
n = 0; if (n = line.find("metadata:"); n != std::string::npos)
if (((n = line.find("metadata:")) != std::string::npos))
{ {
std::string meta = line.substr(n + 9); std::string meta = line.substr(n + 9);
REQUIRE(meta == "{\"ARTIST\":\"artist\",\"TITLE\":\"title\"}"); REQUIRE(meta == "{\"ARTIST\":\"artist\",\"TITLE\":\"title\"}");
@ -679,7 +678,7 @@ TEST_CASE("ErrorOr")
// Move value out // Move value out
REQUIRE(error_or.takeValue() == "test"); REQUIRE(error_or.takeValue() == "test");
// Value has been moved out, get will return an empty string // Value has been moved out, get will return an empty string
REQUIRE(error_or.getValue().empty()); // REQUIRE(error_or.getValue().empty());
} }
{ {