1/* Copyright 2015 OpenMarket Ltd
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef OLM_PICKLE_HH_
16#define OLM_PICKLE_HH_
17
18#include "olm/list.hh"
19#include "olm/crypto.h"
20
21#include <cstring>
22#include <cstdint>
23
24/* Convenience macro for checking the return value of internal unpickling
25 * functions and returning early on failure. */
26#ifndef UNPICKLE_OK
27#define UNPICKLE_OK(x) do { if (!(x)) return nullptr; } while(0)
28#endif
29
30namespace olm {
31
32inline std::size_t pickle_length(
33 const std::uint32_t & value
34) {
35 return 4;
36}
37
38std::uint8_t * pickle(
39 std::uint8_t * pos,
40 std::uint32_t value
41);
42
43std::uint8_t const * unpickle(
44 std::uint8_t const * pos, std::uint8_t const * end,
45 std::uint32_t & value
46);
47
48
49inline std::size_t pickle_length(
50 const std::uint8_t & value
51) {
52 return 1;
53}
54
55std::uint8_t * pickle(
56 std::uint8_t * pos,
57 std::uint8_t value
58);
59
60std::uint8_t const * unpickle(
61 std::uint8_t const * pos, std::uint8_t const * end,
62 std::uint8_t & value
63);
64
65
66inline std::size_t pickle_length(
67 const bool & value
68) {
69 return 1;
70}
71
72std::uint8_t * pickle(
73 std::uint8_t * pos,
74 bool value
75);
76
77std::uint8_t const * unpickle(
78 std::uint8_t const * pos, std::uint8_t const * end,
79 bool & value
80);
81
82
83template<typename T, std::size_t max_size>
84std::size_t pickle_length(
85 olm::List<T, max_size> const & list
86) {
87 std::size_t length = pickle_length(value: std::uint32_t(list.size()));
88 for (auto const & value : list) {
89 length += pickle_length(value);
90 }
91 return length;
92}
93
94
95template<typename T, std::size_t max_size>
96std::uint8_t * pickle(
97 std::uint8_t * pos,
98 olm::List<T, max_size> const & list
99) {
100 pos = pickle(pos, value: std::uint32_t(list.size()));
101 for (auto const & value : list) {
102 pos = pickle(pos, value);
103 }
104 return pos;
105}
106
107
108template<typename T, std::size_t max_size>
109std::uint8_t const * unpickle(
110 std::uint8_t const * pos, std::uint8_t const * end,
111 olm::List<T, max_size> & list
112) {
113 std::uint32_t size;
114
115 pos = unpickle(pos, end, value&: size);
116 if (!pos) {
117 return nullptr;
118 }
119
120 while (size-- && pos != end) {
121 T * value = list.insert(list.end());
122 pos = unpickle(pos, end, *value);
123
124 if (!pos) {
125 return nullptr;
126 }
127 }
128
129 return pos;
130}
131
132
133std::uint8_t * pickle_bytes(
134 std::uint8_t * pos,
135 std::uint8_t const * bytes, std::size_t bytes_length
136);
137
138std::uint8_t const * unpickle_bytes(
139 std::uint8_t const * pos, std::uint8_t const * end,
140 std::uint8_t * bytes, std::size_t bytes_length
141);
142
143
144std::size_t pickle_length(
145 const _olm_curve25519_public_key & value
146);
147
148
149std::uint8_t * pickle(
150 std::uint8_t * pos,
151 const _olm_curve25519_public_key & value
152);
153
154
155std::uint8_t const * unpickle(
156 std::uint8_t const * pos, std::uint8_t const * end,
157 _olm_curve25519_public_key & value
158);
159
160
161std::size_t pickle_length(
162 const _olm_curve25519_key_pair & value
163);
164
165
166std::uint8_t * pickle(
167 std::uint8_t * pos,
168 const _olm_curve25519_key_pair & value
169);
170
171
172std::uint8_t const * unpickle(
173 std::uint8_t const * pos, std::uint8_t const * end,
174 _olm_curve25519_key_pair & value
175);
176
177} // namespace olm
178
179
180
181
182#endif /* OLM_PICKLE_HH */
183