diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2020-12-12 18:23:01 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-12-12 18:23:01 +0000 |
commit | b9bc338c27b722135443b38eacaf0591c01dbef4 (patch) | |
tree | 761a7313a14d4e6c2314cbd483fdef89a453f8fd | |
parent | 4f9010ce6fc2abdf42af55ff9fe00a6000c520c3 (diff) | |
parent | e37e4e30636f6ddaff0a0bbffa102ce5d8ab87f2 (diff) | |
download | libcppbor-b9bc338c27b722135443b38eacaf0591c01dbef4.tar.gz |
Merge "Remove CompoundItem." am: e37e4e3063
Original change: https://android-review.googlesource.com/c/platform/external/libcppbor/+/1515380
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I9dd3988cda35ddd5e18c98d09d168318c68ea8bc
-rw-r--r-- | include/cppbor/cppbor.h | 82 | ||||
-rw-r--r-- | src/cppbor.cpp | 68 | ||||
-rw-r--r-- | src/cppbor_parse.cpp | 7 |
3 files changed, 102 insertions, 55 deletions
diff --git a/include/cppbor/cppbor.h b/include/cppbor/cppbor.h index 5ee055e..b6026ba 100644 --- a/include/cppbor/cppbor.h +++ b/include/cppbor/cppbor.h @@ -419,33 +419,6 @@ class Tstr : public Item { std::string mValue; }; -/** - * CompoundItem is an abstract Item that provides common functionality for Items that contain other - * items, i.e. Arrays (CBOR type 4) and Maps (CBOR type 5). - */ -class CompoundItem : public Item { - public: - bool operator==(const CompoundItem& other) const&; - - virtual size_t size() const { return mEntries.size(); } - - bool isCompound() const override { return true; } - - size_t encodedSize() const override { - return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()), - [](size_t sum, auto& entry) { return sum + entry->encodedSize(); }); - } - - using Item::encode; // Make base versions visible. - uint8_t* encode(uint8_t* pos, const uint8_t* end) const override; - void encode(EncodeCallback encodeCallback) const override; - - virtual uint64_t addlInfo() const = 0; - - protected: - std::vector<std::unique_ptr<Item>> mEntries; -}; - /* * Array is a concrete Item that implements CBOR major type 4. * @@ -453,7 +426,7 @@ class CompoundItem : public Item { * move-only ensures that they're never copied accidentally. If you actually want to copy an Array, * use the clone() method. */ -class Array : public CompoundItem { +class Array : public Item { public: static constexpr MajorType kMajorType = ARRAY; @@ -463,6 +436,8 @@ class Array : public CompoundItem { Array& operator=(const Array&) = delete; Array& operator=(Array&&) = default; + bool operator==(const Array& other) const&; + /** * Construct an Array from a variable number of arguments of different types. See * details::makeItem below for details on what types may be provided. In general, this accepts @@ -480,6 +455,19 @@ class Array : public CompoundItem { template <typename T> Array&& add(T&& v) &&; + bool isCompound() const override { return true; } + + virtual size_t size() const { return mEntries.size(); } + + size_t encodedSize() const override { + return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()), + [](size_t sum, auto& entry) { return sum + entry->encodedSize(); }); + } + + using Item::encode; // Make base versions visible. + uint8_t* encode(uint8_t* pos, const uint8_t* end) const override; + void encode(EncodeCallback encodeCallback) const override; + const std::unique_ptr<Item>& operator[](size_t index) const { return get(index); } std::unique_ptr<Item>& operator[](size_t index) { return get(index); } @@ -491,7 +479,8 @@ class Array : public CompoundItem { std::unique_ptr<Item> clone() const override; - uint64_t addlInfo() const override { return size(); } + protected: + std::vector<std::unique_ptr<Item>> mEntries; }; /* @@ -501,7 +490,7 @@ class Array : public CompoundItem { * move-only ensures that they're never copied accidentally. If you actually want to copy a * Map, use the clone() method. */ -class Map : public CompoundItem { +class Map : public Item { public: static constexpr MajorType kMajorType = MAP; @@ -511,6 +500,8 @@ class Map : public CompoundItem { Map& operator=(const Map& other) = delete; Map& operator=(Map&&) = default; + bool operator==(const Map& other) const&; + /** * Construct a Map from a variable number of arguments of different types. An even number of * arguments must be provided (this is verified statically). See details::makeItem below for @@ -529,11 +520,22 @@ class Map : public CompoundItem { template <typename Key, typename Value> Map&& add(Key&& key, Value&& value) &&; - size_t size() const override { + bool isCompound() const override { return true; } + + virtual size_t size() const { assertInvariant(); return mEntries.size() / 2; } + size_t encodedSize() const override { + return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()), + [](size_t sum, auto& entry) { return sum + entry->encodedSize(); }); + } + + using Item::encode; // Make base versions visible. + uint8_t* encode(uint8_t* pos, const uint8_t* end) const override; + void encode(EncodeCallback encodeCallback) const override; + template <typename Key, typename Enable> const std::unique_ptr<Item>& get(Key key) const; @@ -569,13 +571,14 @@ class Map : public CompoundItem { std::unique_ptr<Item> clone() const override; - uint64_t addlInfo() const override { return size(); } + protected: + std::vector<std::unique_ptr<Item>> mEntries; private: void assertInvariant() const; }; -class Semantic : public CompoundItem { +class Semantic : public Item { public: static constexpr MajorType kMajorType = SEMANTIC; @@ -587,7 +590,11 @@ class Semantic : public CompoundItem { Semantic& operator=(const Semantic& other) = delete; Semantic& operator=(Semantic&&) = default; - size_t size() const override { + bool operator==(const Semantic& other) const&; + + bool isCompound() const override { return true; } + + virtual size_t size() const { assertInvariant(); return 1; } @@ -597,6 +604,10 @@ class Semantic : public CompoundItem { [](size_t sum, auto& entry) { return sum + entry->encodedSize(); }); } + using Item::encode; // Make base versions visible. + uint8_t* encode(uint8_t* pos, const uint8_t* end) const override; + void encode(EncodeCallback encodeCallback) const override; + MajorType type() const override { return kMajorType; } const Semantic* asSemantic() const override { return this; } @@ -612,8 +623,6 @@ class Semantic : public CompoundItem { uint64_t value() const { return mValue; } - uint64_t addlInfo() const override { return value(); } - std::unique_ptr<Item> clone() const override { assertInvariant(); return std::make_unique<Semantic>(mValue, mEntries[0]->clone()); @@ -623,6 +632,7 @@ class Semantic : public CompoundItem { Semantic() = default; Semantic(uint64_t value) : mValue(value) {} uint64_t mValue; + std::vector<std::unique_ptr<Item>> mEntries; private: void assertInvariant() const; diff --git a/src/cppbor.cpp b/src/cppbor.cpp index 50e98ca..632dd0b 100644 --- a/src/cppbor.cpp +++ b/src/cppbor.cpp @@ -52,7 +52,7 @@ void writeBigEndian(T value, std::function<void(uint8_t)>& cb) { } } -bool cborAreAllElementsNonCompound(const CompoundItem* compoundItem) { +bool cborAreAllElementsNonCompound(const Item* compoundItem) { if (compoundItem->type() == ARRAY) { const Array* array = compoundItem->asArray(); for (size_t n = 0; n < array->size(); n++) { @@ -365,17 +365,16 @@ void Tstr::encodeValue(EncodeCallback encodeCallback) const { } } -bool CompoundItem::operator==(const CompoundItem& other) const& { - return type() == other.type() // - && addlInfo() == other.addlInfo() // +bool Array::operator==(const Array& other) const& { + return size() == other.size() // Can't use vector::operator== because the contents are pointers. std::equal lets us // provide a predicate that does the dereferencing. && std::equal(mEntries.begin(), mEntries.end(), other.mEntries.begin(), [](auto& a, auto& b) -> bool { return *a == *b; }); } -uint8_t* CompoundItem::encode(uint8_t* pos, const uint8_t* end) const { - pos = encodeHeader(addlInfo(), pos, end); +uint8_t* Array::encode(uint8_t* pos, const uint8_t* end) const { + pos = encodeHeader(size(), pos, end); if (!pos) return nullptr; for (auto& entry : mEntries) { pos = entry->encode(pos, end); @@ -384,8 +383,41 @@ uint8_t* CompoundItem::encode(uint8_t* pos, const uint8_t* end) const { return pos; } -void CompoundItem::encode(EncodeCallback encodeCallback) const { - encodeHeader(addlInfo(), encodeCallback); +void Array::encode(EncodeCallback encodeCallback) const { + encodeHeader(size(), encodeCallback); + for (auto& entry : mEntries) { + entry->encode(encodeCallback); + } +} + +std::unique_ptr<Item> Array::clone() const { + auto res = std::make_unique<Array>(); + for (size_t i = 0; i < mEntries.size(); i++) { + res->add(mEntries[i]->clone()); + } + return res; +} + +bool Map::operator==(const Map& other) const& { + return size() == other.size() + // Can't use vector::operator== because the contents are pointers. std::equal lets us + // provide a predicate that does the dereferencing. + && std::equal(mEntries.begin(), mEntries.end(), other.mEntries.begin(), + [](auto& a, auto& b) -> bool { return *a == *b; }); +} + +uint8_t* Map::encode(uint8_t* pos, const uint8_t* end) const { + pos = encodeHeader(size(), pos, end); + if (!pos) return nullptr; + for (auto& entry : mEntries) { + pos = entry->encode(pos, end); + if (!pos) return nullptr; + } + return pos; +} + +void Map::encode(EncodeCallback encodeCallback) const { + encodeHeader(size(), encodeCallback); for (auto& entry : mEntries) { entry->encode(encodeCallback); } @@ -455,12 +487,20 @@ std::unique_ptr<Item> Map::clone() const { return res; } -std::unique_ptr<Item> Array::clone() const { - auto res = std::make_unique<Array>(); - for (size_t i = 0; i < mEntries.size(); i++) { - res->add(mEntries[i]->clone()); - } - return res; +bool Semantic::operator==(const Semantic& other) const& { + assertInvariant(); + return *mEntries.front() == *other.mEntries.front(); +} + +uint8_t* Semantic::encode(uint8_t* pos, const uint8_t* end) const { + pos = encodeHeader(value(), pos, end); + if (!pos) return nullptr; + return mEntries.front()->encode(pos, end); +} + +void Semantic::encode(EncodeCallback encodeCallback) const { + encodeHeader(value(), encodeCallback); + mEntries.front()->encode(encodeCallback); } void Semantic::assertInvariant() const { diff --git a/src/cppbor_parse.cpp b/src/cppbor_parse.cpp index 357b9ee..488f8c7 100644 --- a/src/cppbor_parse.cpp +++ b/src/cppbor_parse.cpp @@ -280,10 +280,7 @@ class FullParseClient : public ParseClient { // Starting a new compound data item, i.e. a new parent. Save it on the parent stack. // It's safe to save a raw pointer because the unique_ptr is guaranteed to stay in // existence until the corresponding itemEnd() call. -#if __has_feature(cxx_rtti) - assert(dynamic_cast<CompoundItem*>(item.get())); -#endif - mParentStack.push(static_cast<CompoundItem*>(item.get())); + mParentStack.push(item.get()); return this; } else { appendToLastParent(std::move(item)); @@ -336,7 +333,7 @@ class FullParseClient : public ParseClient { } std::unique_ptr<Item> mTheItem; - std::stack<CompoundItem*> mParentStack; + std::stack<Item*> mParentStack; const uint8_t* mPosition = nullptr; std::string mErrorMessage; }; |