Line | Count | Source |
1 | | #ifndef ZSERIO_WALKER_H_INC |
2 | | #define ZSERIO_WALKER_H_INC |
3 | | |
4 | | #include <algorithm> |
5 | | #include <functional> |
6 | | #include <regex> |
7 | | |
8 | | #include "zserio/IReflectableData.h" |
9 | | #include "zserio/ITypeInfo.h" |
10 | | #include "zserio/IWalkFilter.h" |
11 | | #include "zserio/IWalkObserver.h" |
12 | | #include "zserio/String.h" |
13 | | #include "zserio/StringConvertUtil.h" |
14 | | #include "zserio/TypeInfoUtil.h" |
15 | | #include "zserio/Vector.h" |
16 | | #include "zserio/WalkerConst.h" |
17 | | |
18 | | namespace zserio |
19 | | { |
20 | | |
21 | | template <typename ALLOC> |
22 | | class BasicDefaultWalkFilter; |
23 | | |
24 | | /** |
25 | | * Walker through zserio objects, based on generated type info (see -withTypeInfoCode) and |
26 | | * reflectable interface (see -withReflectionCode). |
27 | | */ |
28 | | template <typename ALLOC = std::allocator<uint8_t>> |
29 | | class BasicWalker |
30 | | { |
31 | | public: |
32 | | /** |
33 | | * Constructor using default walk filter. |
34 | | * |
35 | | * \param walkObserver Observer to use during walking. |
36 | | */ |
37 | | explicit BasicWalker(IBasicWalkObserver<ALLOC>& walkObserver); |
38 | | |
39 | | /** |
40 | | * Constructor. |
41 | | * |
42 | | * \param walkObserver Observer to use during walking. |
43 | | * \param walkFilter Walk filter to use. |
44 | | */ |
45 | | BasicWalker(IBasicWalkObserver<ALLOC>& walkObserver, IBasicWalkFilter<ALLOC>& walkFilter); |
46 | | |
47 | | /** |
48 | | * Method generated by default. |
49 | | */ |
50 | 56 | ~BasicWalker() = default; |
51 | | |
52 | | /** |
53 | | * Copying and moving is disallowed! |
54 | | * \{ |
55 | | */ |
56 | | BasicWalker(const BasicWalker& other) = delete; |
57 | | BasicWalker& operator=(const BasicWalker& other) = delete; |
58 | | |
59 | | BasicWalker(BasicWalker&& other) = delete; |
60 | | BasicWalker& operator=(BasicWalker&& other) = delete; |
61 | | /** |
62 | | * \} |
63 | | */ |
64 | | |
65 | | /** |
66 | | * Walks given reflectable zserio compound object. |
67 | | * |
68 | | * \param compound Zserio compound object to walk. |
69 | | */ |
70 | | void walk(const IBasicReflectableDataConstPtr<ALLOC>& compound); |
71 | | |
72 | | private: |
73 | | void walkFields( |
74 | | const IBasicReflectableDataConstPtr<ALLOC>& compound, const IBasicTypeInfo<ALLOC>& typeInfo); |
75 | | bool walkField( |
76 | | const IBasicReflectableDataConstPtr<ALLOC>& reflectable, const BasicFieldInfo<ALLOC>& fieldInfo); |
77 | | bool walkFieldValue(const IBasicReflectableDataConstPtr<ALLOC>& reflectable, |
78 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex = WALKER_NOT_ELEMENT); |
79 | | |
80 | | IBasicWalkObserver<ALLOC>& m_walkObserver; |
81 | | BasicDefaultWalkFilter<ALLOC> m_defaultWalkFilter; |
82 | | IBasicWalkFilter<ALLOC>& m_walkFilter; |
83 | | }; |
84 | | |
85 | | /** |
86 | | * Default walk observer which just does nothing. |
87 | | */ |
88 | | template <typename ALLOC = std::allocator<uint8_t>> |
89 | | class BasicDefaultWalkObserver : public IBasicWalkObserver<ALLOC> |
90 | | { |
91 | | public: |
92 | | /** |
93 | | * Method generated by default. |
94 | | * \{ |
95 | | */ |
96 | 14 | BasicDefaultWalkObserver() = default; |
97 | 14 | ~BasicDefaultWalkObserver() override = default; |
98 | | /** |
99 | | * \} |
100 | | */ |
101 | | |
102 | | /** |
103 | | * Copying and moving is disallowed! |
104 | | * \{ |
105 | | */ |
106 | | BasicDefaultWalkObserver(const BasicDefaultWalkObserver& other) = delete; |
107 | | BasicDefaultWalkObserver& operator=(const BasicDefaultWalkObserver& other) = delete; |
108 | | |
109 | | BasicDefaultWalkObserver(BasicDefaultWalkObserver&& other) = delete; |
110 | | BasicDefaultWalkObserver& operator=(BasicDefaultWalkObserver&& other) = delete; |
111 | | /** |
112 | | * \} |
113 | | */ |
114 | | |
115 | | void beginRoot(const IBasicReflectableDataConstPtr<ALLOC>&) override |
116 | 12 | {} |
117 | | void endRoot(const IBasicReflectableDataConstPtr<ALLOC>&) override |
118 | 12 | {} |
119 | | |
120 | | void beginArray(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) override |
121 | 3 | {} |
122 | | void endArray(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) override |
123 | 3 | {} |
124 | | |
125 | | void beginCompound( |
126 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
127 | 3 | {} |
128 | | void endCompound(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
129 | 3 | {} |
130 | | |
131 | | void visitValue(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
132 | 9 | {} |
133 | | }; |
134 | | |
135 | | /** |
136 | | * Default walk filter which filters nothing. |
137 | | */ |
138 | | template <typename ALLOC = std::allocator<uint8_t>> |
139 | | class BasicDefaultWalkFilter : public IBasicWalkFilter<ALLOC> |
140 | | { |
141 | | public: |
142 | | /** |
143 | | * Method generated by default. |
144 | | * \{ |
145 | | */ |
146 | 92 | BasicDefaultWalkFilter() = default; |
147 | 92 | ~BasicDefaultWalkFilter() override = default; |
148 | | /** |
149 | | * \} |
150 | | */ |
151 | | |
152 | | /** |
153 | | * Copying and moving is disallowed! |
154 | | * \{ |
155 | | */ |
156 | | BasicDefaultWalkFilter(const BasicDefaultWalkFilter& other) = delete; |
157 | | BasicDefaultWalkFilter& operator=(const BasicDefaultWalkFilter& other) = delete; |
158 | | |
159 | | BasicDefaultWalkFilter(BasicDefaultWalkFilter&& other) = delete; |
160 | | BasicDefaultWalkFilter& operator=(BasicDefaultWalkFilter&& other) = delete; |
161 | | /** |
162 | | * \} |
163 | | */ |
164 | | |
165 | | bool beforeArray(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) override |
166 | 5 | { |
167 | 5 | return true; |
168 | 5 | } |
169 | | |
170 | | bool afterArray(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) override |
171 | 5 | { |
172 | 5 | return true; |
173 | 5 | } |
174 | | |
175 | | bool beforeCompound( |
176 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
177 | 12 | { |
178 | 12 | return true; |
179 | 12 | } |
180 | | |
181 | | bool afterCompound( |
182 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
183 | 12 | { |
184 | 12 | return true; |
185 | 12 | } |
186 | | |
187 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
188 | 48 | { |
189 | 48 | return true; |
190 | 48 | } |
191 | | |
192 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) override |
193 | 48 | { |
194 | 48 | return true; |
195 | 48 | } |
196 | | }; |
197 | | |
198 | | /** |
199 | | * Walk filter which allows to walk only to the given maximum depth. |
200 | | */ |
201 | | template <typename ALLOC = std::allocator<uint8_t>> |
202 | | class BasicDepthWalkFilter : public IBasicWalkFilter<ALLOC> |
203 | | { |
204 | | public: |
205 | | /** |
206 | | * Constructor. |
207 | | * |
208 | | * \param maxDepth Maximum depth to walk to. |
209 | | */ |
210 | | explicit BasicDepthWalkFilter(size_t maxDepth); |
211 | | |
212 | | /** |
213 | | * Method generated by default. |
214 | | */ |
215 | 7 | ~BasicDepthWalkFilter() override = default; |
216 | | |
217 | | /** |
218 | | * Copying is disallowed! |
219 | | * \{ |
220 | | */ |
221 | | BasicDepthWalkFilter(const BasicDepthWalkFilter& other) = delete; |
222 | | BasicDepthWalkFilter& operator=(const BasicDepthWalkFilter& other) = delete; |
223 | | |
224 | | BasicDepthWalkFilter(BasicDepthWalkFilter&& other) = delete; |
225 | | BasicDepthWalkFilter& operator=(BasicDepthWalkFilter&& other) = delete; |
226 | | /** |
227 | | * \} |
228 | | */ |
229 | | |
230 | | bool beforeArray( |
231 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
232 | | bool afterArray( |
233 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
234 | | |
235 | | bool beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
236 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
237 | | bool afterCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
238 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
239 | | |
240 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
241 | | size_t elementIndex) override; |
242 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
243 | | size_t elementIndex) override; |
244 | | |
245 | | private: |
246 | | bool enterDepthLevel(); |
247 | | bool leaveDepthLevel(); |
248 | | |
249 | | size_t m_maxDepth; |
250 | | size_t m_depth; |
251 | | }; |
252 | | |
253 | | /** |
254 | | * Walk filter which allows to walk only paths matching the given regex. |
255 | | * |
256 | | * The path is constructed from field names within the root object, thus the root object itself |
257 | | * is not part of the path. |
258 | | * |
259 | | * Array elements have the index appended to the path so that e.g. "compound.arrayField[0]" will match |
260 | | * only the first element in the array "arrayField". |
261 | | */ |
262 | | template <typename ALLOC = std::allocator<uint8_t>> |
263 | | class BasicRegexWalkFilter : public IBasicWalkFilter<ALLOC> |
264 | | { |
265 | | public: |
266 | | /** |
267 | | * Constructor. |
268 | | * |
269 | | * \param pathRegex Path regex to use for filtering. |
270 | | */ |
271 | | explicit BasicRegexWalkFilter(const char* pathRegex, const ALLOC& allocator = ALLOC()); |
272 | | |
273 | | /** |
274 | | * Method generated by default. |
275 | | */ |
276 | 8 | ~BasicRegexWalkFilter() override = default; |
277 | | |
278 | | /** |
279 | | * Copying is disallowed! |
280 | | * \{ |
281 | | */ |
282 | | BasicRegexWalkFilter(const BasicRegexWalkFilter& other) = delete; |
283 | | BasicRegexWalkFilter& operator=(const BasicRegexWalkFilter& other) = delete; |
284 | | |
285 | | BasicRegexWalkFilter(BasicRegexWalkFilter&& other) = delete; |
286 | | BasicRegexWalkFilter& operator=(BasicRegexWalkFilter&& other) = delete; |
287 | | /** |
288 | | * \} |
289 | | */ |
290 | | |
291 | | bool beforeArray( |
292 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
293 | | bool afterArray( |
294 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
295 | | |
296 | | bool beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
297 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
298 | | bool afterCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
299 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
300 | | |
301 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
302 | | size_t elementIndex) override; |
303 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
304 | | size_t elementIndex) override; |
305 | | |
306 | | private: |
307 | | using StringType = BasicString<RebindAlloc<ALLOC, char>>; |
308 | | |
309 | | void appendPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex); |
310 | | void popPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex); |
311 | | StringType getCurrentPath() const; |
312 | | bool matchSubtree( |
313 | | const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo) const; |
314 | | |
315 | | typename IBasicWalkFilter<ALLOC>::Path m_currentPath; |
316 | | std::regex m_pathRegex; |
317 | | ALLOC m_allocator; // TODO[Mi-L@]: Check how std::regex_match allocates when results are omitted! |
318 | | }; |
319 | | |
320 | | /** |
321 | | * Walk filter which allows to walk only to the given maximum array length. |
322 | | */ |
323 | | template <typename ALLOC = std::allocator<uint8_t>> |
324 | | class BasicArrayLengthWalkFilter : public IBasicWalkFilter<ALLOC> |
325 | | { |
326 | | public: |
327 | | /** |
328 | | * Constructor. |
329 | | * |
330 | | * \param maxArrayLength Maximum array length to walk to. |
331 | | */ |
332 | | explicit BasicArrayLengthWalkFilter(size_t maxArrayLength); |
333 | | |
334 | | /** |
335 | | * Method generated by default. |
336 | | */ |
337 | 1 | ~BasicArrayLengthWalkFilter() override = default; |
338 | | |
339 | | /** |
340 | | * Copying and moving is disallowed! |
341 | | * \{ |
342 | | */ |
343 | | BasicArrayLengthWalkFilter(const BasicArrayLengthWalkFilter& other) = delete; |
344 | | BasicArrayLengthWalkFilter& operator=(const BasicArrayLengthWalkFilter& other) = delete; |
345 | | |
346 | | BasicArrayLengthWalkFilter(BasicArrayLengthWalkFilter&& other) = delete; |
347 | | BasicArrayLengthWalkFilter& operator=(BasicArrayLengthWalkFilter&& other) = delete; |
348 | | /** |
349 | | * \} |
350 | | */ |
351 | | |
352 | | bool beforeArray( |
353 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
354 | | bool afterArray( |
355 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
356 | | |
357 | | bool beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
358 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
359 | | bool afterCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
360 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
361 | | |
362 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
363 | | size_t elementIndex) override; |
364 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
365 | | size_t elementIndex) override; |
366 | | |
367 | | private: |
368 | | bool filterArrayElement(size_t elementIndex); |
369 | | |
370 | | size_t m_maxArrayLength; |
371 | | }; |
372 | | |
373 | | /** |
374 | | * Walk filter which implements composition of particular filters. |
375 | | * |
376 | | * The filters are called sequentially and logical and is applied on theirs results. |
377 | | * Note that all filters are always called. |
378 | | */ |
379 | | template <typename ALLOC = std::allocator<uint8_t>> |
380 | | class BasicAndWalkFilter : public IBasicWalkFilter<ALLOC> |
381 | | { |
382 | | public: |
383 | | using WalkFilterRef = std::reference_wrapper<IBasicWalkFilter<ALLOC>>; |
384 | | using WalkFilters = Vector<WalkFilterRef, RebindAlloc<ALLOC, WalkFilterRef>>; |
385 | | |
386 | | /** |
387 | | * Constructor. |
388 | | * |
389 | | * \param walkFilters List of filters to use in composition. |
390 | | */ |
391 | | explicit BasicAndWalkFilter(const WalkFilters& walkFilters); |
392 | | |
393 | | /** |
394 | | * Method generated by default. |
395 | | */ |
396 | 4 | ~BasicAndWalkFilter() override = default; |
397 | | |
398 | | /** |
399 | | * Copying and moving is disallowed! |
400 | | * \{ |
401 | | */ |
402 | | BasicAndWalkFilter(const BasicAndWalkFilter& other) = delete; |
403 | | BasicAndWalkFilter& operator=(const BasicAndWalkFilter& other) = delete; |
404 | | |
405 | | BasicAndWalkFilter(BasicAndWalkFilter&& other) = delete; |
406 | | BasicAndWalkFilter& operator=(BasicAndWalkFilter&& other) = delete; |
407 | | /** |
408 | | * \} |
409 | | */ |
410 | | |
411 | | bool beforeArray( |
412 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
413 | | bool afterArray( |
414 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) override; |
415 | | |
416 | | bool beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
417 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
418 | | bool afterCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
419 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) override; |
420 | | |
421 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
422 | | size_t elementIndex) override; |
423 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo, |
424 | | size_t elementIndex) override; |
425 | | |
426 | | private: |
427 | | template <typename FILTER_FUNC, typename... ARGS> |
428 | | bool applyFilters(FILTER_FUNC filterFunc, ARGS... args) |
429 | 24 | { |
430 | 24 | bool result = true; |
431 | 24 | for (IBasicWalkFilter<ALLOC>& walkFilter : m_walkFilters) |
432 | 36 | { |
433 | 36 | result &= (walkFilter.*filterFunc)(args...); |
434 | 36 | } |
435 | 24 | return result; |
436 | 24 | } |
437 | | |
438 | | WalkFilters m_walkFilters; |
439 | | }; |
440 | | |
441 | | /** Typedefs to walker related classes provided for convenience - using default std::allocator<uint8_t>. */ |
442 | | /** \{ */ |
443 | | using Walker = BasicWalker<>; |
444 | | using DefaultWalkObserver = BasicDefaultWalkObserver<>; |
445 | | using DefaultWalkFilter = BasicDefaultWalkFilter<>; |
446 | | using DepthWalkFilter = BasicDepthWalkFilter<>; |
447 | | using RegexWalkFilter = BasicRegexWalkFilter<>; |
448 | | using ArrayLengthWalkFilter = BasicArrayLengthWalkFilter<>; |
449 | | using AndWalkFilter = BasicAndWalkFilter<>; |
450 | | /** \} */ |
451 | | |
452 | | template <typename ALLOC> |
453 | | BasicWalker<ALLOC>::BasicWalker(IBasicWalkObserver<ALLOC>& walkObserver) : |
454 | 2 | m_walkObserver(walkObserver), |
455 | 2 | m_walkFilter(m_defaultWalkFilter) |
456 | 2 | {} |
457 | | |
458 | | template <typename ALLOC> |
459 | | BasicWalker<ALLOC>::BasicWalker(IBasicWalkObserver<ALLOC>& walkObserver, IBasicWalkFilter<ALLOC>& walkFilter) : |
460 | 54 | m_walkObserver(walkObserver), |
461 | 54 | m_walkFilter(walkFilter) |
462 | 54 | {} |
463 | | |
464 | | template <typename ALLOC> |
465 | | void BasicWalker<ALLOC>::walk(const IBasicReflectableDataConstPtr<ALLOC>& compound) |
466 | 56 | { |
467 | 56 | if (!compound) |
468 | 1 | { |
469 | 1 | throw CppRuntimeException("Walker: Root object cannot be NULL!"); |
470 | 1 | } |
471 | | |
472 | 55 | const IBasicTypeInfo<ALLOC>& typeInfo = compound->getTypeInfo(); |
473 | 55 | if (!TypeInfoUtil::isCompound(typeInfo.getSchemaType())) |
474 | 1 | { |
475 | 1 | throw CppRuntimeException("Walker: Root object '") |
476 | 1 | << typeInfo.getSchemaName() << "' is not a compound type!"; |
477 | 1 | } |
478 | | |
479 | 54 | m_walkObserver.beginRoot(compound); |
480 | 54 | walkFields(compound, typeInfo); |
481 | 54 | m_walkObserver.endRoot(compound); |
482 | 54 | } |
483 | | |
484 | | template <typename ALLOC> |
485 | | void BasicWalker<ALLOC>::walkFields( |
486 | | const IBasicReflectableDataConstPtr<ALLOC>& compound, const IBasicTypeInfo<ALLOC>& typeInfo) |
487 | 71 | { |
488 | 71 | if (TypeInfoUtil::hasChoice(typeInfo.getSchemaType())) |
489 | 21 | { |
490 | 21 | std::string_view compoundChoice = compound->getChoice(); |
491 | 21 | if (!compoundChoice.empty()) |
492 | 18 | { |
493 | 18 | Span<const BasicFieldInfo<ALLOC>> fields = typeInfo.getFields(); |
494 | 18 | auto fieldsIt = std::find_if( |
495 | 38 | fields.begin(), fields.end(), [compoundChoice](const BasicFieldInfo<ALLOC>& fieldInfo) { |
496 | 38 | return fieldInfo.schemaName == compoundChoice; |
497 | 38 | }); |
498 | 18 | if (fieldsIt != fields.end()) |
499 | 17 | { |
500 | 17 | walkField(compound->getField(compoundChoice), *fieldsIt); |
501 | 17 | } |
502 | 18 | } |
503 | | // else uninitialized or empty branch |
504 | 21 | } |
505 | 50 | else |
506 | 50 | { |
507 | 50 | for (const BasicFieldInfo<ALLOC>& fieldInfo : typeInfo.getFields()) |
508 | 75 | { |
509 | 75 | if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo)) |
510 | 3 | { |
511 | 3 | break; |
512 | 3 | } |
513 | 75 | } |
514 | 50 | } |
515 | 71 | } |
516 | | |
517 | | template <typename ALLOC> |
518 | | bool BasicWalker<ALLOC>::walkField( |
519 | | const IBasicReflectableDataConstPtr<ALLOC>& reflectable, const BasicFieldInfo<ALLOC>& fieldInfo) |
520 | 92 | { |
521 | 92 | if (reflectable && fieldInfo.isArray87 ) |
522 | 10 | { |
523 | 10 | if (m_walkFilter.beforeArray(reflectable, fieldInfo)) |
524 | 8 | { |
525 | 8 | m_walkObserver.beginArray(reflectable, fieldInfo); |
526 | 21 | for (size_t i = 0; i < reflectable->size(); ++i13 ) |
527 | 14 | { |
528 | 14 | if (!walkFieldValue(reflectable->at(i), fieldInfo, i)) |
529 | 1 | { |
530 | 1 | break; |
531 | 1 | } |
532 | 14 | } |
533 | 8 | m_walkObserver.endArray(reflectable, fieldInfo); |
534 | 8 | } |
535 | 10 | return m_walkFilter.afterArray(reflectable, fieldInfo); |
536 | 10 | } |
537 | 82 | else |
538 | 82 | { |
539 | 82 | return walkFieldValue(reflectable, fieldInfo); |
540 | 82 | } |
541 | 92 | } |
542 | | |
543 | | template <typename ALLOC> |
544 | | bool BasicWalker<ALLOC>::walkFieldValue(const IBasicReflectableDataConstPtr<ALLOC>& reflectable, |
545 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
546 | 96 | { |
547 | 96 | const IBasicTypeInfo<ALLOC>& typeInfo = fieldInfo.typeInfo; |
548 | 96 | if (reflectable && TypeInfoUtil::isCompound(typeInfo.getSchemaType())91 ) |
549 | 22 | { |
550 | 22 | if (m_walkFilter.beforeCompound(reflectable, fieldInfo, elementIndex)) |
551 | 17 | { |
552 | 17 | m_walkObserver.beginCompound(reflectable, fieldInfo, elementIndex); |
553 | 17 | walkFields(reflectable, typeInfo); |
554 | 17 | m_walkObserver.endCompound(reflectable, fieldInfo, elementIndex); |
555 | 17 | } |
556 | 22 | return m_walkFilter.afterCompound(reflectable, fieldInfo, elementIndex); |
557 | 22 | } |
558 | 74 | else |
559 | 74 | { |
560 | 74 | if (m_walkFilter.beforeValue(reflectable, fieldInfo, elementIndex)) |
561 | 68 | { |
562 | 68 | m_walkObserver.visitValue(reflectable, fieldInfo, elementIndex); |
563 | 68 | } |
564 | 74 | return m_walkFilter.afterValue(reflectable, fieldInfo, elementIndex); |
565 | 74 | } |
566 | 96 | } |
567 | | |
568 | | template <typename ALLOC> |
569 | | BasicDepthWalkFilter<ALLOC>::BasicDepthWalkFilter(size_t maxDepth) : |
570 | 7 | m_maxDepth(maxDepth), |
571 | 7 | m_depth(1) |
572 | 7 | {} |
573 | | |
574 | | template <typename ALLOC> |
575 | | bool BasicDepthWalkFilter<ALLOC>::beforeArray( |
576 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) |
577 | 4 | { |
578 | 4 | return enterDepthLevel(); |
579 | 4 | } |
580 | | |
581 | | template <typename ALLOC> |
582 | | bool BasicDepthWalkFilter<ALLOC>::afterArray( |
583 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) |
584 | 4 | { |
585 | 4 | return leaveDepthLevel(); |
586 | 4 | } |
587 | | |
588 | | template <typename ALLOC> |
589 | | bool BasicDepthWalkFilter<ALLOC>::beforeCompound( |
590 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) |
591 | 4 | { |
592 | 4 | return enterDepthLevel(); |
593 | 4 | } |
594 | | |
595 | | template <typename ALLOC> |
596 | | bool BasicDepthWalkFilter<ALLOC>::afterCompound( |
597 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) |
598 | 4 | { |
599 | 4 | return leaveDepthLevel(); |
600 | 4 | } |
601 | | |
602 | | template <typename ALLOC> |
603 | | bool BasicDepthWalkFilter<ALLOC>::beforeValue( |
604 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) |
605 | 9 | { |
606 | 9 | return m_depth <= m_maxDepth; |
607 | 9 | } |
608 | | |
609 | | template <typename ALLOC> |
610 | | bool BasicDepthWalkFilter<ALLOC>::afterValue( |
611 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t) |
612 | 9 | { |
613 | 9 | return true; |
614 | 9 | } |
615 | | |
616 | | template <typename ALLOC> |
617 | | bool BasicDepthWalkFilter<ALLOC>::enterDepthLevel() |
618 | 8 | { |
619 | 8 | const bool enter = (m_depth <= m_maxDepth); |
620 | 8 | m_depth += 1; |
621 | 8 | return enter; |
622 | 8 | } |
623 | | |
624 | | template <typename ALLOC> |
625 | | bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel() |
626 | 8 | { |
627 | 8 | m_depth -= 1; |
628 | 8 | return true; |
629 | 8 | } |
630 | | |
631 | | namespace detail |
632 | | { |
633 | | |
634 | | template <typename PATH, typename ALLOC> |
635 | | BasicString<RebindAlloc<ALLOC, char>> getCurrentPathImpl(const PATH& currentPath, const ALLOC& allocator) |
636 | 31 | { |
637 | 31 | BasicString<RebindAlloc<ALLOC, char>> currentPathStr(allocator); |
638 | 80 | for (auto it = currentPath.begin(); it != currentPath.end(); ++it49 ) |
639 | 49 | { |
640 | 49 | if (!currentPathStr.empty()) |
641 | 18 | { |
642 | 18 | currentPathStr += "."; |
643 | 18 | } |
644 | 49 | currentPathStr += *it; |
645 | 49 | } |
646 | 31 | return currentPathStr; |
647 | 31 | } |
648 | | |
649 | | template <typename PATH, typename ALLOC> |
650 | | void appendPathImpl( |
651 | | PATH& currentPath, const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex, const ALLOC& allocator) |
652 | 23 | { |
653 | 23 | if (elementIndex == WALKER_NOT_ELEMENT) |
654 | 18 | { |
655 | 18 | currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size()); |
656 | 18 | } |
657 | 5 | else |
658 | 5 | { |
659 | 5 | currentPath.back() = |
660 | 5 | toString(fieldInfo.schemaName, allocator) + "[" + toString(elementIndex, allocator) + "]"; |
661 | 5 | } |
662 | 23 | } |
663 | | |
664 | | template <typename PATH, typename ALLOC> |
665 | | void popPathImpl( |
666 | | PATH& currentPath, const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex, const ALLOC& allocator) |
667 | 23 | { |
668 | 23 | if (elementIndex == WALKER_NOT_ELEMENT) |
669 | 18 | { |
670 | 18 | currentPath.pop_back(); |
671 | 18 | } |
672 | 5 | else |
673 | 5 | { |
674 | 5 | currentPath.back() = toString(fieldInfo.schemaName, allocator); |
675 | 5 | } |
676 | 23 | } |
677 | | |
678 | | template <typename ALLOC> |
679 | | class SubtreeRegexWalkFilter : public IBasicWalkFilter<ALLOC> |
680 | | { |
681 | | public: |
682 | | SubtreeRegexWalkFilter(const typename IBasicWalkFilter<ALLOC>::Path& currentPath, |
683 | | const std::regex& pathRegex, const ALLOC& allocator) : |
684 | 11 | m_currentPath(currentPath), |
685 | 11 | m_pathRegex(pathRegex), |
686 | 11 | m_allocator(allocator) |
687 | 11 | {} |
688 | | |
689 | | bool matches() |
690 | 11 | { |
691 | 11 | return m_matches; |
692 | 11 | } |
693 | | |
694 | | bool beforeArray( |
695 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>& fieldInfo) override |
696 | 4 | { |
697 | 4 | m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size()); |
698 | 4 | m_matches = std::regex_match(getCurrentPath(), m_pathRegex); |
699 | | |
700 | | // terminate when the match is already found (note that array is never null here) |
701 | 4 | return !m_matches; |
702 | 4 | } |
703 | | |
704 | | bool afterArray(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) override |
705 | 4 | { |
706 | 4 | m_currentPath.pop_back(); |
707 | 4 | return !m_matches; // terminate when the match is already found |
708 | 4 | } |
709 | | |
710 | | bool beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>& fieldInfo, |
711 | | size_t elementIndex) override |
712 | 2 | { |
713 | 2 | appendPath(fieldInfo, elementIndex); |
714 | 2 | m_matches = std::regex_match(getCurrentPath(), m_pathRegex); |
715 | | |
716 | | // terminate when the match is already found (note that compound is never null here) |
717 | 2 | return !m_matches; |
718 | 2 | } |
719 | | |
720 | | bool afterCompound(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>& fieldInfo, |
721 | | size_t elementIndex) override |
722 | 2 | { |
723 | 2 | popPath(fieldInfo, elementIndex); |
724 | 2 | return !m_matches; // terminate when the match is already found |
725 | 2 | } |
726 | | |
727 | | bool beforeValue(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>& fieldInfo, |
728 | | size_t elementIndex) override |
729 | 9 | { |
730 | 9 | appendPath(fieldInfo, elementIndex); |
731 | 9 | m_matches = std::regex_match(getCurrentPath(), m_pathRegex); |
732 | | |
733 | 9 | return !m_matches; // terminate when the match is already found |
734 | 9 | } |
735 | | |
736 | | bool afterValue(const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>& fieldInfo, |
737 | | size_t elementIndex) override |
738 | 9 | { |
739 | 9 | popPath(fieldInfo, elementIndex); |
740 | 9 | return !m_matches; // terminate when the match is already found |
741 | 9 | } |
742 | | |
743 | | private: |
744 | | BasicString<RebindAlloc<ALLOC, char>> getCurrentPath() const |
745 | 15 | { |
746 | 15 | return detail::getCurrentPathImpl(m_currentPath, m_allocator); |
747 | 15 | } |
748 | | |
749 | | void appendPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
750 | 11 | { |
751 | 11 | detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator); |
752 | 11 | } |
753 | | |
754 | | void popPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
755 | 11 | { |
756 | 11 | detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator); |
757 | 11 | } |
758 | | |
759 | | typename IBasicWalkFilter<ALLOC>::Path m_currentPath; |
760 | | std::regex m_pathRegex; |
761 | | ALLOC m_allocator; |
762 | | bool m_matches = false; |
763 | | }; |
764 | | |
765 | | } // namespace detail |
766 | | |
767 | | template <typename ALLOC> |
768 | | BasicRegexWalkFilter<ALLOC>::BasicRegexWalkFilter(const char* pathRegex, const ALLOC& allocator) : |
769 | 8 | m_pathRegex(pathRegex), |
770 | 8 | m_allocator(allocator) |
771 | 8 | {} |
772 | | |
773 | | template <typename ALLOC> |
774 | | bool BasicRegexWalkFilter<ALLOC>::beforeArray( |
775 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) |
776 | 4 | { |
777 | 4 | m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size()); |
778 | | |
779 | 4 | if (std::regex_match(getCurrentPath(), m_pathRegex)) |
780 | 1 | { |
781 | 1 | return true; // the array itself matches |
782 | 1 | } |
783 | | |
784 | 9 | for (size_t i = 0; 3 i < array->size(); ++i6 ) |
785 | 7 | { |
786 | 7 | m_currentPath.back() = |
787 | 7 | toString(fieldInfo.schemaName, m_allocator) + "[" + toString(i, m_allocator) + "]"; |
788 | | |
789 | 7 | if (matchSubtree(array->at(i), fieldInfo)) |
790 | 1 | { |
791 | 1 | return true; |
792 | 1 | } |
793 | 7 | } |
794 | | |
795 | 2 | m_currentPath.back() = toString(fieldInfo.schemaName, m_allocator); |
796 | | |
797 | 2 | return false; |
798 | 3 | } |
799 | | |
800 | | template <typename ALLOC> |
801 | | bool BasicRegexWalkFilter<ALLOC>::afterArray( |
802 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) |
803 | 4 | { |
804 | 4 | m_currentPath.pop_back(); |
805 | 4 | return true; |
806 | 4 | } |
807 | | |
808 | | template <typename ALLOC> |
809 | | bool BasicRegexWalkFilter<ALLOC>::beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
810 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
811 | 5 | { |
812 | 5 | appendPath(fieldInfo, elementIndex); |
813 | 5 | if (std::regex_match(getCurrentPath(), m_pathRegex)) |
814 | 1 | { |
815 | 1 | return true; // the compound itself matches |
816 | 1 | } |
817 | | |
818 | 4 | return matchSubtree(compound, fieldInfo); |
819 | 5 | } |
820 | | |
821 | | template <typename ALLOC> |
822 | | bool BasicRegexWalkFilter<ALLOC>::afterCompound(const IBasicReflectableDataConstPtr<ALLOC>&, |
823 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
824 | 5 | { |
825 | 5 | popPath(fieldInfo, elementIndex); |
826 | 5 | return true; |
827 | 5 | } |
828 | | |
829 | | template <typename ALLOC> |
830 | | bool BasicRegexWalkFilter<ALLOC>::beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, |
831 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
832 | 7 | { |
833 | 7 | appendPath(fieldInfo, elementIndex); |
834 | 7 | return matchSubtree(value, fieldInfo); |
835 | 7 | } |
836 | | |
837 | | template <typename ALLOC> |
838 | | bool BasicRegexWalkFilter<ALLOC>::afterValue(const IBasicReflectableDataConstPtr<ALLOC>&, |
839 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
840 | 7 | { |
841 | 7 | popPath(fieldInfo, elementIndex); |
842 | 7 | return true; |
843 | 7 | } |
844 | | |
845 | | template <typename ALLOC> |
846 | | void BasicRegexWalkFilter<ALLOC>::appendPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
847 | 12 | { |
848 | 12 | detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator); |
849 | 12 | } |
850 | | |
851 | | template <typename ALLOC> |
852 | | void BasicRegexWalkFilter<ALLOC>::popPath(const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
853 | 12 | { |
854 | 12 | detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator); |
855 | 12 | } |
856 | | |
857 | | template <typename ALLOC> |
858 | | BasicString<RebindAlloc<ALLOC, char>> BasicRegexWalkFilter<ALLOC>::getCurrentPath() const |
859 | 16 | { |
860 | 16 | return detail::getCurrentPathImpl(m_currentPath, m_allocator); |
861 | 16 | } |
862 | | |
863 | | template <typename ALLOC> |
864 | | bool BasicRegexWalkFilter<ALLOC>::matchSubtree( |
865 | | const IBasicReflectableDataConstPtr<ALLOC>& value, const BasicFieldInfo<ALLOC>& fieldInfo) const |
866 | 18 | { |
867 | 18 | if (value != nullptr && TypeInfoUtil::isCompound(fieldInfo.typeInfo.getSchemaType())13 ) |
868 | 11 | { |
869 | | // is a not null compound, try to find match within its subtree |
870 | 11 | BasicDefaultWalkObserver<ALLOC> defaultObserver; |
871 | 11 | detail::SubtreeRegexWalkFilter<ALLOC> subtreeFilter(m_currentPath, m_pathRegex, m_allocator); |
872 | 11 | BasicWalker<ALLOC> walker(defaultObserver, subtreeFilter); |
873 | 11 | walker.walk(value); |
874 | 11 | return subtreeFilter.matches(); |
875 | 11 | } |
876 | 7 | else |
877 | 7 | { |
878 | | // try to match a simple value or null compound |
879 | 7 | return std::regex_match(getCurrentPath(), m_pathRegex); |
880 | 7 | } |
881 | 18 | } |
882 | | |
883 | | template <typename ALLOC> |
884 | | BasicArrayLengthWalkFilter<ALLOC>::BasicArrayLengthWalkFilter(size_t maxArrayLength) : |
885 | 1 | m_maxArrayLength(maxArrayLength) |
886 | 1 | {} |
887 | | |
888 | | template <typename ALLOC> |
889 | | bool BasicArrayLengthWalkFilter<ALLOC>::beforeArray( |
890 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) |
891 | 2 | { |
892 | 2 | return true; |
893 | 2 | } |
894 | | |
895 | | template <typename ALLOC> |
896 | | bool BasicArrayLengthWalkFilter<ALLOC>::afterArray( |
897 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&) |
898 | 2 | { |
899 | 2 | return true; |
900 | 2 | } |
901 | | |
902 | | template <typename ALLOC> |
903 | | bool BasicArrayLengthWalkFilter<ALLOC>::beforeCompound( |
904 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t elementIndex) |
905 | 2 | { |
906 | 2 | return filterArrayElement(elementIndex); |
907 | 2 | } |
908 | | |
909 | | template <typename ALLOC> |
910 | | bool BasicArrayLengthWalkFilter<ALLOC>::afterCompound( |
911 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t elementIndex) |
912 | 2 | { |
913 | 2 | return filterArrayElement(elementIndex); |
914 | 2 | } |
915 | | |
916 | | template <typename ALLOC> |
917 | | bool BasicArrayLengthWalkFilter<ALLOC>::beforeValue( |
918 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t elementIndex) |
919 | 3 | { |
920 | 3 | return filterArrayElement(elementIndex); |
921 | 3 | } |
922 | | |
923 | | template <typename ALLOC> |
924 | | bool BasicArrayLengthWalkFilter<ALLOC>::afterValue( |
925 | | const IBasicReflectableDataConstPtr<ALLOC>&, const BasicFieldInfo<ALLOC>&, size_t elementIndex) |
926 | 3 | { |
927 | 3 | return filterArrayElement(elementIndex); |
928 | 3 | } |
929 | | |
930 | | template <typename ALLOC> |
931 | | bool BasicArrayLengthWalkFilter<ALLOC>::filterArrayElement(size_t elementIndex) |
932 | 10 | { |
933 | 10 | return elementIndex == WALKER_NOT_ELEMENT ? true4 : elementIndex < m_maxArrayLength6 ; |
934 | 10 | } |
935 | | |
936 | | template <typename ALLOC> |
937 | | BasicAndWalkFilter<ALLOC>::BasicAndWalkFilter(const WalkFilters& walkFilters) : |
938 | 4 | m_walkFilters(walkFilters) |
939 | 4 | {} |
940 | | |
941 | | template <typename ALLOC> |
942 | | bool BasicAndWalkFilter<ALLOC>::beforeArray( |
943 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) |
944 | 4 | { |
945 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::beforeArray, array, fieldInfo); |
946 | 4 | } |
947 | | |
948 | | template <typename ALLOC> |
949 | | bool BasicAndWalkFilter<ALLOC>::afterArray( |
950 | | const IBasicReflectableDataConstPtr<ALLOC>& array, const BasicFieldInfo<ALLOC>& fieldInfo) |
951 | 4 | { |
952 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::afterArray, array, fieldInfo); |
953 | 4 | } |
954 | | |
955 | | template <typename ALLOC> |
956 | | bool BasicAndWalkFilter<ALLOC>::beforeCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
957 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
958 | 4 | { |
959 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::beforeCompound, compound, fieldInfo, elementIndex); |
960 | 4 | } |
961 | | |
962 | | template <typename ALLOC> |
963 | | bool BasicAndWalkFilter<ALLOC>::afterCompound(const IBasicReflectableDataConstPtr<ALLOC>& compound, |
964 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
965 | 4 | { |
966 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::afterCompound, compound, fieldInfo, elementIndex); |
967 | 4 | } |
968 | | |
969 | | template <typename ALLOC> |
970 | | bool BasicAndWalkFilter<ALLOC>::beforeValue(const IBasicReflectableDataConstPtr<ALLOC>& value, |
971 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
972 | 4 | { |
973 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::beforeValue, value, fieldInfo, elementIndex); |
974 | 4 | } |
975 | | |
976 | | template <typename ALLOC> |
977 | | bool BasicAndWalkFilter<ALLOC>::afterValue(const IBasicReflectableDataConstPtr<ALLOC>& value, |
978 | | const BasicFieldInfo<ALLOC>& fieldInfo, size_t elementIndex) |
979 | 4 | { |
980 | 4 | return applyFilters(&IBasicWalkFilter<ALLOC>::afterValue, value, fieldInfo, elementIndex); |
981 | 4 | } |
982 | | |
983 | | } // namespace zserio |
984 | | |
985 | | #endif // ZSERIO_WALKER_H_INC |