• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
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 
16 #ifndef META_EXT_SERIALIZATION_SERIALISER_H
17 #define META_EXT_SERIALIZATION_SERIALISER_H
18 
19 #include <meta/interface/property/property.h>
20 #include <meta/interface/serialization/intf_export_context.h>
21 #include <meta/interface/serialization/intf_import_context.h>
22 
23 META_BEGIN_NAMESPACE()
24 
25 template<typename Type>
26 struct NamedValue {
NamedValueNamedValue27     NamedValue(BASE_NS::string_view name, Type& v) : name(name), value(v) {}
28 
29     BASE_NS::string_view name;
30     Type& value;
31 };
32 
33 template<typename Type>
34 NamedValue(BASE_NS::string_view name, const Type& v) -> NamedValue<const Type>;
35 
36 struct AutoSerializeTag {};
AutoSerialize()37 inline AutoSerializeTag AutoSerialize()
38 {
39     return {};
40 }
41 
42 class SerializerBase {
43 public:
ReturnError()44     operator ReturnError() const
45     {
46         return state_;
47     }
48 
49     explicit operator bool() const
50     {
51         return state_;
52     }
53 
SetState(ReturnError s)54     SerializerBase& SetState(ReturnError s)
55     {
56         state_ = s;
57         return *this;
58     }
59 
60 protected:
61     ReturnError state_ { GenericError::SUCCESS };
62 };
63 
64 /// Helper class to export and return the status
65 class ExportSerializer : public SerializerBase {
66 public:
ExportSerializer(IExportContext & context)67     ExportSerializer(IExportContext& context) : context_(context) {}
68 
69     template<typename Type>
70     ExportSerializer& operator&(const NamedValue<Type>& nv)
71     {
72         if (state_) {
73             if constexpr (is_enum_v<BASE_NS::remove_const_t<Type>>) {
74                 using UT = BASE_NS::underlying_type_t<BASE_NS::remove_const_t<Type>>;
75                 SetState(context_.ExportValue(nv.name, static_cast<UT>(nv.value)));
76             } else {
77                 SetState(context_.ExportValue(nv.name, nv.value));
78             }
79         }
80         return *this;
81     }
82 
83     template<typename Type>
84     ExportSerializer& operator&(const NamedValue<Property<Type>>& nv)
85     {
86         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
87             *this& NamedValue(nv.name, p);
88         } else {
89             SetState(GenericError::FAIL);
90         }
91         return *this;
92     }
93 
94     template<typename Type>
95     ExportSerializer& operator&(const NamedValue<const Property<Type>>& nv)
96     {
97         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
98             *this& NamedValue(nv.name, p);
99         } else {
100             SetState(GenericError::FAIL);
101         }
102         return *this;
103     }
104 
105     template<typename Type>
106     ExportSerializer& operator&(const NamedValue<const BASE_NS::weak_ptr<Type>>& nv)
107     {
108         if (state_) {
109             SetState(context_.ExportWeakPtr(nv.name, interface_pointer_cast<IObject>(nv.value)));
110         }
111         return *this;
112     }
113 
114     ExportSerializer& operator&(AutoSerializeTag)
115     {
116         if (state_) {
117             SetState(context_.AutoExport());
118         }
119         return *this;
120     }
121 
122 private:
123     IExportContext& context_;
124 };
125 
126 /// Helper class to import and return the status
127 class ImportSerializer : public SerializerBase {
128 public:
ImportSerializer(IImportContext & context)129     ImportSerializer(IImportContext& context) : context_(context) {}
130 
131     template<typename Type>
132     ImportSerializer& operator&(const NamedValue<Type>& nv)
133     {
134         if (state_) {
135             if constexpr (is_enum_v<BASE_NS::remove_const_t<Type>>) {
136                 using UT = BASE_NS::underlying_type_t<BASE_NS::remove_const_t<Type>>;
137                 UT v {};
138                 if (SetState(context_.ImportValue(nv.name, v))) {
139                     nv.value = static_cast<Type>(v);
140                 }
141             } else {
142                 SetState(context_.ImportValue(nv.name, nv.value));
143             }
144         }
145         return *this;
146     }
147 
148     template<typename Type>
149     ImportSerializer& operator&(const NamedValue<Property<Type>>& nv)
150     {
151         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
152             *this& NamedValue(nv.name, p);
153         } else {
154             SetState(GenericError::FAIL);
155         }
156         return *this;
157     }
158 
159     template<typename Type>
160     ImportSerializer& operator&(const NamedValue<const Property<Type>>& nv)
161     {
162         if (auto p = interface_pointer_cast<IObject>(nv.value.GetProperty())) {
163             *this& NamedValue(nv.name, p);
164         } else {
165             SetState(GenericError::FAIL);
166         }
167         return *this;
168     }
169 
170     template<typename Type>
171     ImportSerializer& operator&(const NamedValue<BASE_NS::weak_ptr<Type>>& nv)
172     {
173         if (state_) {
174             IObject::WeakPtr p;
175             SetState(context_.ImportWeakPtr(nv.name, p));
176             if (state_) {
177                 nv.value = interface_pointer_cast<BASE_NS::remove_const_t<Type>>(p);
178             }
179         }
180         return *this;
181     }
182 
183     ImportSerializer& operator&(AutoSerializeTag)
184     {
185         if (state_) {
186             SetState(context_.AutoImport());
187         }
188         return *this;
189     }
190 
191 private:
192     IImportContext& context_;
193 };
194 
195 /// Helper to use same names and syntax for export and import
196 template<typename Context>
197 class Serializer {
198     Serializer(Context& c);
199 };
200 
201 template<>
202 class Serializer<IImportContext> : public ImportSerializer {
203 public:
Serializer(IImportContext & c)204     Serializer(IImportContext& c) : ImportSerializer(c) {}
205 };
206 
207 template<>
208 class Serializer<IExportContext> : public ExportSerializer {
209 public:
Serializer(IExportContext & c)210     Serializer(IExportContext& c) : ExportSerializer(c) {}
211 };
212 
213 META_END_NAMESPACE()
214 
215 #endif
216