From e06b85632aa48c173a42d4f34e79cc1ad9b2280c Mon Sep 17 00:00:00 2001 From: TennesseeTrash Date: Fri, 26 Sep 2025 02:54:05 +0200 Subject: [PATCH] Make all decoder components move-only --- LibCBOR/Include/CBOR/Decoder.hpp | 55 ++++++++++++++ LibCBOR/Source/Decoder.cpp | 118 +++++++++++++++++++++++++++++++ Tests/Main.cpp | 2 +- 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/LibCBOR/Include/CBOR/Decoder.hpp b/LibCBOR/Include/CBOR/Decoder.hpp index 9c3d1e2..b3c957e 100644 --- a/LibCBOR/Include/CBOR/Decoder.hpp +++ b/LibCBOR/Include/CBOR/Decoder.hpp @@ -19,7 +19,14 @@ namespace CBOR private: Item(class Decoder &decoder); + Item(const Item &) = delete; + Item &operator=(const Item &) = delete; + public: + Item(Item &&other); + Item &operator=(Item &&other); + ~Item() = default; + static constexpr std::uint64_t ArgumentIndefinite = std::numeric_limits::max(); @@ -66,7 +73,14 @@ namespace CBOR private: TaggedItem(class Decoder &decoder); + TaggedItem(const TaggedItem &) = delete; + TaggedItem &operator=(const TaggedItem &) = delete; + public: + TaggedItem(TaggedItem &&other); + TaggedItem &operator=(TaggedItem &&other); + ~TaggedItem() = default; + std::uint64_t Tag(); Item Item(); @@ -87,7 +101,14 @@ namespace CBOR private: KeyValue(class Decoder &decoder); + KeyValue(const KeyValue &) = delete; + KeyValue &operator=(const KeyValue &) = delete; + public: + KeyValue(KeyValue &&other); + KeyValue &operator=(KeyValue &&other); + ~KeyValue() = default; + Item Key(); Item Value(); private: @@ -108,7 +129,14 @@ namespace CBOR private: Binary(class Decoder &decoder); + Binary(const Binary &) = delete; + Binary &operator=(const Binary &) = delete; + public: + Binary(Binary &&other); + Binary &operator=(Binary &&other); + ~Binary() = default; + bool Done(); ConstBuffer Next(); @@ -126,7 +154,14 @@ namespace CBOR private: String(class Decoder &decoder); + String(const String &) = delete; + String &operator=(const String &) = delete; + public: + String(String &&other); + String &operator=(String &&other); + ~String() = default; + bool Done(); std::string_view Next(); @@ -144,7 +179,14 @@ namespace CBOR private: Array(class Decoder &decoder); + Array(const Array &) = delete; + Array &operator=(const Array &) = delete; + public: + Array(Array &&other); + Array &operator=(Array &&other); + ~Array() = default; + bool Done(); Item Next(); @@ -164,7 +206,14 @@ namespace CBOR private: Map(class Decoder &decoder); + Map(const Map &) = delete; + Map &operator=(const Map &) = delete; + public: + Map(Map &&other); + Map &operator=(Map &&other); + ~Map() = default; + bool Done(); KeyValue Next(); @@ -184,6 +233,12 @@ namespace CBOR public: Decoder(ConstBuffer buffer); + Decoder(const Decoder &) = delete; + Decoder &operator=(const Decoder &) = delete; + Decoder(Decoder &&other); + Decoder &operator=(Decoder &&other); + ~Decoder() = default; + static constexpr std::uint64_t ArgumentIndefinite = std::numeric_limits::max(); diff --git a/LibCBOR/Source/Decoder.cpp b/LibCBOR/Source/Decoder.cpp index 706efb0..dae31e0 100644 --- a/LibCBOR/Source/Decoder.cpp +++ b/LibCBOR/Source/Decoder.cpp @@ -411,6 +411,16 @@ namespace CBOR : mDecoder(&decoder) {} + Item::Item(Item &&other) + : mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + Item &Item::operator=(Item &&other) + { + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + MajorType Item::GetMajor() const { return mDecoder->GetMajor(); @@ -525,6 +535,18 @@ namespace CBOR : mState(State::Initial), mDecoder(&decoder) {} + TaggedItem::TaggedItem(TaggedItem &&other) + : mState(std::exchange(other.mState, State::Done)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + TaggedItem &TaggedItem::operator=(TaggedItem &&other) + { + mState = std::exchange(other.mState, State::Done); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + std::uint64_t TaggedItem::Tag() { if (mState != State::Initial) { @@ -555,6 +577,18 @@ namespace CBOR : mState(State::Initial), mDecoder(&decoder) {} + KeyValue::KeyValue(KeyValue &&other) + : mState(std::exchange(other.mState, State::Done)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + KeyValue &KeyValue::operator=(KeyValue &&other) + { + mState = std::exchange(other.mState, State::Done); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + Item KeyValue::Key() { if (mState != State::Initial) { @@ -582,6 +616,22 @@ namespace CBOR , mDecoder(&decoder) {} + Binary::Binary(Binary &&other) + : mHeaderParsed(std::exchange(other.mHeaderParsed, true)) + , mDone(std::exchange(other.mDone, true)) + , mCheckedDone(std::exchange(other.mCheckedDone, true)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + Binary &Binary::operator=(Binary &&other) + { + mHeaderParsed = std::exchange(other.mHeaderParsed, true); + mDone = std::exchange(other.mDone, true); + mCheckedDone = std::exchange(other.mCheckedDone, true); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + bool Binary::Done() { if (!mHeaderParsed) { @@ -649,6 +699,22 @@ namespace CBOR , mDecoder(&decoder) {} + String::String(String &&other) + : mHeaderParsed(std::exchange(other.mHeaderParsed, true)) + , mDone(std::exchange(other.mDone, true)) + , mCheckedDone(std::exchange(other.mCheckedDone, true)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + String &String::operator=(String &&other) + { + mHeaderParsed = std::exchange(other.mHeaderParsed, true); + mDone = std::exchange(other.mDone, true); + mCheckedDone = std::exchange(other.mCheckedDone, true); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + bool String::Done() { if (!mHeaderParsed) { @@ -718,6 +784,26 @@ namespace CBOR , mDecoder(&decoder) {} + Array::Array(Array &&other) + : mHeaderParsed(std::exchange(other.mHeaderParsed, true)) + , mDone(std::exchange(other.mDone, true)) + , mCheckedDone(std::exchange(other.mCheckedDone, true)) + , mCurrent(std::exchange(other.mCurrent, 0)) + , mSize(std::exchange(other.mSize, 0)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + Array &Array::operator=(Array &&other) + { + mHeaderParsed = std::exchange(other.mHeaderParsed, true); + mDone = std::exchange(other.mDone, true); + mCheckedDone = std::exchange(other.mCheckedDone, true); + mCurrent = std::exchange(other.mCurrent, 0); + mSize = std::exchange(other.mSize, 0); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + bool Array::Done() { if (!mHeaderParsed) { @@ -782,6 +868,26 @@ namespace CBOR , mDecoder(&decoder) {} + Map::Map(Map &&other) + : mHeaderParsed(std::exchange(other.mHeaderParsed, true)) + , mDone(std::exchange(other.mDone, true)) + , mCheckedDone(std::exchange(other.mCheckedDone, true)) + , mCurrent(std::exchange(other.mCurrent, 0)) + , mSize(std::exchange(other.mSize, 0)) + , mDecoder(std::exchange(other.mDecoder, nullptr)) + {} + + Map &Map::operator=(Map &&other) + { + mHeaderParsed = std::exchange(other.mHeaderParsed, true); + mDone = std::exchange(other.mDone, true); + mCheckedDone = std::exchange(other.mCheckedDone, true); + mCurrent = std::exchange(other.mCurrent, 0); + mSize = std::exchange(other.mSize, 0); + mDecoder = std::exchange(other.mDecoder, nullptr); + return *this; + } + bool Map::Done() { if (!mHeaderParsed) { @@ -841,6 +947,18 @@ namespace CBOR : mCurrent(0), mBuffer(buffer) {} + Decoder::Decoder(Decoder &&other) + : mCurrent(std::exchange(other.mCurrent, 0)) + , mBuffer(std::exchange(other.mBuffer, {})) + {} + + Decoder &Decoder::operator=(Decoder &&other) + { + mCurrent = std::exchange(other.mCurrent, 0); + mBuffer = std::exchange(other.mBuffer, {}); + return *this; + } + MajorType Decoder::GetMajor() const { std::uint8_t header = Read1B(mBuffer, mCurrent); diff --git a/Tests/Main.cpp b/Tests/Main.cpp index e0424ef..67653a7 100644 --- a/Tests/Main.cpp +++ b/Tests/Main.cpp @@ -1,6 +1,6 @@ #include "CBOR/Decoder.hpp" #include "CBOR/Encoder.hpp" -#include "Cbor/Printer.hpp" +#include "CBOR/Printer.hpp" #include #include #include