filter/*: use std::span instead of ConstBuffer
This commit is contained in:
parent
18ebd42c52
commit
67c6d111a8
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003-2021 The Music Player Daemon Project
|
|
||||||
* http://www.musicpd.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Filter.hxx"
|
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
ConstBuffer<void>
|
|
||||||
Filter::Flush()
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
@ -23,8 +23,8 @@
|
|||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
template<typename T> struct ConstBuffer;
|
#include <span>
|
||||||
|
|
||||||
class Filter {
|
class Filter {
|
||||||
protected:
|
protected:
|
||||||
@ -61,7 +61,7 @@ public:
|
|||||||
* invalidated by deleting this object or the next FilterPCM()
|
* invalidated by deleting this object or the next FilterPCM()
|
||||||
* or Reset() call)
|
* or Reset() call)
|
||||||
*/
|
*/
|
||||||
virtual ConstBuffer<void> FilterPCM(ConstBuffer<void> src) = 0;
|
virtual std::span<const std::byte> FilterPCM(std::span<const std::byte> src) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush pending data and return it. This should be called
|
* Flush pending data and return it. This should be called
|
||||||
@ -69,7 +69,9 @@ public:
|
|||||||
*
|
*
|
||||||
* Throws on error.
|
* Throws on error.
|
||||||
*/
|
*/
|
||||||
virtual ConstBuffer<void> Flush();
|
virtual std::span<const std::byte> Flush() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,13 +21,12 @@
|
|||||||
#define MPD_NULL_FILTER_HXX
|
#define MPD_NULL_FILTER_HXX
|
||||||
|
|
||||||
#include "filter/Filter.hxx"
|
#include "filter/Filter.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
class NullFilter final : public Filter {
|
class NullFilter final : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit NullFilter(const AudioFormat &af):Filter(af) {}
|
explicit NullFilter(const AudioFormat &af):Filter(af) {}
|
||||||
|
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override {
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override {
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "Observer.hxx"
|
#include "Observer.hxx"
|
||||||
#include "Filter.hxx"
|
#include "Filter.hxx"
|
||||||
#include "Prepared.hxx"
|
#include "Prepared.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -81,11 +80,11 @@ public:
|
|||||||
filter->Reset();
|
filter->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override {
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override {
|
||||||
return filter->FilterPCM(src);
|
return filter->FilterPCM(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void> Flush() override {
|
std::span<const std::byte> Flush() override {
|
||||||
return filter->Flush();
|
return filter->Flush();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
filter_api = static_library(
|
filter_api = static_library(
|
||||||
'filter_api',
|
'filter_api',
|
||||||
'Observer.cxx',
|
'Observer.cxx',
|
||||||
'Filter.cxx',
|
|
||||||
include_directories: inc,
|
include_directories: inc,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "filter/Prepared.hxx"
|
#include "filter/Prepared.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "pcm/Convert.hxx"
|
#include "pcm/Convert.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -50,9 +49,9 @@ public:
|
|||||||
state->Reset();
|
state->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
|
|
||||||
ConstBuffer<void> Flush() override {
|
std::span<const std::byte> Flush() override {
|
||||||
return state
|
return state
|
||||||
? state->Flush()
|
? state->Flush()
|
||||||
: std::span<const std::byte>{};
|
: std::span<const std::byte>{};
|
||||||
@ -102,8 +101,8 @@ PreparedConvertFilter::Open(AudioFormat &audio_format)
|
|||||||
return std::make_unique<ConvertFilter>(audio_format);
|
return std::make_unique<ConvertFilter>(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
ConvertFilter::FilterPCM(ConstBuffer<void> src)
|
ConvertFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
return state
|
return state
|
||||||
? state->Convert(src)
|
? state->Convert(src)
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "FfmpegFilter.hxx"
|
#include "FfmpegFilter.hxx"
|
||||||
#include "lib/ffmpeg/Interleave.hxx"
|
#include "lib/ffmpeg/Interleave.hxx"
|
||||||
#include "lib/ffmpeg/SampleFormat.hxx"
|
#include "lib/ffmpeg/SampleFormat.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavfilter/buffersrc.h>
|
#include <libavfilter/buffersrc.h>
|
||||||
@ -46,8 +45,8 @@ FfmpegFilter::FfmpegFilter(const AudioFormat &in_audio_format,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
FfmpegFilter::FilterPCM(ConstBuffer<void> src)
|
FfmpegFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
/* submit source data into the FFmpeg audio buffer source */
|
/* submit source data into the FFmpeg audio buffer source */
|
||||||
|
|
||||||
@ -55,11 +54,11 @@ FfmpegFilter::FilterPCM(ConstBuffer<void> src)
|
|||||||
frame->format = in_format;
|
frame->format = in_format;
|
||||||
frame->sample_rate = in_sample_rate;
|
frame->sample_rate = in_sample_rate;
|
||||||
frame->channels = in_channels;
|
frame->channels = in_channels;
|
||||||
frame->nb_samples = src.size / in_audio_frame_size;
|
frame->nb_samples = src.size() / in_audio_frame_size;
|
||||||
|
|
||||||
frame.GetBuffer();
|
frame.GetBuffer();
|
||||||
|
|
||||||
memcpy(frame.GetData(0), src.data, src.size);
|
memcpy(frame.GetData(0), src.data(), src.size());
|
||||||
|
|
||||||
int err = av_buffersrc_add_frame(&buffer_src, frame.get());
|
int err = av_buffersrc_add_frame(&buffer_src, frame.get());
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -72,7 +71,7 @@ FfmpegFilter::FilterPCM(ConstBuffer<void> src)
|
|||||||
err = av_buffersink_get_frame(&buffer_sink, frame.get());
|
err = av_buffersink_get_frame(&buffer_sink, frame.get());
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
|
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
|
||||||
return nullptr;
|
return {};
|
||||||
|
|
||||||
throw MakeFfmpegError(err, "av_buffersink_get_frame() failed");
|
throw MakeFfmpegError(err, "av_buffersink_get_frame() failed");
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
AVFilterContext &_buffer_sink) noexcept;
|
AVFilterContext &_buffer_sink) noexcept;
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "pcm/Buffer.hxx"
|
#include "pcm/Buffer.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "pcm/AudioCompress/compress.h"
|
#include "pcm/AudioCompress/compress.h"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ public:
|
|||||||
NormalizeFilter &operator=(const NormalizeFilter &) = delete;
|
NormalizeFilter &operator=(const NormalizeFilter &) = delete;
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreparedNormalizeFilter final : public PreparedFilter {
|
class PreparedNormalizeFilter final : public PreparedFilter {
|
||||||
@ -70,14 +69,14 @@ PreparedNormalizeFilter::Open(AudioFormat &audio_format)
|
|||||||
return std::make_unique<NormalizeFilter>(audio_format);
|
return std::make_unique<NormalizeFilter>(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
NormalizeFilter::FilterPCM(ConstBuffer<void> src)
|
NormalizeFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
auto *dest = (int16_t *)buffer.Get(src.size);
|
auto *dest = (int16_t *)buffer.Get(src.size());
|
||||||
memcpy(dest, src.data, src.size);
|
memcpy(dest, src.data(), src.size());
|
||||||
|
|
||||||
Compressor_Process_int16(compressor, dest, src.size / 2);
|
Compressor_Process_int16(compressor, dest, src.size() / 2);
|
||||||
return { (const void *)dest, src.size };
|
return { (const std::byte *)dest, src.size() };
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterPlugin normalize_filter_plugin = {
|
const FilterPlugin normalize_filter_plugin = {
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "mixer/MixerControl.hxx"
|
#include "mixer/MixerControl.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "pcm/Volume.hxx"
|
#include "pcm/Volume.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Idle.hxx"
|
#include "Idle.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
@ -109,7 +108,7 @@ public:
|
|||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreparedReplayGainFilter final : public PreparedFilter {
|
class PreparedReplayGainFilter final : public PreparedFilter {
|
||||||
@ -197,8 +196,8 @@ PreparedReplayGainFilter::Open(AudioFormat &af)
|
|||||||
af, mixer, base);
|
af, mixer, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
ReplayGainFilter::FilterPCM(ConstBuffer<void> src)
|
ReplayGainFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
return mixer != nullptr
|
return mixer != nullptr
|
||||||
? std::span<const std::byte>{src}
|
? std::span<const std::byte>{src}
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#include "pcm/Silence.hxx"
|
#include "pcm/Silence.hxx"
|
||||||
#include "util/StringStrip.hxx"
|
#include "util/StringStrip.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -94,7 +93,7 @@ public:
|
|||||||
const std::array<int8_t, MAX_CHANNELS> &_sources);
|
const std::array<int8_t, MAX_CHANNELS> &_sources);
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreparedRouteFilter final : public PreparedFilter {
|
class PreparedRouteFilter final : public PreparedFilter {
|
||||||
@ -221,15 +220,15 @@ PreparedRouteFilter::Open(AudioFormat &audio_format)
|
|||||||
sources);
|
sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
RouteFilter::FilterPCM(ConstBuffer<void> src)
|
RouteFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
size_t number_of_frames = src.size / input_frame_size;
|
size_t number_of_frames = src.size() / input_frame_size;
|
||||||
|
|
||||||
const size_t bytes_per_frame_per_channel = input_format.GetSampleSize();
|
const size_t bytes_per_frame_per_channel = input_format.GetSampleSize();
|
||||||
|
|
||||||
// A moving pointer that always refers to channel 0 in the input, at the currently handled frame
|
// A moving pointer that always refers to channel 0 in the input, at the currently handled frame
|
||||||
const auto *base_source = (const uint8_t *)src.data;
|
const auto *base_source = (const uint8_t *)src.data();
|
||||||
|
|
||||||
// Grow our reusable buffer, if needed, and set the moving pointer
|
// Grow our reusable buffer, if needed, and set the moving pointer
|
||||||
const size_t result_size = number_of_frames * output_frame_size;
|
const size_t result_size = number_of_frames * output_frame_size;
|
||||||
@ -268,7 +267,7 @@ RouteFilter::FilterPCM(ConstBuffer<void> src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Here it is, ladies and gentlemen! Rerouted data!
|
// Here it is, ladies and gentlemen! Rerouted data!
|
||||||
return { result, result_size };
|
return { (const std::byte *)result, result_size };
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterPlugin route_filter_plugin = {
|
const FilterPlugin route_filter_plugin = {
|
||||||
|
@ -19,21 +19,20 @@
|
|||||||
|
|
||||||
#include "TwoFilters.hxx"
|
#include "TwoFilters.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/StringBuffer.hxx"
|
#include "util/StringBuffer.hxx"
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
TwoFilters::FilterPCM(ConstBuffer<void> src)
|
TwoFilters::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
return second->FilterPCM(first->FilterPCM(src));
|
return second->FilterPCM(first->FilterPCM(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
TwoFilters::Flush()
|
TwoFilters::Flush()
|
||||||
{
|
{
|
||||||
auto result = first->Flush();
|
auto result = first->Flush();
|
||||||
if (!result.IsNull())
|
if (result.data() != nullptr)
|
||||||
/* Flush() output from the first Filter must be
|
/* Flush() output from the first Filter must be
|
||||||
filtered by the second Filter */
|
filtered by the second Filter */
|
||||||
return second->FilterPCM(result);
|
return second->FilterPCM(result);
|
||||||
|
@ -44,8 +44,8 @@ public:
|
|||||||
second->Reset();
|
second->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
ConstBuffer<void> Flush() override;
|
std::span<const std::byte> Flush() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "filter/Prepared.hxx"
|
#include "filter/Prepared.hxx"
|
||||||
#include "pcm/Volume.hxx"
|
#include "pcm/Volume.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
|
|
||||||
class VolumeFilter final : public Filter {
|
class VolumeFilter final : public Filter {
|
||||||
PcmVolume pv;
|
PcmVolume pv;
|
||||||
@ -43,7 +42,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
std::span<const std::byte> FilterPCM(std::span<const std::byte> src) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreparedVolumeFilter final : public PreparedFilter {
|
class PreparedVolumeFilter final : public PreparedFilter {
|
||||||
@ -58,8 +57,8 @@ PreparedVolumeFilter::Open(AudioFormat &audio_format)
|
|||||||
return std::make_unique<VolumeFilter>(audio_format);
|
return std::make_unique<VolumeFilter>(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void>
|
std::span<const std::byte>
|
||||||
VolumeFilter::FilterPCM(ConstBuffer<void> src)
|
VolumeFilter::FilterPCM(std::span<const std::byte> src)
|
||||||
{
|
{
|
||||||
return pv.Apply(src);
|
return pv.Apply(src);
|
||||||
}
|
}
|
||||||
|
@ -255,5 +255,5 @@ AudioOutputSource::Flush()
|
|||||||
{
|
{
|
||||||
return filter
|
return filter
|
||||||
? filter->Flush()
|
? filter->Flush()
|
||||||
: nullptr;
|
: std::span<const std::byte>{};
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include "mixer/MixerControl.hxx"
|
#include "mixer/MixerControl.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
#include "io/FileDescriptor.hxx"
|
#include "io/FileDescriptor.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
|
||||||
#include "util/StringBuffer.hxx"
|
#include "util/StringBuffer.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/PrintException.hxx"
|
#include "util/PrintException.hxx"
|
||||||
@ -102,22 +101,22 @@ try {
|
|||||||
FileDescriptor output_fd(STDOUT_FILENO);
|
FileDescriptor output_fd(STDOUT_FILENO);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
char buffer[4096];
|
std::byte buffer[4096];
|
||||||
|
|
||||||
ssize_t nbytes = ReadFrames(input_fd, buffer, sizeof(buffer),
|
ssize_t nbytes = ReadFrames(input_fd, buffer, sizeof(buffer),
|
||||||
in_frame_size);
|
in_frame_size);
|
||||||
if (nbytes == 0)
|
if (nbytes == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto dest = filter->FilterPCM({(const void *)buffer, (size_t)nbytes});
|
auto dest = filter->FilterPCM(std::span{buffer}.first(nbytes));
|
||||||
output_fd.FullWrite(dest.data, dest.size);
|
output_fd.FullWrite(dest.data(), dest.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto dest = filter->Flush();
|
auto dest = filter->Flush();
|
||||||
if (dest.IsNull())
|
if (dest.data() == nullptr)
|
||||||
break;
|
break;
|
||||||
output_fd.FullWrite(dest.data, dest.size);
|
output_fd.FullWrite(dest.data(), dest.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup and exit */
|
/* cleanup and exit */
|
||||||
|
Loading…
Reference in New Issue
Block a user