diff --git a/src/decoder/plugins/ModCommon.cxx b/src/decoder/plugins/ModCommon.cxx index 4adf9a272..187da1abe 100644 --- a/src/decoder/plugins/ModCommon.cxx +++ b/src/decoder/plugins/ModCommon.cxx @@ -51,8 +51,8 @@ mod_loadfile(const Domain *domain, DecoderClient *client, InputStream &is) auto buffer = AllocatedArray(buffer_size); - std::byte *const end = buffer.end(); - std::byte *p = buffer.begin(); + std::byte *p = buffer.data(); + std::byte *const end = p + buffer.size(); while (true) { size_t ret = decoder_read(client, is, p, end - p); diff --git a/src/decoder/plugins/ModplugDecoderPlugin.cxx b/src/decoder/plugins/ModplugDecoderPlugin.cxx index cd31602af..f6e017888 100644 --- a/src/decoder/plugins/ModplugDecoderPlugin.cxx +++ b/src/decoder/plugins/ModplugDecoderPlugin.cxx @@ -73,7 +73,7 @@ static ModPlugFile * LoadModPlugFile(DecoderClient *client, InputStream &is) { const auto buffer = mod_loadfile(&modplug_domain, client, is); - if (buffer.IsNull()) { + if (buffer == nullptr) { LogWarning(modplug_domain, "could not load stream"); return nullptr; } diff --git a/src/decoder/plugins/OpenmptDecoderPlugin.cxx b/src/decoder/plugins/OpenmptDecoderPlugin.cxx index 1e8547d1f..12508d2c3 100644 --- a/src/decoder/plugins/OpenmptDecoderPlugin.cxx +++ b/src/decoder/plugins/OpenmptDecoderPlugin.cxx @@ -73,7 +73,7 @@ mod_decode(DecoderClient &client, InputStream &is) char audio_buffer[OPENMPT_FRAME_SIZE]; const auto buffer = mod_loadfile(&openmpt_domain, &client, is); - if (buffer.IsNull()) { + if (buffer == nullptr) { LogWarning(openmpt_domain, "could not load stream"); return; } @@ -128,7 +128,7 @@ static bool openmpt_scan_stream(InputStream &is, TagHandler &handler) noexcept try { const auto buffer = mod_loadfile(&openmpt_domain, nullptr, is); - if (buffer.IsNull()) { + if (buffer == nullptr) { LogWarning(openmpt_domain, "could not load stream"); return false; } diff --git a/src/lib/icu/CaseFold.cxx b/src/lib/icu/CaseFold.cxx index d085b3cf6..c6b06c546 100644 --- a/src/lib/icu/CaseFold.cxx +++ b/src/lib/icu/CaseFold.cxx @@ -43,21 +43,21 @@ IcuCaseFold(std::string_view src) noexcept try { #ifdef HAVE_ICU const auto u = UCharFromUTF8(src); - if (u.IsNull()) + if (u.data() == nullptr) return {src}; AllocatedArray folded(u.size() * 2U); UErrorCode error_code = U_ZERO_ERROR; - size_t folded_length = u_strFoldCase(folded.begin(), folded.size(), - u.begin(), u.size(), + size_t folded_length = u_strFoldCase(folded.data(), folded.size(), + u.data(), u.size(), U_FOLD_CASE_DEFAULT, &error_code); if (folded_length == 0 || error_code != U_ZERO_ERROR) return {src}; folded.SetSize(folded_length); - return UCharToUTF8({folded.begin(), folded.size()}); + return UCharToUTF8(std::basic_string_view{folded.data(), folded.size()}); #else #error not implemented diff --git a/src/lib/icu/Converter.cxx b/src/lib/icu/Converter.cxx index 9fc15c728..9335fe4a7 100644 --- a/src/lib/icu/Converter.cxx +++ b/src/lib/icu/Converter.cxx @@ -141,11 +141,11 @@ IcuConverter::FromUTF8(std::string_view s) const // TODO: dynamic buffer? char buffer[4096], *target = buffer; - const UChar *source = u.begin(); + const UChar *source = u.data(); UErrorCode code = U_ZERO_ERROR; ucnv_fromUnicode(converter, &target, buffer + std::size(buffer), - &source, u.end(), + &source, u.data() + u.size(), nullptr, true, &code); if (code != U_ZERO_ERROR) diff --git a/src/lib/icu/Util.cxx b/src/lib/icu/Util.cxx index 4739c3f45..084a25def 100644 --- a/src/lib/icu/Util.cxx +++ b/src/lib/icu/Util.cxx @@ -38,7 +38,7 @@ UCharFromUTF8(std::string_view src) UErrorCode error_code = U_ZERO_ERROR; int32_t dest_length; - u_strFromUTF8(dest.begin(), dest_capacity, &dest_length, + u_strFromUTF8(dest.data(), dest_capacity, &dest_length, src.data(), src.size(), &error_code); if (U_FAILURE(error_code)) diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx index eebd47540..25df4c920 100644 --- a/src/output/plugins/AlsaOutputPlugin.cxx +++ b/src/output/plugins/AlsaOutputPlugin.cxx @@ -760,7 +760,7 @@ Play_44_1_Silence(snd_pcm_t *pcm) throw Alsa::MakeError(err, "snd_pcm_prepare() failed"); AllocatedArray buffer{channels * period_size}; - buffer = {}; + buffer = std::span{}; /* play at least 250ms of silence */ for (snd_pcm_uframes_t remaining_frames = rate / 4;;) { diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx index de58286ca..9af3897ac 100644 --- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx +++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx @@ -172,7 +172,7 @@ HttpdOutput::ReadPage() if (size == 0) return nullptr; - return std::make_shared(ConstBuffer{buffer, size}); + return std::make_shared(std::span{buffer, size}); } inline void diff --git a/src/output/plugins/httpd/IcyMetaDataServer.cxx b/src/output/plugins/httpd/IcyMetaDataServer.cxx index 96c8bba12..29260608e 100644 --- a/src/output/plugins/httpd/IcyMetaDataServer.cxx +++ b/src/output/plugins/httpd/IcyMetaDataServer.cxx @@ -114,5 +114,5 @@ icy_server_metadata_page(const Tag &tag, const TagType *types) noexcept if (icy_string == nullptr) return nullptr; - return std::make_shared(ConstBuffer{(const std::byte *)icy_string.c_str(), uint8_t(icy_string[0]) * 16U + 1U}); + return std::make_shared(std::span{(const std::byte *)icy_string.c_str(), uint8_t(icy_string[0]) * 16U + 1U}); } diff --git a/src/output/plugins/snapcast/Client.cxx b/src/output/plugins/snapcast/Client.cxx index 4b4a7601e..0f7e29c1c 100644 --- a/src/output/plugins/snapcast/Client.cxx +++ b/src/output/plugins/snapcast/Client.cxx @@ -95,8 +95,8 @@ SnapcastClient::OnSocketReady(unsigned flags) noexcept /* discard old chunks */ continue; - const ConstBuffer payload = chunk->payload; - if (!SendWireChunk(payload.ToVoid(), chunk->time)) { + const std::span payload = chunk->payload; + if (!SendWireChunk(payload, chunk->time)) { // TODO: handle EAGAIN LockClose(); return; @@ -110,23 +110,23 @@ SnapcastClient::OnSocketReady(unsigned flags) noexcept } static bool -Send(SocketDescriptor s, ConstBuffer buffer) noexcept +Send(SocketDescriptor s, std::span buffer) noexcept { - auto nbytes = s.Write(buffer.data, buffer.size); - return nbytes == ssize_t(buffer.size); + auto nbytes = s.Write(buffer.data(), buffer.size()); + return nbytes == ssize_t(buffer.size()); } template static bool SendT(SocketDescriptor s, const T &buffer) noexcept { - return Send(s, ConstBuffer{&buffer, 1}.ToVoid()); + return Send(s, std::as_bytes(std::span{&buffer, 1})); } static bool -Send(SocketDescriptor s, StringView buffer) noexcept +Send(SocketDescriptor s, std::string_view buffer) noexcept { - return Send(s, buffer.ToVoid()); + return Send(s, std::as_bytes(std::span{buffer})); } static bool @@ -158,10 +158,10 @@ static bool SendCodecHeader(SocketDescriptor s, const PackedBE16 id, const SnapcastBase &request, const StringView codec, - const ConstBuffer payload) noexcept + const std::span payload) noexcept { const PackedLE32 codec_size = codec.size; - const PackedLE32 payload_size = payload.size; + const PackedLE32 payload_size = payload.size(); SnapcastBase base{}; base.type = uint16_t(SnapcastMessageType::CODEC_HEADER); @@ -169,7 +169,7 @@ SendCodecHeader(SocketDescriptor s, const PackedBE16 id, base.refers_to = request.id; base.sent = ToSnapcastTimestamp(std::chrono::steady_clock::now()); base.size = sizeof(codec_size) + codec.size + - sizeof(payload_size) + payload.size; + sizeof(payload_size) + payload.size(); return SendT(s, base) && SendT(s, codec_size) && Send(s, codec) && @@ -212,25 +212,25 @@ SnapcastClient::SendTime(const SnapcastBase &request_header, static bool SendWireChunk(SocketDescriptor s, const PackedBE16 id, - const ConstBuffer payload, + const std::span payload, std::chrono::steady_clock::time_point t) noexcept { SnapcastWireChunk hdr{}; hdr.timestamp = ToSnapcastTimestamp(t); - hdr.size = payload.size; + hdr.size = payload.size(); SnapcastBase base{}; base.type = uint16_t(SnapcastMessageType::WIRE_CHUNK); base.id = id; base.sent = ToSnapcastTimestamp(std::chrono::steady_clock::now()); - base.size = sizeof(hdr) + payload.size; + base.size = sizeof(hdr) + payload.size(); // TODO: no blocking send() return SendT(s, base) && SendT(s, hdr) && Send(s, payload); } bool -SnapcastClient::SendWireChunk(ConstBuffer payload, +SnapcastClient::SendWireChunk(std::span payload, std::chrono::steady_clock::time_point t) noexcept { return ::SendWireChunk(GetSocket(), next_id++, payload, t); @@ -238,21 +238,21 @@ SnapcastClient::SendWireChunk(ConstBuffer payload, static bool SendStreamTags(SocketDescriptor s, const PackedBE16 id, - const ConstBuffer payload) noexcept + const std::span payload) noexcept { - const PackedLE32 payload_size = payload.size; + const PackedLE32 payload_size = payload.size(); SnapcastBase base{}; base.type = uint16_t(SnapcastMessageType::STREAM_TAGS); base.id = id; base.sent = ToSnapcastTimestamp(std::chrono::steady_clock::now()); - base.size = sizeof(payload_size) + payload.size; + base.size = sizeof(payload_size) + payload.size(); return SendT(s, base) && SendT(s, payload_size) && Send(s, payload); } void -SnapcastClient::SendStreamTags(ConstBuffer payload) noexcept +SnapcastClient::SendStreamTags(std::span payload) noexcept { ::SendStreamTags(GetSocket(), next_id++, payload); } @@ -270,7 +270,7 @@ SnapcastClient::OnSocketInput(void *data, size_t length) noexcept ConsumeInput(sizeof(base) + base.size); - const ConstBuffer payload{&base + 1, base.size}; + const std::span payload{(const std::byte *)(&base + 1), base.size}; switch (SnapcastMessageType(uint16_t(base.type))) { case SnapcastMessageType::HELLO: @@ -284,8 +284,8 @@ SnapcastClient::OnSocketInput(void *data, size_t length) noexcept break; case SnapcastMessageType::TIME: - if (payload.size >= sizeof(SnapcastTime)) - SendTime(base, *(const SnapcastTime *)payload.data); + if (payload.size() >= sizeof(SnapcastTime)) + SendTime(base, *(const SnapcastTime *)(const void *)payload.data()); break; default: diff --git a/src/output/plugins/snapcast/Client.hxx b/src/output/plugins/snapcast/Client.hxx index d104d4ae8..7e4f19db8 100644 --- a/src/output/plugins/snapcast/Client.hxx +++ b/src/output/plugins/snapcast/Client.hxx @@ -26,6 +26,7 @@ #include #include +#include struct SnapcastBase; struct SnapcastTime; @@ -60,7 +61,7 @@ public: void LockClose() noexcept; - void SendStreamTags(ConstBuffer payload) noexcept; + void SendStreamTags(std::span payload) noexcept; /** * Caller must lock the mutex. @@ -84,7 +85,7 @@ public: private: SnapcastChunkPtr LockPopQueue() noexcept; - bool SendWireChunk(ConstBuffer payload, + bool SendWireChunk(std::span payload, std::chrono::steady_clock::time_point t) noexcept; bool SendServerSettings(const SnapcastBase &request) noexcept; diff --git a/src/output/plugins/snapcast/Internal.hxx b/src/output/plugins/snapcast/Internal.hxx index 837b568a5..54fca7430 100644 --- a/src/output/plugins/snapcast/Internal.hxx +++ b/src/output/plugins/snapcast/Internal.hxx @@ -161,9 +161,8 @@ public: return "pcm"; } - ConstBuffer GetCodecHeader() const noexcept { - ConstBuffer result(codec_header); - return result.ToVoid(); + std::span GetCodecHeader() const noexcept { + return codec_header; } /* virtual methods from class AudioOutput */ diff --git a/src/output/plugins/snapcast/SnapcastOutputPlugin.cxx b/src/output/plugins/snapcast/SnapcastOutputPlugin.cxx index 1abe2a45a..fd5a6fee6 100644 --- a/src/output/plugins/snapcast/SnapcastOutputPlugin.cxx +++ b/src/output/plugins/snapcast/SnapcastOutputPlugin.cxx @@ -127,7 +127,7 @@ ReadEncoder(Encoder &encoder) std::byte buffer[4096]; size_t nbytes = encoder.Read(buffer, sizeof(buffer)); - const ConstBuffer src(buffer, nbytes); + const std::span src{buffer, nbytes}; return AllocatedArray{src}; } @@ -181,7 +181,7 @@ SnapcastOutput::Close() noexcept ClearQueue(chunks); - codec_header = nullptr; + codec_header = std::span{}; delete encoder; } @@ -294,12 +294,12 @@ SnapcastOutput::SendTag(const Tag &tag) if (json.empty()) return; - const ConstBuffer payload(json.data(), json.size()); + const auto payload = std::as_bytes(std::span{json}); const std::scoped_lock protect(mutex); // TODO: enqueue StreamTags, don't send directly for (auto &client : clients) - client.SendStreamTags(payload.ToVoid()); + client.SendStreamTags(payload); #else (void)tag; #endif @@ -348,7 +348,7 @@ SnapcastOutput::Play(const void *chunk, size_t size) if (chunks.empty()) inject_event.Schedule(); - const ConstBuffer payload{buffer, nbytes}; + const std::span payload{buffer, nbytes}; chunks.push(std::make_shared(now, AllocatedArray{payload})); } diff --git a/src/tag/Builder.cxx b/src/tag/Builder.cxx index 468d3d676..28241d3ef 100644 --- a/src/tag/Builder.cxx +++ b/src/tag/Builder.cxx @@ -216,7 +216,7 @@ TagBuilder::AddItemInternal(TagType type, StringView value) noexcept assert(!value.empty()); auto f = FixTagString(value); - if (!f.IsNull()) + if (f != nullptr) value = { f.data(), f.size() }; AddItemUnchecked(type, value); diff --git a/src/util/AllocatedArray.hxx b/src/util/AllocatedArray.hxx index 476997f00..86a703511 100644 --- a/src/util/AllocatedArray.hxx +++ b/src/util/AllocatedArray.hxx @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 Max Kellermann + * Copyright 2010-2022 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +27,11 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ALLOCATED_ARRAY_HXX -#define ALLOCATED_ARRAY_HXX - -#include "ConstBuffer.hxx" -#include "WritableBuffer.hxx" +#pragma once #include #include +#include #include /** @@ -42,7 +39,7 @@ */ template class AllocatedArray { - typedef WritableBuffer Buffer; + using Buffer = std::span; public: using size_type = typename Buffer::size_type; @@ -51,10 +48,10 @@ public: using pointer = typename Buffer::pointer; using const_pointer = typename Buffer::const_pointer; using iterator = typename Buffer::iterator; - using const_iterator = typename Buffer::const_iterator; + using const_iterator = typename Buffer::iterator; protected: - Buffer buffer{nullptr}; + Buffer buffer{}; public: constexpr AllocatedArray() = default; @@ -62,16 +59,15 @@ public: explicit AllocatedArray(size_type _size) noexcept :buffer{new T[_size], _size} {} - explicit AllocatedArray(ConstBuffer src) noexcept { - if (src == nullptr) + explicit AllocatedArray(std::span src) noexcept { + if (src.data() == nullptr) return; - buffer = {new T[src.size], src.size}; - std::copy_n(src.data, src.size, buffer.data); + buffer = {new T[src.size()], src.size()}; + std::copy(src.begin(), src.end(), buffer.begin()); } - AllocatedArray(std::nullptr_t n) noexcept - :buffer(n) {} + AllocatedArray(std::nullptr_t) noexcept {} explicit AllocatedArray(const AllocatedArray &other) noexcept :AllocatedArray(other.buffer) {} @@ -80,27 +76,28 @@ public: :buffer(other.release()) {} ~AllocatedArray() noexcept { - delete[] buffer.data; + delete[] buffer.data(); } - AllocatedArray &operator=(ConstBuffer src) noexcept { - assert(size() == 0 || buffer.data != nullptr); - assert(src.size == 0 || src.data != nullptr); + AllocatedArray &operator=(std::span src) noexcept { + assert(empty() || buffer.data() != nullptr); + assert(src.empty() || src.data() != nullptr); - ResizeDiscard(src.size); - std::copy_n(src.data, src.size, buffer.data); + ResizeDiscard(src.size()); + std::copy(src.begin(), src.end(), buffer.begin()); return *this; } AllocatedArray &operator=(const AllocatedArray &other) noexcept { - assert(size() == 0 || buffer.data != nullptr); - assert(other.size() == 0 || other.buffer.data != nullptr); + assert(empty() || buffer.data() != nullptr); + assert(other.empty() || other.buffer.data() != nullptr); if (&other == this) return *this; ResizeDiscard(other.size()); - std::copy_n(other.buffer.data, other.buffer.size, buffer.data); + std::copy_n(other.buffer.begin(), other.buffer.end(), + buffer.begin()); return *this; } @@ -111,29 +108,25 @@ public: } AllocatedArray &operator=(std::nullptr_t n) noexcept { - delete[] buffer.data; - buffer = n; + delete[] buffer.data(); + buffer = {}; return *this; } - operator ConstBuffer() const noexcept { + operator std::span() const noexcept { return buffer; } - operator WritableBuffer() noexcept { + operator std::span() noexcept { return buffer; } - constexpr bool IsNull() const noexcept { - return buffer.IsNull(); - } - constexpr bool operator==(std::nullptr_t) const noexcept { - return buffer == nullptr; + return buffer.data() == nullptr; } constexpr bool operator!=(std::nullptr_t) const noexcept { - return buffer != nullptr; + return buffer.data() != nullptr; } /** @@ -147,22 +140,22 @@ public: * Returns the number of allocated elements. */ constexpr size_type size() const noexcept { - return buffer.size; + return buffer.size(); } /** * Returns the number of allocated elements. */ constexpr size_type capacity() const noexcept { - return buffer.size; + return buffer.size(); } pointer data() noexcept { - return buffer.data; + return buffer.data(); } const_pointer data() const noexcept { - return buffer.data; + return buffer.data(); } reference front() noexcept { @@ -200,7 +193,7 @@ public: } constexpr const_iterator begin() const noexcept { - return buffer.cbegin(); + return buffer.begin(); } iterator end() noexcept { @@ -208,19 +201,18 @@ public: } constexpr const_iterator end() const noexcept { - return buffer.cend(); + return buffer.end(); } /** * Resizes the array, discarding old data. */ void ResizeDiscard(size_type _size) noexcept { - if (_size == buffer.size) + if (_size == buffer.size()) return; - delete[] buffer.data; - buffer.size = _size; - buffer.data = new T[buffer.size]; + delete[] buffer.data(); + buffer = {new T[_size], _size}; } /** @@ -229,7 +221,7 @@ public: * avoid expensive heap operations. */ void GrowDiscard(size_type _size) noexcept { - if (_size > buffer.size) + if (_size > buffer.size()) ResizeDiscard(_size); } @@ -238,16 +230,16 @@ public: * range of elements, starting from the beginning. */ void GrowPreserve(size_type _size, size_type preserve) noexcept { - if (_size <= buffer.size) + if (_size <= buffer.size()) return; T *new_data = new T[_size]; - std::move(buffer.data, buffer.data + preserve, new_data); + std::move(buffer.begin(), std::next(buffer.begin(), preserve), + new_data); - delete[] buffer.data; - buffer.data = new_data; - buffer.size = _size; + delete[] buffer.data(); + buffer = {new_data, _size}; } /** @@ -256,17 +248,15 @@ public: * they are still allocated). */ void SetSize(size_type _size) noexcept { - assert(_size <= buffer.size); + assert(_size <= buffer.size()); - buffer.size = _size; + buffer = buffer.first(_size); } /** * Give up ownership of the allocated buffer and return it. */ Buffer release() noexcept { - return std::exchange(buffer, nullptr); + return std::exchange(buffer, std::span{}); } }; - -#endif