refactor: use more portable types in cbor matching

This commit is contained in:
CJ van den Berg 2024-02-28 21:02:03 +01:00
parent f82f9f6f5d
commit 522813dae1
3 changed files with 118 additions and 124 deletions

View file

@ -1,6 +1,5 @@
#pragma once
#include <cstdint>
#include <functional>
#include <ostream>
#include <string>
@ -55,48 +54,27 @@ private:
static auto decode_array_header(iter &, const iter &) -> size_t;
static auto decode_map_header(iter &, const iter &) -> size_t;
[[nodiscard]] static auto match_value(iter &, const iter &, const extractor &)
-> bool;
// clang-format off
[[nodiscard]] static auto match_value(iter &, const iter &, const extractor &) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, type) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, int64_t) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, signed long long int) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, unsigned long long int) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, bool) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &,
const std::string &) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &,
const std::string_view) -> bool;
[[nodiscard]] static auto match_value(iter &b, const iter &e, const char *s)
-> bool {
[[nodiscard]] static auto match_value(iter &, const iter &, const std::string &) -> bool;
[[nodiscard]] static auto match_value(iter &, const iter &, const std::string_view) -> bool;
[[nodiscard]] static auto match_value(iter &b, const iter &e, const char *s) -> bool {
return match_value(b, e, std::string(s));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, uint64_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, int32_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, uint32_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, int16_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, uint16_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, int8_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, uint8_t v)
-> bool {
return match_value(b, e, static_cast<int64_t>(v));
}
[[nodiscard]] static auto match_value(iter &b, const iter &e, unsigned long int v) -> bool { return match_value(b, e, static_cast<unsigned long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, unsigned int v) -> bool { return match_value(b, e, static_cast<unsigned long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, unsigned short int v) -> bool { return match_value(b, e, static_cast<unsigned long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, unsigned char v) -> bool { return match_value(b, e, static_cast<unsigned long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, signed long int v) -> bool { return match_value(b, e, static_cast<signed long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, signed int v) -> bool { return match_value(b, e, static_cast<signed long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, signed short int v) -> bool { return match_value(b, e, static_cast<signed long long int>(v)); }
[[nodiscard]] static auto match_value(iter &b, const iter &e, signed char v) -> bool { return match_value(b, e, static_cast<signed long long int>(v)); }
// clang-format on
template <typename T>
[[nodiscard]] static auto match_next(size_t n, iter &b, const iter &e, T &&p)
@ -186,7 +164,7 @@ public:
auto push_string(const std::string &) -> buffer &;
auto push_string(const std::string_view &s) -> buffer &;
auto push_int(int64_t value) -> buffer & {
auto push_int(signed long long int value) -> buffer & {
if (value < 0) {
push_typed_val(1, -(value + 1));
} else {
@ -194,28 +172,29 @@ public:
}
return *this;
}
auto push(const long long &i) -> buffer & { return push_int(i); }
auto push(const int64_t &i) -> buffer & { return push_int(i); }
auto push(const int32_t &i) -> buffer & { return push_int(i); }
auto push(const int16_t &i) -> buffer & { return push_int(i); }
auto push(const int8_t &i) -> buffer & { return push_int(i); }
auto push_uint(unsigned long long int value) -> buffer & {
push_typed_val(0, value);
return *this;
}
// clang-format off
auto push(const unsigned long long int &i) -> buffer & { return push_uint(i); }
auto push(const unsigned long int &i) -> buffer & { return push_uint(i); }
auto push(const unsigned int &i) -> buffer & { return push_uint(i); }
auto push(const unsigned short int &i) -> buffer & { return push_uint(i); }
auto push(const unsigned char &i) -> buffer & { return push_uint(i); }
auto push(const signed long long int &i) -> buffer & { return push_int(i); }
auto push(const signed long int &i) -> buffer & { return push_int(i); }
auto push(const signed int &i) -> buffer & { return push_int(i); }
auto push(const signed short int &i) -> buffer & { return push_int(i); }
auto push(const signed char &i) -> buffer & { return push_int(i); }
auto push(const bool &v) -> buffer & { return push_bool(v); }
auto push(const std::string &s) -> buffer & { return push_string(s); }
auto push(const std::string_view &s) -> buffer & { return push_string(s); }
auto push(char *s) -> buffer & { return push_string(std::string_view(s)); }
auto push(const char *s) -> buffer & {
return push_string(std::string_view(s));
}
auto push_uint(uint64_t value) -> buffer & {
push_typed_val(0, value);
return *this;
}
auto push(const unsigned long long &i) -> buffer & { return push_uint(i); }
auto push(const uint64_t &i) -> buffer & { return push_uint(i); }
auto push(const uint32_t &i) -> buffer & { return push_uint(i); }
auto push(const uint16_t &i) -> buffer & { return push_uint(i); }
auto push(const uint8_t &i) -> buffer & { return push_uint(i); }
auto push(const char *s) -> buffer & { return push_string(std::string_view(s)); }
// clang-format on
template <typename T> auto push(const T &a) -> buffer & {
a.to_cbor(*this);
@ -279,18 +258,20 @@ public:
[[nodiscard]] auto type_() const -> type;
operator type() const; // NOLINT
operator int64_t() const; // NOLINT
operator uint64_t() const; // NOLINT
operator int32_t() const; // NOLINT
operator uint32_t() const; // NOLINT
operator int16_t() const; // NOLINT
operator uint16_t() const; // NOLINT
operator int8_t() const; // NOLINT
operator uint8_t() const; // NOLINT
operator bool() const; // NOLINT
operator std::string_view() const; // NOLINT
operator buffer::range() const; // NOLINT
operator type() const; // NOLINT
operator unsigned long long int() const; // NOLINT
operator unsigned long int() const; // NOLINT
operator unsigned int() const; // NOLINT
operator unsigned short int() const; // NOLINT
operator unsigned char() const; // NOLINT
operator signed long long int() const; // NOLINT
operator signed long int() const; // NOLINT
operator signed int() const; // NOLINT
operator signed short int() const; // NOLINT
operator signed char() const; // NOLINT
operator bool() const; // NOLINT
operator std::string_view() const; // NOLINT
operator buffer::range() const; // NOLINT
struct unvisitable_type {
cbor::type t;
@ -423,15 +404,19 @@ template <typename... Ts> auto map(Ts &&...parms) -> buffer {
}
auto extract(type &) -> buffer::extractor;
auto extract(int64_t &) -> buffer::extractor;
auto extract(unsigned long long &) -> buffer::extractor;
auto extract(uint64_t &) -> buffer::extractor;
auto extract(int32_t &) -> buffer::extractor;
auto extract(uint32_t &) -> buffer::extractor;
auto extract(int16_t &) -> buffer::extractor;
auto extract(uint16_t &) -> buffer::extractor;
auto extract(int8_t &) -> buffer::extractor;
auto extract(uint8_t &) -> buffer::extractor;
auto extract(signed long long int &) -> buffer::extractor;
auto extract(signed long int &) -> buffer::extractor;
auto extract(signed int &) -> buffer::extractor;
auto extract(signed short int &) -> buffer::extractor;
auto extract(signed char &) -> buffer::extractor;
auto extract(unsigned long long int &) -> buffer::extractor;
auto extract(unsigned long int &) -> buffer::extractor;
auto extract(unsigned int &) -> buffer::extractor;
auto extract(unsigned short int &) -> buffer::extractor;
auto extract(unsigned char &) -> buffer::extractor;
auto extract(bool &) -> buffer::extractor;
auto extract(std::string &) -> buffer::extractor;
auto extract(std::string_view &) -> buffer::extractor;

View file

@ -411,7 +411,7 @@ static auto decode_string(uint8_t type, iter &b, const iter &e) -> string_view {
return {
reinterpret_cast< // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
const char *>(s),
sz};
static_cast<size_t>(sz)};
}
static auto decode_bytes(uint8_t type, iter &b, const iter &e) -> string_view {
@ -570,7 +570,8 @@ auto buffer::match_value(iter &b, const iter &e, type t) -> bool {
return false;
}
static auto match_uint(iter &b, const iter &e, uint64_t &val) -> bool {
static auto match_uint(iter &b, const iter &e, unsigned long long int &val)
-> bool {
const auto [major, minor, type] = decode_type(b, e);
if (major != 0)
return false;
@ -578,7 +579,8 @@ static auto match_uint(iter &b, const iter &e, uint64_t &val) -> bool {
return true;
}
static auto match_int(iter &b, const iter &e, int64_t &val) -> bool {
static auto match_int(iter &b, const iter &e, signed long long int &val)
-> bool {
const auto [major, minor, type] = decode_type(b, e);
switch (major) {
case 0: // positive integer
@ -595,8 +597,17 @@ static auto match_int(iter &b, const iter &e, int64_t &val) -> bool {
return true;
}
auto buffer::match_value(iter &b, const iter &e, int64_t lit) -> bool {
int64_t val{0};
auto buffer::match_value(iter &b, const iter &e, unsigned long long int lit)
-> bool {
unsigned long long int val{0};
if (match_uint(b, e, val))
return val == lit;
return false;
}
auto buffer::match_value(iter &b, const iter &e, signed long long int lit)
-> bool {
signed long long int val{0};
if (match_int(b, e, val))
return val == lit;
return false;
@ -660,10 +671,9 @@ auto extract(type &t) -> buffer::extractor {
template <typename T> static auto extract_int(T &i) -> buffer::extractor {
return [&i](iter &b, const iter &e) {
int64_t i_{};
signed long long int i_{};
if (match_int(b, e, i_)) {
if (i_ < int64_t(numeric_limits<T>::min()) or
i_ > int64_t(numeric_limits<T>::max()))
if (i_ < numeric_limits<T>::min() or i_ > numeric_limits<T>::max())
return false;
i = i_;
return true;
@ -671,19 +681,22 @@ template <typename T> static auto extract_int(T &i) -> buffer::extractor {
return false;
};
}
auto extract(int64_t &i) -> buffer::extractor { return extract_int(i); }
auto extract(int32_t &i) -> buffer::extractor { return extract_int(i); }
auto extract(int16_t &i) -> buffer::extractor { return extract_int(i); }
auto extract(int8_t &i) -> buffer::extractor { return extract_int(i); }
// clang-format off
auto extract(signed long long int &i) -> buffer::extractor { return extract_int(i); }
auto extract(signed long int &i) -> buffer::extractor { return extract_int(i); }
auto extract(signed int &i) -> buffer::extractor { return extract_int(i); }
auto extract(signed short int &i) -> buffer::extractor { return extract_int(i); }
auto extract(signed char &i) -> buffer::extractor { return extract_int(i); }
// clang-format on
auto extract(uint64_t &i) -> buffer::extractor {
auto extract(unsigned long long int &i) -> buffer::extractor {
return [&i](iter &b, const iter &e) { return match_uint(b, e, i); };
}
template <typename T> static auto extract_uint(T &i) -> buffer::extractor {
return [&i](iter &b, const iter &e) {
uint64_t i_{};
unsigned long long int i_{};
if (match_uint(b, e, i_)) {
if (i_ > uint64_t(numeric_limits<T>::max()))
if (i_ > numeric_limits<T>::max())
return false;
i = i_;
return true;
@ -691,12 +704,12 @@ template <typename T> static auto extract_uint(T &i) -> buffer::extractor {
return false;
};
}
auto extract(unsigned long long &i) -> buffer::extractor {
return extract_uint(i);
}
auto extract(uint32_t &i) -> buffer::extractor { return extract_uint(i); }
auto extract(uint16_t &i) -> buffer::extractor { return extract_uint(i); }
auto extract(uint8_t &i) -> buffer::extractor { return extract_uint(i); }
// clang-format off
auto extract(unsigned long int &i) -> buffer::extractor { return extract_uint(i); }
auto extract(unsigned int &i) -> buffer::extractor { return extract_uint(i); }
auto extract(unsigned short int &i) -> buffer::extractor { return extract_uint(i); }
auto extract(unsigned char &i) -> buffer::extractor { return extract_uint(i); }
// clang-format on
auto extract(bool &val) -> buffer::extractor {
return [&val](iter &b, const iter &e) { return match_bool(b, e, val); };
@ -872,7 +885,8 @@ auto buffer::range::to_json(ostream &os) const -> void {
extern "C" void cbor_to_json(cbor_buffer buf, cbor_to_json_callback cb) {
auto cbor = cbor::buffer();
const uint8_t *data = buf.base;
std::copy(data, data + buf.len, back_inserter(cbor)); // NOLINT(*-pointer-arithmetic)
std::copy(data, data + buf.len,
back_inserter(cbor)); // NOLINT(*-pointer-arithmetic)
auto json = cbor.to_json();
cb({json.data(), json.size()});
}
@ -900,27 +914,22 @@ template <typename T> static auto get(iter b, const iter &e) -> T {
extract(val)(b, e);
return val;
}
// clang-format off
buffer::value_accessor::operator type() const { return get<type>(b, e); }
buffer::value_accessor::operator int64_t() const { return get<int64_t>(b, e); }
buffer::value_accessor::operator uint64_t() const { return get<int64_t>(b, e); }
buffer::value_accessor::operator int32_t() const {
return get<int64_t>(b, e); // NOLINT(*-narrowing-conversions)
}
buffer::value_accessor::operator uint32_t() const { return get<int64_t>(b, e); }
buffer::value_accessor::operator int16_t() const {
return get<int64_t>(b, e); // NOLINT(*-narrowing-conversions)
}
buffer::value_accessor::operator uint16_t() const { return get<int64_t>(b, e); }
buffer::value_accessor::operator int8_t() const {
return get<int64_t>(b, e); // NOLINT(*-narrowing-conversions)
}
buffer::value_accessor::operator uint8_t() const { return get<int64_t>(b, e); }
buffer::value_accessor::operator unsigned long long int() const { return get<unsigned long long int>(b, e); }
buffer::value_accessor::operator unsigned long int() const { return get<unsigned long int>(b, e); }
buffer::value_accessor::operator unsigned int() const { return get<unsigned int>(b, e); }
buffer::value_accessor::operator unsigned short int() const { return get<unsigned short int>(b, e); }
buffer::value_accessor::operator unsigned char() const { return get<unsigned char>(b, e); }
buffer::value_accessor::operator signed long long int() const { return get<signed long long int>(b, e); }
buffer::value_accessor::operator signed long int() const { return get<signed long int>(b, e); }
buffer::value_accessor::operator signed int() const { return get<signed int>(b, e); } // NOLINT(*-narrowing-conversions)
buffer::value_accessor::operator signed short int() const { return get<signed short int>(b, e); } // NOLINT(*-narrowing-conversions)
buffer::value_accessor::operator signed char() const { return get<signed char>(b, e); } // NOLINT(*-narrowing-conversions)
buffer::value_accessor::operator bool() const { return get<bool>(b, e); }
buffer::value_accessor::operator string_view() const {
return get<string_view>(b, e);
}
buffer::value_accessor::operator buffer::range() const {
return get<buffer::range>(b, e);
}
buffer::value_accessor::operator string_view() const { return get<string_view>(b, e); }
buffer::value_accessor::operator buffer::range() const { return get<buffer::range>(b, e); }
// clang-format on
} // namespace cbor

View file

@ -290,12 +290,12 @@ pub fn decodeArrayHeader(iter: *[]const u8) CborError!usize {
return 0;
if (t.major != 4)
return error.CborInvalidType;
return decodePInt(iter, t.minor);
return @intCast(try decodePInt(iter, t.minor));
}
fn decodeString(iter_: *[]const u8, minor: u5) CborError![]const u8 {
var iter = iter_.*;
const len = try decodePInt(&iter, minor);
const len: usize = @intCast(try decodePInt(&iter, minor));
if (iter.len < len)
return error.CborTooShort;
const s = iter[0..len];
@ -392,7 +392,7 @@ fn matchBoolValue(iter: *[]const u8, val: bool) CborError!bool {
}
fn skipString(iter: *[]const u8, minor: u5) CborError!void {
const len = try decodePInt(iter, minor);
const len: usize = @intCast(try decodePInt(iter, minor));
if (iter.len < len)
return error.CborTooShort;
iter.* = iter.*[len..];