Skip to content

Commit 9dc996a

Browse files
Feature/cbor map (#542)
* respect cbor map order Signed-off-by: Alexey Chernyshov <[email protected]>
1 parent 6693708 commit 9dc996a

File tree

3 files changed

+545
-461
lines changed

3 files changed

+545
-461
lines changed

core/codec/cbor/cbor_encode_stream.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
#include "common/cmp.hpp"
1010

1111
namespace fc::codec::cbor {
12+
CborEncodeStream &CborOrderedMap::operator[](const std::string &key) {
13+
// remove old value if present and push new one
14+
erase(std::remove_if(
15+
begin(), end(), [&key](const auto &p) { return p.first == key; }),
16+
end());
17+
emplace_back(key, CborEncodeStream{});
18+
return back().second;
19+
}
20+
1221
CborEncodeStream &CborEncodeStream::operator<<(const Bytes &bytes) {
1322
return *this << gsl::make_span(bytes);
1423
}
@@ -100,6 +109,21 @@ namespace fc::codec::cbor {
100109
return *this;
101110
}
102111

112+
CborEncodeStream &CborEncodeStream::operator<<(const CborOrderedMap &map) {
113+
addCount(1);
114+
writeMap(data_, map.size());
115+
const auto count{count_};
116+
for (const auto &pair : map) {
117+
if (pair.second.count() != 1) {
118+
outcome::raise(CborEncodeError::kExpectedMapValueSingle);
119+
}
120+
*this << common::span::bytestr(common::span::cbytes(pair.first));
121+
*this << pair.second;
122+
}
123+
count_ = count;
124+
return *this;
125+
}
126+
103127
CborEncodeStream &CborEncodeStream::operator<<(std::nullptr_t) {
104128
addCount(1);
105129
writeNull(data_);
@@ -115,6 +139,10 @@ namespace fc::codec::cbor {
115139
return result;
116140
}
117141

142+
size_t CborEncodeStream::count() const {
143+
return count_;
144+
}
145+
118146
CborEncodeStream CborEncodeStream::list() {
119147
CborEncodeStream stream;
120148
stream.is_list_ = true;
@@ -125,6 +153,10 @@ namespace fc::codec::cbor {
125153
return {};
126154
}
127155

156+
CborOrderedMap CborEncodeStream::orderedMap() {
157+
return {};
158+
}
159+
128160
CborEncodeStream CborEncodeStream::wrap(BytesIn data, size_t count) {
129161
CborEncodeStream s;
130162
copy(s.data_, data);

core/codec/cbor/cbor_encode_stream.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
#include "primitives/cid/cid.hpp"
1616

1717
namespace fc::codec::cbor {
18+
class CborEncodeStream;
19+
20+
/** Cbor map with respect for key order */
21+
struct CborOrderedMap
22+
: public std::vector<std::pair<std::string, CborEncodeStream>> {
23+
CborEncodeStream &operator[](const std::string &key);
24+
};
25+
1826
/** Encodes CBOR */
1927
class CborEncodeStream {
2028
public:
@@ -98,17 +106,23 @@ namespace fc::codec::cbor {
98106
CborEncodeStream &operator<<(const BlockParentCbCids &parents);
99107
/** Encodes list container encode substream */
100108
CborEncodeStream &operator<<(const CborEncodeStream &other);
101-
/** Encodes map container encode substream map */
109+
/** Encodes map container encode substream map with canonical order */
102110
CborEncodeStream &operator<<(
103111
const std::map<std::string, CborEncodeStream> &map);
112+
/** Encodes map container encode substream map with order respect */
113+
CborEncodeStream &operator<<(const CborOrderedMap &map);
104114
/** Encodes null */
105115
CborEncodeStream &operator<<(std::nullptr_t);
106116
/** Returns CBOR bytes of encoded elements */
107117
Bytes data() const;
118+
/** Returns the number of elements */
119+
size_t count() const;
108120
/** Creates list container encode substream */
109121
static CborEncodeStream list();
110122
/** Creates map container encode substream map */
111123
static std::map<std::string, CborEncodeStream> map();
124+
/** Creates map container encode substream map */
125+
static CborOrderedMap orderedMap();
112126
/** Wraps CBOR bytes */
113127
static CborEncodeStream wrap(BytesIn data, size_t count);
114128

0 commit comments

Comments
 (0)