HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
pickle.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "utility.hpp"
8#include "assert.hpp"
9#include "datum.hpp"
10#include "concepts.hpp"
11#include "codec/base_n.hpp"
12#include <string>
13#include <limits>
14
15namespace hi::inline v1 {
16
22template<typename T>
23struct pickle {
29 [[nodiscard]] datum encode(T const& rhs) const noexcept
30 {
31 hi_static_not_implemented();
32 }
33
34 [[nodiscard]] datum encode(T const& rhs) const noexcept
35 requires(std::has_unique_object_representations_v<T> and not std::is_pointer_v<T>)
36 {
37 auto *rhs_ = reinterpret_cast<std::byte const *>(&rhs);
38 return datum{base64::encode({rhs_, sizeof(rhs_)})};
39 }
40
47 [[nodiscard]] T decode(datum rhs) const
48 {
49 hi_static_not_implemented();
50 }
51
52 [[nodiscard]] T decode(datum rhs) const requires(std::has_unique_object_representations_v<T> and not std::is_pointer_v<T>)
53 {
54 if (auto *b = get_if<std::string>(rhs)) {
55 auto tmp = base64::decode(*b);
56 if (tmp.size() != sizeof(T)) {
57 throw parse_error(std::format("Length of base64 encoded object is {}, expected length {}", tmp.size(), sizeof(T)));
58 }
59
60 auto r = T{};
61 std::memcpy(&r, tmp.data(), sizeof(T));
62 return r;
63
64 } else {
65 throw parse_error(std::format("Expecting std::string to be encoded as a base64-string, got {}", rhs));
66 }
67 }
68};
69
70template<numeric_integral T>
71struct pickle<T> {
72 [[nodiscard]] datum encode(T const& rhs) const noexcept
73 {
74 return datum{rhs};
75 }
76
77 [[nodiscard]] T decode(datum rhs) const
78 {
79 if (auto *i = get_if<long long>(rhs)) {
81 throw parse_error(std::format("Encoded value is to out of range, got {}", rhs));
82 }
83 return static_cast<T>(*i);
84 } else {
85 throw parse_error(std::format("Expecting numeric integrals to be encoded as a long long, got {}", rhs));
86 }
87 }
88};
89
90template<std::floating_point T>
91struct pickle<T> {
92 [[nodiscard]] datum encode(T const& rhs) const noexcept
93 {
94 return datum{rhs};
95 }
96
97 [[nodiscard]] T decode(datum rhs) const
98 {
99 if (auto *f = get_if<double>(rhs)) {
100 return static_cast<T>(*f);
101
102 } else if (auto *i = get_if<long long>(rhs)) {
103 return static_cast<T>(*i);
104
105 } else {
106 throw parse_error(std::format("Expecting floating point to be encoded as a double or long long, got {}", rhs));
107 }
108 }
109};
110
111template<>
112struct pickle<bool> {
113 [[nodiscard]] datum encode(bool const& rhs) const noexcept
114 {
115 return datum{rhs};
116 }
117
118 [[nodiscard]] bool decode(datum rhs) const
119 {
120 if (auto *b = get_if<bool>(rhs)) {
121 return *b;
122
123 } else {
124 throw parse_error(std::format("Expecting bool to be encoded as a bool, got {}", rhs));
125 }
126 }
127};
128
129template<>
130struct pickle<std::string> {
131 [[nodiscard]] datum encode(std::string const& rhs) const noexcept
132 {
133 return datum{rhs};
134 }
135
136 [[nodiscard]] std::string decode(datum rhs) const
137 {
138 if (auto *b = get_if<std::string>(rhs)) {
139 return *b;
140
141 } else {
142 throw parse_error(std::format("Expecting std::string to be encoded as a string, got {}", rhs));
143 }
144 }
145};
146
147
148} // namespace hi::inline v1
Utilities used by the HikoGUI library itself.
STL namespace.
DOXYGEN BUG.
Definition algorithm.hpp:15
A dynamic data type.
Definition datum.hpp:224
Encode and decode a type to and from a UTF-8 string.
Definition pickle.hpp:23
datum encode(T const &rhs) const noexcept
Encode the value of a type into a UTF-8 string.
Definition pickle.hpp:29
T decode(datum rhs) const
Decode a UTF-8 string into a value of a given type.
Definition pickle.hpp:47
T memcpy(T... args)