LCOV - code coverage report
Current view: top level - source/simulation2/serialization - SerializedTypes.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 60 89 67.4 %
Date: 2023-01-19 00:18:29 Functions: 12 54 22.2 %

          Line data    Source code
       1             : /* Copyright (C) 2020 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #ifndef INCLUDED_SERIALIZED_TYPES
      19             : #define INCLUDED_SERIALIZED_TYPES
      20             : 
      21             : /**
      22             :  * @file
      23             :  * Provide specializations for some generic types and containers.
      24             :  */
      25             : 
      26             : #include "simulation2/serialization/SerializeTemplates.h"
      27             : 
      28             : #include "lib/types.h"
      29             : 
      30             : #include <array>
      31             : #include <map>
      32             : #include <set>
      33             : #include <string>
      34             : #include <unordered_map>
      35             : #include <vector>
      36             : 
      37             : template<typename T, size_t N>
      38             : struct SerializeHelper<std::array<T, N>>
      39             : {
      40           1 :     void operator()(ISerializer& serialize, const char* name, std::array<T, N>& value)
      41             :     {
      42           7 :         for (size_t i = 0; i < N; ++i)
      43           6 :             Serializer(serialize, name, value[i]);
      44           1 :     }
      45             : 
      46           0 :     void operator()(IDeserializer& deserialize, const char* name, std::array<T, N>& value)
      47             :     {
      48           0 :         for (size_t i = 0; i < N; ++i)
      49           0 :             Serializer(deserialize, name, value[i]);
      50           0 :     }
      51             : };
      52             : 
      53             : template<typename T>
      54             : struct SerializeHelper<std::vector<T>>
      55             : {
      56           2 :     void operator()(ISerializer& serialize, const char* name, std::vector<T>& value)
      57             :     {
      58           2 :         size_t len = value.size();
      59           2 :         serialize.NumberU32_Unbounded("length", (u32)len);
      60           9 :         for (size_t i = 0; i < len; ++i)
      61           7 :             Serializer(serialize, name, value[i]);
      62           2 :     }
      63             : 
      64           1 :     void operator()(IDeserializer& deserialize, const char* name, std::vector<T>& value)
      65             :     {
      66           1 :         value.clear();
      67             :         u32 len;
      68           1 :         deserialize.NumberU32_Unbounded("length", len);
      69           1 :         value.reserve(len); // TODO: watch out for out-of-memory
      70           2 :         for (size_t i = 0; i < len; ++i)
      71             :         {
      72           0 :             T el;
      73           1 :             Serializer(deserialize, name, el);
      74           1 :             value.emplace_back(el);
      75             :         }
      76           1 :     }
      77             : };
      78             : 
      79             : template<typename T>
      80             : struct SerializeHelper<std::set<T>>
      81             : {
      82          19 :     void operator()(ISerializer& serialize, const char* name, const std::set<T>& value)
      83             :     {
      84          19 :         serialize.NumberU32_Unbounded("size", static_cast<u32>(value.size()));
      85          24 :         for (const T& elem : value)
      86           5 :             Serializer(serialize, name, elem);
      87          19 :     }
      88             : 
      89           3 :     void operator()(IDeserializer& deserialize, const char* name, std::set<T>& value)
      90             :     {
      91           3 :         value.clear();
      92             :         u32 size;
      93           3 :         deserialize.NumberU32_Unbounded("size", size);
      94           3 :         for (size_t i = 0; i < size; ++i)
      95             :         {
      96             :             T el;
      97           0 :             Serializer(deserialize, name, el);
      98           0 :             value.emplace(std::move(el));
      99             :         }
     100           3 :     }
     101             : };
     102             : 
     103             : template<typename K, typename V>
     104             : struct SerializeHelper<std::map<K, V>>
     105             : {
     106             :     template<typename... Args>
     107           1 :     void operator()(ISerializer& serialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
     108             :     {
     109           1 :         size_t len = value.size();
     110           1 :         serialize.NumberU32_Unbounded("length", (u32)len);
     111           2 :         for (typename std::map<K, V>::iterator it = value.begin(); it != value.end(); ++it)
     112             :         {
     113           1 :             Serializer(serialize, "key", it->first, std::forward<Args>(args)...);
     114           1 :             Serializer(serialize, "value", it->second, std::forward<Args>(args)...);
     115             :         }
     116           1 :     }
     117             : 
     118             :     template<typename... Args>
     119           1 :     void operator()(IDeserializer& deserialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
     120             :     {
     121           1 :         value.clear();
     122             :         u32 len;
     123           1 :         deserialize.NumberU32_Unbounded("length", len);
     124           2 :         for (size_t i = 0; i < len; ++i)
     125             :         {
     126           2 :             K k;
     127           2 :             V v;
     128           1 :             Serializer(deserialize, "key", k, std::forward<Args>(args)...);
     129           1 :             Serializer(deserialize, "value", v, std::forward<Args>(args)...);
     130           1 :             value.emplace(std::move(k), std::move(v));
     131             :         }
     132           1 :     }
     133             : };
     134             : 
     135             : // We have to order the map before serializing to make things consistent
     136             : template<typename K, typename V>
     137             : struct SerializeHelper<std::unordered_map<K, V>>
     138             : {
     139             :     void operator()(ISerializer& serialize, const char* name, std::unordered_map<K, V>& value)
     140             :     {
     141             :         std::map<K, V> ordered_value(value.begin(), value.end());
     142             :         Serializer(serialize, name, ordered_value);
     143             :     }
     144             : 
     145             :     void operator()(IDeserializer& deserialize, const char* name, std::unordered_map<K, V>& value)
     146             :     {
     147             :         Serializer(deserialize, name, value);
     148             :     }
     149             : };
     150             : 
     151             : template<>
     152             : struct SerializeHelper<u8>
     153             : {
     154           0 :     void operator()(ISerializer& serialize, const char* name, u8 value)
     155             :     {
     156           0 :         serialize.NumberU8_Unbounded(name, value);
     157           0 :     }
     158             : 
     159           0 :     void operator()(IDeserializer& deserialize, const char* name, u8& value)
     160             :     {
     161           0 :         deserialize.NumberU8_Unbounded(name, value);
     162           0 :     }
     163             : };
     164             : 
     165             : 
     166             : template<typename Enum>
     167             : struct SerializeHelper<Enum, std::enable_if_t<std::is_enum_v<Enum>>>
     168             : {
     169           0 :     void operator()(ISerializer& serialize, const char* name, Enum value, Enum&& max)
     170             :     {
     171           0 :         serialize.NumberU8(name, static_cast<u8>(value), 0, static_cast<u8>(max));
     172           0 :     }
     173             : 
     174           0 :     void operator()(IDeserializer& deserialize, const char* name, Enum& value, Enum&& max)
     175             :     {
     176             :         u8 val;
     177           0 :         deserialize.NumberU8(name, val, 0, static_cast<u8>(max));
     178           0 :         value = static_cast<Enum>(val);
     179           0 :     }
     180             : };
     181             : 
     182             : 
     183             : template<>
     184             : struct SerializeHelper<u16>
     185             : {
     186           6 :     void operator()(ISerializer& serialize, const char* name, u16 value)
     187             :     {
     188           6 :         serialize.NumberU16_Unbounded(name, value);
     189           6 :     }
     190             : 
     191           0 :     void operator()(IDeserializer& deserialize, const char* name, u16& value)
     192             :     {
     193           0 :         deserialize.NumberU16_Unbounded(name, value);
     194           0 :     }
     195             : };
     196             : 
     197             : template<>
     198             : struct SerializeHelper<u32>
     199             : {
     200             :     template<typename... Args>
     201          18 :     void operator()(ISerializer& serialize, const char* name, u32 value, Args&&...)
     202             :     {
     203          18 :         serialize.NumberU32_Unbounded(name, value);
     204          18 :     }
     205             : 
     206             :     template<typename... Args>
     207           1 :     void operator()(IDeserializer& deserialize, const char* name, u32& value, Args&&...)
     208             :     {
     209           1 :         deserialize.NumberU32_Unbounded(name, value);
     210           1 :     }
     211             : };
     212             : 
     213             : template<>
     214             : struct SerializeHelper<i32>
     215             : {
     216             :     void operator()(ISerializer& serialize, const char* name, i32 value)
     217             :     {
     218             :         serialize.NumberI32_Unbounded(name, value);
     219             :     }
     220             : 
     221             :     void operator()(IDeserializer& deserialize, const char* name, i32& value)
     222             :     {
     223             :         deserialize.NumberI32_Unbounded(name, value);
     224             :     }
     225             : };
     226             : 
     227             : template<>
     228             : struct SerializeHelper<bool>
     229             : {
     230           0 :     void operator()(ISerializer& serialize, const char* name, bool value)
     231             :     {
     232           0 :         serialize.Bool(name, value);
     233           0 :     }
     234             : 
     235           0 :     void operator()(IDeserializer& deserialize, const char* name, bool& value)
     236             :     {
     237           0 :         deserialize.Bool(name, value);
     238           0 :     }
     239             : };
     240             : 
     241             : template<typename StringLike>
     242             : struct SerializeHelper<StringLike, std::enable_if_t<std::is_base_of_v<std::string, StringLike>>>
     243             : {
     244             :     template<typename T>
     245           1 :     void operator()(ISerializer& serialize, const char* name, T&& value)
     246             :     {
     247           1 :         serialize.StringASCII(name, value, 0, UINT32_MAX);
     248           1 :     }
     249             : 
     250             :     template<typename T>
     251           1 :     void operator()(IDeserializer& deserialize, const char* name, T& value)
     252             :     {
     253           1 :         deserialize.StringASCII(name, value, 0, UINT32_MAX);
     254           1 :     }
     255             : };
     256             : 
     257             : #endif // INCLUDED_SERIALIZED_TYPES

Generated by: LCOV version 1.13