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/utility.hpp"
8#include "datum.hpp"
9#include "base_n.hpp"
10#include "../macros.hpp"
11#include <string>
12#include <limits>
13
14hi_export_module(hikogui.codec.pickle);
15
16hi_export namespace hi { inline namespace v1 {
17
23hi_export template<typename T>
24struct pickle {
30 [[nodiscard]] datum encode(T const& rhs) const noexcept
31 {
32 hi_static_not_implemented();
33 }
34
35 [[nodiscard]] datum encode(T const& rhs) const noexcept
36 requires(std::has_unique_object_representations_v<T> and not std::is_pointer_v<T>)
37 {
38 auto *rhs_ = reinterpret_cast<std::byte const *>(&rhs);
39 return datum{base64::encode({rhs_, sizeof(rhs_)})};
40 }
41
48 [[nodiscard]] T decode(datum rhs) const
49 {
50 hi_static_not_implemented();
51 }
52
53 [[nodiscard]] T decode(datum rhs) const
54 requires(std::has_unique_object_representations_v<T> and not std::is_pointer_v<T>)
55 {
56 if (auto *b = get_if<std::string>(rhs)) {
57 auto tmp = base64::decode(*b);
58 if (tmp.size() != sizeof(T)) {
59 throw parse_error(
60 std::format("Length of base64 encoded object is {}, expected length {}", tmp.size(), sizeof(T)));
61 }
62
63 auto r = T{};
64 std::memcpy(&r, tmp.data(), sizeof(T));
65 return r;
66
67 } else {
68 throw parse_error(std::format("Expecting std::string to be encoded as a base64-string, got {}", rhs));
69 }
70 }
71};
72
73hi_export template<numeric_integral T>
74struct pickle<T> {
75 [[nodiscard]] datum encode(T const& rhs) const noexcept
76 {
77 return datum{rhs};
78 }
79
80 [[nodiscard]] T decode(datum rhs) const
81 {
82 if (auto *i = get_if<long long>(rhs)) {
84 throw parse_error(std::format("Encoded value is to out of range, got {}", rhs));
85 }
86 return static_cast<T>(*i);
87 } else {
88 throw parse_error(std::format("Expecting numeric integrals to be encoded as a long long, got {}", rhs));
89 }
90 }
91};
92
93hi_export template<std::floating_point T>
94struct pickle<T> {
95 [[nodiscard]] datum encode(T const& rhs) const noexcept
96 {
97 return datum{rhs};
98 }
99
100 [[nodiscard]] T decode(datum rhs) const
101 {
102 if (auto *f = get_if<double>(rhs)) {
103 return static_cast<T>(*f);
104
105 } else if (auto *i = get_if<long long>(rhs)) {
106 return static_cast<T>(*i);
107
108 } else {
109 throw parse_error(std::format("Expecting floating point to be encoded as a double or long long, got {}", rhs));
110 }
111 }
112};
113
114hi_export template<>
115struct pickle<bool> {
116 [[nodiscard]] datum encode(bool const& rhs) const noexcept
117 {
118 return datum{rhs};
119 }
120
121 [[nodiscard]] bool decode(datum rhs) const
122 {
123 if (auto *b = get_if<bool>(rhs)) {
124 return *b;
125
126 } else {
127 throw parse_error(std::format("Expecting bool to be encoded as a bool, got {}", rhs));
128 }
129 }
130};
131
132hi_export template<>
133struct pickle<std::string> {
134 [[nodiscard]] datum encode(std::string const& rhs) const noexcept
135 {
136 return datum{rhs};
137 }
138
139 [[nodiscard]] std::string decode(datum rhs) const
140 {
141 if (auto *b = get_if<std::string>(rhs)) {
142 return *b;
143
144 } else {
145 throw parse_error(std::format("Expecting std::string to be encoded as a string, got {}", rhs));
146 }
147 }
148};
149
150}} // namespace hi::v1
STL namespace.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
A dynamic data type.
Definition datum.hpp:198
Encode and decode a type to and from a UTF-8 string.
Definition pickle.hpp:24
T decode(datum rhs) const
Decode a UTF-8 string into a value of a given type.
Definition pickle.hpp:48
datum encode(T const &rhs) const noexcept
Encode the value of a type into a UTF-8 string.
Definition pickle.hpp:30
Exception thrown during parsing on an error.
Definition exception_intf.hpp:48
T memcpy(T... args)