20 #ifndef GEODE_SERIALIZER_H_
21 #define GEODE_SERIALIZER_H_
24 #include <type_traits>
25 #include <unordered_map>
26 #include <unordered_set>
30 #include "DataOutput.hpp"
31 #include "internal/geode_globals.hpp"
36 namespace serializer {
60 const uint8_t* bytes, int32_t len) {
70 const int8_t* bytes, int32_t len) {
148 std::vector<bool>::reference value) {
172 output.
writeInt(
static_cast<int16_t
>(value));
181 std::string& value) {
182 value = input.readString();
186 const std::string& value) {
187 output.writeString(value);
190 template <
typename TObj,
191 typename std::enable_if<std::is_base_of<Serializable, TObj>::value,
192 Serializable>::type* =
nullptr>
194 const std::shared_ptr<TObj>& value) {
198 template <
typename TObj,
199 typename std::enable_if<std::is_base_of<Serializable, TObj>::value,
200 Serializable>::type* =
nullptr>
202 std::shared_ptr<TObj>& value) {
203 value = std::dynamic_pointer_cast<TObj>(input.
readObject());
208 template <
typename TObj,
typename TLen>
210 const TObj* array, TLen len) {
211 if (array ==
nullptr) {
212 output.
write(
static_cast<int8_t
>(-1));
215 const TObj* endArray = array + len;
216 while (array < endArray) {
217 writeObject(output, *array++);
222 template <
typename TObj>
224 const std::vector<TObj>& array) {
226 for (
auto&& obj : array) {
227 writeObject(output, obj);
231 template <
typename TObj>
232 inline std::vector<TObj> readArrayObject(
234 std::vector<TObj> array;
238 for (
auto&& obj : array) {
239 readObject(input, obj);
245 template <
typename TObj,
typename TLen>
250 _GEODE_NEW(array, TObj[len]);
251 TObj* startArray = array;
252 TObj* endArray = array + len;
253 while (startArray < endArray) {
254 readObject(input, *startArray++);
261 template <
typename TObj,
262 typename std::enable_if<!std::is_base_of<Serializable, TObj>::value,
263 Serializable>::type* =
nullptr>
264 inline size_t objectArraySize(
const std::vector<TObj>& array) {
265 return sizeof(TObj) * array.size();
268 template <
typename TObj,
269 typename std::enable_if<std::is_base_of<Serializable, TObj>::value,
270 Serializable>::type* =
nullptr>
271 inline size_t objectArraySize(
const std::vector<TObj>& array) {
273 for (
auto obj : array) {
274 size += obj.objectArraySize();
276 size +=
sizeof(TObj) * array.size();
280 template <
typename TObj,
typename TLen,
281 typename std::enable_if<!std::is_base_of<Serializable, TObj>::value,
282 Serializable>::type* =
nullptr>
283 inline size_t objectSize(
const TObj*, TLen len) {
284 return sizeof(TObj) * len;
287 template <
typename TObj,
typename TLen,
288 typename std::enable_if<std::is_base_of<Serializable, TObj>::value,
289 Serializable>::type* =
nullptr>
290 inline size_t objectSize(
const TObj* array, TLen len) {
292 const TObj* endArray = array + len;
293 while (array < endArray) {
294 if (*array !=
nullptr) {
295 size += (*array)->objectSize();
299 size +=
sizeof(TObj) * len;
305 template <
typename TObj,
typename Allocator>
307 const std::vector<TObj, Allocator>& value) {
309 for (
const auto& v : value) {
310 writeObject(output, v);
314 inline size_t objectSize(
const std::vector<std::shared_ptr<Cacheable>>& value) {
315 size_t objectSize = 0;
316 for (
const auto& iter : value) {
318 objectSize += iter->objectSize();
321 objectSize +=
sizeof(std::shared_ptr<Cacheable>) * value.size();
325 template <
typename TObj,
typename _tail>
327 std::vector<TObj, _tail>& value) {
331 for (int32_t index = 0; index < len; index++) {
332 readObject(input, obj);
333 value.push_back(obj);
338 template <
typename TKey,
typename TValue,
typename Hash,
typename KeyEqual,
340 inline void writeObject(
342 const std::unordered_map<TKey, TValue, Hash, KeyEqual, Allocator>& value) {
344 for (
const auto& iter : value) {
345 writeObject(output, iter.first);
346 writeObject(output, iter.second);
350 inline size_t objectSize(
const HashMapOfCacheable& value) {
351 auto objectSize = (
sizeof(std::shared_ptr<CacheableKey>) +
352 sizeof(std::shared_ptr<Cacheable>)) *
354 for (
const auto& iter : value) {
355 objectSize += iter.first->objectSize();
357 objectSize += iter.second->objectSize();
363 template <
typename TKey,
typename TValue,
typename Hash,
typename KeyEqual,
365 inline void readObject(
367 std::unordered_map<TKey, TValue, Hash, KeyEqual, Allocator>& value) {
370 std::shared_ptr<Serializable> key;
371 std::shared_ptr<Serializable> val;
372 for (int32_t index = 0; index < len; index++) {
373 readObject(input, key);
374 readObject(input, val);
376 std::dynamic_pointer_cast<typename TKey::element_type>(key),
377 std::dynamic_pointer_cast<typename TValue::element_type>(val));
381 template <
typename TKey,
typename Hash,
typename KeyEqual,
typename Allocator>
382 inline void writeObject(
384 const std::unordered_set<TKey, Hash, KeyEqual, Allocator>& value) {
386 for (
const auto& iter : value) {
387 writeObject(output, iter);
391 inline size_t objectSize(
const HashSetOfCacheableKey& value) {
392 auto objectSize =
sizeof(std::shared_ptr<CacheableKey>) * value.size();
393 for (
const auto& iter : value) {
395 objectSize += iter->objectSize();
401 template <
typename TKey,
typename Hash,
typename KeyEqual,
typename Allocator>
402 inline void readObject(
404 std::unordered_set<TKey, Hash, KeyEqual, Allocator>& value) {
407 std::shared_ptr<Serializable> key;
408 for (int32_t index = 0; index < len; index++) {
409 readObject(input, key);
410 value.insert(std::dynamic_pointer_cast<typename TKey::element_type>(key));
417 template <
typename TObj>
418 inline TObj zeroObject() {
423 inline bool zeroObject<bool>() {
428 inline double zeroObject<double>() {
433 inline float zeroObject<float>() {
441 #endif // GEODE_SERIALIZER_H_