1 #ifndef ZSERIO_WALKER_H_INC
2 #define ZSERIO_WALKER_H_INC
21 template <
typename ALLOC>
22 class BasicDefaultWalkFilter;
28 template <
typename ALLOC = std::allocator<u
int8_t>>
86 template <
typename ALLOC = std::allocator<u
int8_t>>
135 template <
typename ALLOC = std::allocator<u
int8_t>>
196 template <
typename ALLOC = std::allocator<u
int8_t>>
233 size_t elementIndex)
override;
236 size_t elementIndex)
override;
238 size_t elementIndex)
override;
241 bool enterDepthLevel();
242 bool leaveDepthLevel();
257 template <
typename ALLOC = std::allocator<u
int8_t>>
294 size_t elementIndex)
override;
297 size_t elementIndex)
override;
299 size_t elementIndex)
override;
309 std::regex m_pathRegex;
316 template <
typename ALLOC = std::allocator<u
int8_t>>
353 size_t elementIndex)
override;
356 size_t elementIndex)
override;
358 size_t elementIndex)
override;
361 bool filterArrayElement(
size_t elementIndex);
363 size_t m_maxArrayLength;
372 template <
typename ALLOC = std::allocator<u
int8_t>>
412 size_t elementIndex)
override;
415 size_t elementIndex)
override;
417 size_t elementIndex)
override;
420 template <
typename FILTER_FUNC,
typename... ARGS>
421 bool applyFilters(FILTER_FUNC filterFunc, ARGS... args)
425 result &= (walkFilter.*filterFunc)(args...);
443 template <
typename ALLOC>
445 m_walkObserver(walkObserver),
446 m_walkFilter(m_defaultWalkFilter)
449 template <
typename ALLOC>
451 m_walkObserver(walkObserver),
452 m_walkFilter(walkFilter)
455 template <
typename ALLOC>
468 m_walkObserver.beginRoot(compound);
469 walkFields(compound, typeInfo);
470 m_walkObserver.endRoot(compound);
473 template <
typename ALLOC>
479 StringView compoundChoice = compound->getChoice();
480 if (!compoundChoice.
empty())
483 auto fieldsIt = std::find_if(
485 return fieldInfo.schemaName == compoundChoice;
487 if (fieldsIt != fields.
end())
489 walkField(compound->getField(compoundChoice), *fieldsIt);
496 for (
const BasicFieldInfo<ALLOC>& fieldInfo : typeInfo.
getFields())
498 if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo))
504 template <
typename ALLOC>
505 bool BasicWalker<ALLOC>::walkField(
506 const IBasicReflectableConstPtr<ALLOC>& reflectable,
const BasicFieldInfo<ALLOC>& fieldInfo)
508 if (reflectable && fieldInfo.isArray)
510 if (m_walkFilter.beforeArray(reflectable, fieldInfo))
512 m_walkObserver.beginArray(reflectable, fieldInfo);
513 for (
size_t i = 0; i < reflectable->size(); ++i)
515 if (!walkFieldValue(reflectable->at(i), fieldInfo, i))
518 m_walkObserver.endArray(reflectable, fieldInfo);
520 return m_walkFilter.afterArray(reflectable, fieldInfo);
524 return walkFieldValue(reflectable, fieldInfo);
528 template <
typename ALLOC>
529 bool BasicWalker<ALLOC>::walkFieldValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable,
530 const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
532 const IBasicTypeInfo<ALLOC>& typeInfo = fieldInfo.typeInfo;
535 if (m_walkFilter.beforeCompound(reflectable, fieldInfo, elementIndex))
537 m_walkObserver.beginCompound(reflectable, fieldInfo, elementIndex);
538 walkFields(reflectable, typeInfo);
539 m_walkObserver.endCompound(reflectable, fieldInfo, elementIndex);
541 return m_walkFilter.afterCompound(reflectable, fieldInfo, elementIndex);
545 if (m_walkFilter.beforeValue(reflectable, fieldInfo, elementIndex))
546 m_walkObserver.visitValue(reflectable, fieldInfo, elementIndex);
547 return m_walkFilter.afterValue(reflectable, fieldInfo, elementIndex);
551 template <
typename ALLOC>
553 m_maxDepth(maxDepth),
557 template <
typename ALLOC>
561 return enterDepthLevel();
564 template <
typename ALLOC>
568 return leaveDepthLevel();
571 template <
typename ALLOC>
575 return enterDepthLevel();
578 template <
typename ALLOC>
582 return leaveDepthLevel();
585 template <
typename ALLOC>
589 return m_depth <= m_maxDepth;
592 template <
typename ALLOC>
599 template <
typename ALLOC>
602 const bool enter = (m_depth <= m_maxDepth);
607 template <
typename ALLOC>
608 bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel()
617 template <
typename ALLOC>
618 string<ALLOC> getCurrentPathImpl(
const vector<string<ALLOC>, ALLOC>& currentPath,
const ALLOC& allocator)
620 string<ALLOC> currentPathStr(allocator);
621 for (
auto it = currentPath.begin(); it != currentPath.end(); ++it)
623 if (!currentPathStr.empty())
624 currentPathStr +=
".";
625 currentPathStr += *it;
627 return currentPathStr;
630 template <
typename ALLOC>
631 void appendPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
632 size_t elementIndex,
const ALLOC& allocator)
634 if (elementIndex == WALKER_NOT_ELEMENT)
636 currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size(), allocator);
641 toString(fieldInfo.schemaName, allocator) +
"[" +
toString(elementIndex, allocator) +
"]";
645 template <
typename ALLOC>
646 void popPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
647 size_t elementIndex,
const ALLOC& allocator)
649 if (elementIndex == WALKER_NOT_ELEMENT)
650 currentPath.pop_back();
652 currentPath.back() =
toString(fieldInfo.schemaName, allocator);
655 template <
typename ALLOC>
656 class SubtreeRegexWalkFilter :
public IBasicWalkFilter<ALLOC>
659 SubtreeRegexWalkFilter(
const vector<string<ALLOC>, ALLOC>& currentPath,
const std::regex& pathRegex,
660 const ALLOC& allocator) :
661 m_currentPath(currentPath),
662 m_pathRegex(pathRegex),
663 m_allocator(allocator)
671 bool beforeArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo)
override
673 m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size());
674 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
680 bool afterArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>&)
override
682 m_currentPath.pop_back();
686 bool beforeCompound(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
687 size_t elementIndex)
override
689 appendPath(fieldInfo, elementIndex);
690 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
696 bool afterCompound(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
697 size_t elementIndex)
override
699 popPath(fieldInfo, elementIndex);
703 bool beforeValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
704 size_t elementIndex)
override
706 appendPath(fieldInfo, elementIndex);
707 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
712 bool afterValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
713 size_t elementIndex)
override
715 popPath(fieldInfo, elementIndex);
720 string<ALLOC> getCurrentPath()
const
722 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
725 void appendPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
727 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
730 void popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
732 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
735 vector<string<ALLOC>, ALLOC> m_currentPath;
736 std::regex m_pathRegex;
738 bool m_matches =
false;
743 template <
typename ALLOC>
745 m_pathRegex(pathRegex),
746 m_allocator(allocator)
749 template <
typename ALLOC>
755 if (std::regex_match(getCurrentPath(), m_pathRegex))
758 for (
size_t i = 0; i < array->size(); ++i)
760 m_currentPath.back() =
763 if (matchSubtree(array->at(i), fieldInfo))
772 template <
typename ALLOC>
776 m_currentPath.pop_back();
780 template <
typename ALLOC>
784 appendPath(fieldInfo, elementIndex);
785 if (std::regex_match(getCurrentPath(), m_pathRegex))
788 return matchSubtree(compound, fieldInfo);
791 template <
typename ALLOC>
795 popPath(fieldInfo, elementIndex);
799 template <
typename ALLOC>
803 appendPath(fieldInfo, elementIndex);
804 return matchSubtree(value, fieldInfo);
807 template <
typename ALLOC>
811 popPath(fieldInfo, elementIndex);
815 template <
typename ALLOC>
818 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
821 template <
typename ALLOC>
822 void BasicRegexWalkFilter<ALLOC>::popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
824 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
827 template <
typename ALLOC>
828 string<ALLOC> BasicRegexWalkFilter<ALLOC>::getCurrentPath()
const
830 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
833 template <
typename ALLOC>
834 bool BasicRegexWalkFilter<ALLOC>::matchSubtree(
835 const IBasicReflectableConstPtr<ALLOC>& value,
const BasicFieldInfo<ALLOC>& fieldInfo)
const
840 BasicDefaultWalkObserver<ALLOC> defaultObserver;
841 detail::SubtreeRegexWalkFilter<ALLOC> subtreeFilter(m_currentPath, m_pathRegex, m_allocator);
842 BasicWalker<ALLOC> walker(defaultObserver, subtreeFilter);
844 return subtreeFilter.matches();
849 return std::regex_match(getCurrentPath(), m_pathRegex);
853 template <
typename ALLOC>
855 m_maxArrayLength(maxArrayLength)
858 template <
typename ALLOC>
865 template <
typename ALLOC>
872 template <
typename ALLOC>
876 return filterArrayElement(elementIndex);
879 template <
typename ALLOC>
883 return filterArrayElement(elementIndex);
886 template <
typename ALLOC>
890 return filterArrayElement(elementIndex);
893 template <
typename ALLOC>
897 return filterArrayElement(elementIndex);
900 template <
typename ALLOC>
903 return elementIndex == WALKER_NOT_ELEMENT ? true : elementIndex < m_maxArrayLength;
906 template <
typename ALLOC>
908 m_walkFilters(walkFilters)
911 template <
typename ALLOC>
918 template <
typename ALLOC>
925 template <
typename ALLOC>
932 template <
typename ALLOC>
939 template <
typename ALLOC>
946 template <
typename ALLOC>
BasicAndWalkFilter(const WalkFilters &walkFilters)
std::reference_wrapper< IBasicWalkFilter< ALLOC > > WalkFilterRef
bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool afterArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicAndWalkFilter(const BasicAndWalkFilter &other)=delete
~BasicAndWalkFilter() override=default
bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicAndWalkFilter & operator=(const BasicAndWalkFilter &other)=delete
vector< WalkFilterRef, ALLOC > WalkFilters
BasicAndWalkFilter & operator=(BasicAndWalkFilter &&other)=delete
BasicAndWalkFilter(BasicAndWalkFilter &&other)=delete
bool afterArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicArrayLengthWalkFilter(BasicArrayLengthWalkFilter &&other)=delete
bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicArrayLengthWalkFilter(const BasicArrayLengthWalkFilter &other)=delete
bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
~BasicArrayLengthWalkFilter() override=default
BasicArrayLengthWalkFilter & operator=(BasicArrayLengthWalkFilter &&other)=delete
BasicArrayLengthWalkFilter(size_t maxArrayLength)
bool afterValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicArrayLengthWalkFilter & operator=(const BasicArrayLengthWalkFilter &other)=delete
BasicDefaultWalkFilter(BasicDefaultWalkFilter &&other)=delete
BasicDefaultWalkFilter & operator=(const BasicDefaultWalkFilter &other)=delete
bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool afterValue(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkFilter()=default
BasicDefaultWalkFilter & operator=(BasicDefaultWalkFilter &&other)=delete
BasicDefaultWalkFilter(const BasicDefaultWalkFilter &other)=delete
~BasicDefaultWalkFilter() override=default
bool afterArray(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
void beginArray(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
~BasicDefaultWalkObserver() override=default
BasicDefaultWalkObserver & operator=(BasicDefaultWalkObserver &&other)=delete
BasicDefaultWalkObserver(BasicDefaultWalkObserver &&other)=delete
void beginCompound(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
void endCompound(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
void endArray(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
void endRoot(const IBasicReflectableConstPtr< ALLOC > &) override
void visitValue(const IBasicReflectableConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkObserver()=default
BasicDefaultWalkObserver(const BasicDefaultWalkObserver &other)=delete
BasicDefaultWalkObserver & operator=(const BasicDefaultWalkObserver &other)=delete
void beginRoot(const IBasicReflectableConstPtr< ALLOC > &) override
BasicDepthWalkFilter(size_t maxDepth)
BasicDepthWalkFilter & operator=(const BasicDepthWalkFilter &other)=delete
bool afterArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
~BasicDepthWalkFilter() override=default
bool afterValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicDepthWalkFilter & operator=(BasicDepthWalkFilter &&other)=delete
bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicDepthWalkFilter(BasicDepthWalkFilter &&other)=delete
bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicDepthWalkFilter(const BasicDepthWalkFilter &other)=delete
bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicRegexWalkFilter & operator=(BasicRegexWalkFilter &&other)=delete
BasicRegexWalkFilter & operator=(const BasicRegexWalkFilter &other)=delete
bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
~BasicRegexWalkFilter() override=default
BasicRegexWalkFilter(const char *pathRegex, const ALLOC &allocator=ALLOC())
BasicRegexWalkFilter(const BasicRegexWalkFilter &other)=delete
bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicRegexWalkFilter(BasicRegexWalkFilter &&other)=delete
bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
constexpr size_type size() const noexcept
constexpr bool empty() const noexcept
constexpr const_pointer data() const noexcept
BasicWalker(IBasicWalkObserver< ALLOC > &walkObserver)
BasicWalker & operator=(BasicWalker &&other)=delete
BasicWalker & operator=(const BasicWalker &other)=delete
void walk(const IBasicReflectableConstPtr< ALLOC > &compound)
BasicWalker(const BasicWalker &other)=delete
BasicWalker(BasicWalker &&other)=delete
virtual StringView getSchemaName() const =0
virtual Span< const BasicFieldInfo< ALLOC > > getFields() const =0
virtual SchemaType getSchemaType() const =0
virtual bool beforeCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool beforeArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo)=0
virtual bool beforeValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool afterValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool afterCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool afterArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo)=0
constexpr iterator end() const noexcept
constexpr iterator begin() const noexcept
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
std::vector< T, RebindAlloc< ALLOC, T > > vector
string< ALLOC > toString(T value, const ALLOC &allocator=ALLOC())
typename IBasicReflectable< ALLOC >::ConstPtr IBasicReflectableConstPtr
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)