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)
426 result &= (walkFilter.*filterFunc)(args...);
445 template <
typename ALLOC>
447 m_walkObserver(walkObserver),
448 m_walkFilter(m_defaultWalkFilter)
451 template <
typename ALLOC>
453 m_walkObserver(walkObserver),
454 m_walkFilter(walkFilter)
457 template <
typename ALLOC>
472 m_walkObserver.beginRoot(compound);
473 walkFields(compound, typeInfo);
474 m_walkObserver.endRoot(compound);
477 template <
typename ALLOC>
483 StringView compoundChoice = compound->getChoice();
484 if (!compoundChoice.
empty())
487 auto fieldsIt = std::find_if(
489 return fieldInfo.schemaName == compoundChoice;
491 if (fieldsIt != fields.
end())
493 walkField(compound->getField(compoundChoice), *fieldsIt);
500 for (
const BasicFieldInfo<ALLOC>& fieldInfo : typeInfo.
getFields())
502 if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo))
510 template <
typename ALLOC>
511 bool BasicWalker<ALLOC>::walkField(
512 const IBasicReflectableConstPtr<ALLOC>& reflectable,
const BasicFieldInfo<ALLOC>& fieldInfo)
514 if (reflectable && fieldInfo.isArray)
516 if (m_walkFilter.beforeArray(reflectable, fieldInfo))
518 m_walkObserver.beginArray(reflectable, fieldInfo);
519 for (
size_t i = 0; i < reflectable->size(); ++i)
521 if (!walkFieldValue(reflectable->at(i), fieldInfo, i))
526 m_walkObserver.endArray(reflectable, fieldInfo);
528 return m_walkFilter.afterArray(reflectable, fieldInfo);
532 return walkFieldValue(reflectable, fieldInfo);
536 template <
typename ALLOC>
537 bool BasicWalker<ALLOC>::walkFieldValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable,
538 const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
540 const IBasicTypeInfo<ALLOC>& typeInfo = fieldInfo.typeInfo;
543 if (m_walkFilter.beforeCompound(reflectable, fieldInfo, elementIndex))
545 m_walkObserver.beginCompound(reflectable, fieldInfo, elementIndex);
546 walkFields(reflectable, typeInfo);
547 m_walkObserver.endCompound(reflectable, fieldInfo, elementIndex);
549 return m_walkFilter.afterCompound(reflectable, fieldInfo, elementIndex);
553 if (m_walkFilter.beforeValue(reflectable, fieldInfo, elementIndex))
555 m_walkObserver.visitValue(reflectable, fieldInfo, elementIndex);
557 return m_walkFilter.afterValue(reflectable, fieldInfo, elementIndex);
561 template <
typename ALLOC>
563 m_maxDepth(maxDepth),
567 template <
typename ALLOC>
571 return enterDepthLevel();
574 template <
typename ALLOC>
578 return leaveDepthLevel();
581 template <
typename ALLOC>
585 return enterDepthLevel();
588 template <
typename ALLOC>
592 return leaveDepthLevel();
595 template <
typename ALLOC>
599 return m_depth <= m_maxDepth;
602 template <
typename ALLOC>
609 template <
typename ALLOC>
612 const bool enter = (m_depth <= m_maxDepth);
617 template <
typename ALLOC>
618 bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel()
627 template <
typename ALLOC>
628 string<ALLOC> getCurrentPathImpl(
const vector<string<ALLOC>, ALLOC>& currentPath,
const ALLOC& allocator)
630 string<ALLOC> currentPathStr(allocator);
631 for (
auto it = currentPath.begin(); it != currentPath.end(); ++it)
633 if (!currentPathStr.empty())
635 currentPathStr +=
".";
637 currentPathStr += *it;
639 return currentPathStr;
642 template <
typename ALLOC>
643 void appendPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
644 size_t elementIndex,
const ALLOC& allocator)
646 if (elementIndex == WALKER_NOT_ELEMENT)
648 currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size(), allocator);
653 toString(fieldInfo.schemaName, allocator) +
"[" +
toString(elementIndex, allocator) +
"]";
657 template <
typename ALLOC>
658 void popPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
659 size_t elementIndex,
const ALLOC& allocator)
661 if (elementIndex == WALKER_NOT_ELEMENT)
663 currentPath.pop_back();
667 currentPath.back() =
toString(fieldInfo.schemaName, allocator);
671 template <
typename ALLOC>
672 class SubtreeRegexWalkFilter :
public IBasicWalkFilter<ALLOC>
675 SubtreeRegexWalkFilter(
const vector<string<ALLOC>, ALLOC>& currentPath,
const std::regex& pathRegex,
676 const ALLOC& allocator) :
677 m_currentPath(currentPath),
678 m_pathRegex(pathRegex),
679 m_allocator(allocator)
687 bool beforeArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo)
override
689 m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size());
690 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
696 bool afterArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>&)
override
698 m_currentPath.pop_back();
702 bool beforeCompound(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
703 size_t elementIndex)
override
705 appendPath(fieldInfo, elementIndex);
706 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
712 bool afterCompound(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
713 size_t elementIndex)
override
715 popPath(fieldInfo, elementIndex);
719 bool beforeValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
720 size_t elementIndex)
override
722 appendPath(fieldInfo, elementIndex);
723 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
728 bool afterValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
729 size_t elementIndex)
override
731 popPath(fieldInfo, elementIndex);
736 string<ALLOC> getCurrentPath()
const
738 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
741 void appendPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
743 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
746 void popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
748 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
751 vector<string<ALLOC>, ALLOC> m_currentPath;
752 std::regex m_pathRegex;
754 bool m_matches =
false;
759 template <
typename ALLOC>
761 m_pathRegex(pathRegex),
762 m_allocator(allocator)
765 template <
typename ALLOC>
771 if (std::regex_match(getCurrentPath(), m_pathRegex))
776 for (
size_t i = 0; i < array->size(); ++i)
778 m_currentPath.back() =
781 if (matchSubtree(array->at(i), fieldInfo))
792 template <
typename ALLOC>
796 m_currentPath.pop_back();
800 template <
typename ALLOC>
804 appendPath(fieldInfo, elementIndex);
805 if (std::regex_match(getCurrentPath(), m_pathRegex))
810 return matchSubtree(compound, fieldInfo);
813 template <
typename ALLOC>
817 popPath(fieldInfo, elementIndex);
821 template <
typename ALLOC>
825 appendPath(fieldInfo, elementIndex);
826 return matchSubtree(value, fieldInfo);
829 template <
typename ALLOC>
833 popPath(fieldInfo, elementIndex);
837 template <
typename ALLOC>
840 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
843 template <
typename ALLOC>
844 void BasicRegexWalkFilter<ALLOC>::popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
846 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
849 template <
typename ALLOC>
850 string<ALLOC> BasicRegexWalkFilter<ALLOC>::getCurrentPath()
const
852 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
855 template <
typename ALLOC>
856 bool BasicRegexWalkFilter<ALLOC>::matchSubtree(
857 const IBasicReflectableConstPtr<ALLOC>& value,
const BasicFieldInfo<ALLOC>& fieldInfo)
const
862 BasicDefaultWalkObserver<ALLOC> defaultObserver;
863 detail::SubtreeRegexWalkFilter<ALLOC> subtreeFilter(m_currentPath, m_pathRegex, m_allocator);
864 BasicWalker<ALLOC> walker(defaultObserver, subtreeFilter);
866 return subtreeFilter.matches();
871 return std::regex_match(getCurrentPath(), m_pathRegex);
875 template <
typename ALLOC>
877 m_maxArrayLength(maxArrayLength)
880 template <
typename ALLOC>
887 template <
typename ALLOC>
894 template <
typename ALLOC>
898 return filterArrayElement(elementIndex);
901 template <
typename ALLOC>
905 return filterArrayElement(elementIndex);
908 template <
typename ALLOC>
912 return filterArrayElement(elementIndex);
915 template <
typename ALLOC>
919 return filterArrayElement(elementIndex);
922 template <
typename ALLOC>
925 return elementIndex == WALKER_NOT_ELEMENT ? true : elementIndex < m_maxArrayLength;
928 template <
typename ALLOC>
930 m_walkFilters(walkFilters)
933 template <
typename ALLOC>
940 template <
typename ALLOC>
947 template <
typename ALLOC>
954 template <
typename ALLOC>
961 template <
typename ALLOC>
968 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)