1 #ifndef ZSERIO_WALKER_H_INC
2 #define ZSERIO_WALKER_H_INC
22 template <
typename ALLOC>
23 class BasicDefaultWalkFilter;
29 template <
typename ALLOC = std::allocator<u
int8_t>>
87 template <
typename ALLOC = std::allocator<u
int8_t>>
136 template <
typename ALLOC = std::allocator<u
int8_t>>
197 template <
typename ALLOC = std::allocator<u
int8_t>>
234 size_t elementIndex)
override;
237 size_t elementIndex)
override;
239 size_t elementIndex)
override;
242 bool enterDepthLevel();
243 bool leaveDepthLevel();
258 template <
typename ALLOC = std::allocator<u
int8_t>>
295 size_t elementIndex)
override;
298 size_t elementIndex)
override;
300 size_t elementIndex)
override;
310 std::regex m_pathRegex;
317 template <
typename ALLOC = std::allocator<u
int8_t>>
354 size_t elementIndex)
override;
357 size_t elementIndex)
override;
359 size_t elementIndex)
override;
362 bool filterArrayElement(
size_t elementIndex);
364 size_t m_maxArrayLength;
373 template <
typename ALLOC = std::allocator<u
int8_t>>
413 size_t elementIndex)
override;
416 size_t elementIndex)
override;
418 size_t elementIndex)
override;
421 template <
typename FILTER_FUNC,
typename... ARGS>
422 bool applyFilters(FILTER_FUNC filterFunc, ARGS... args)
427 result &= (walkFilter.*filterFunc)(args...);
446 template <
typename ALLOC>
448 m_walkObserver(walkObserver),
449 m_walkFilter(m_defaultWalkFilter)
452 template <
typename ALLOC>
454 m_walkObserver(walkObserver),
455 m_walkFilter(walkFilter)
458 template <
typename ALLOC>
473 m_walkObserver.beginRoot(compound);
474 walkFields(compound, typeInfo);
475 m_walkObserver.endRoot(compound);
478 template <
typename ALLOC>
484 StringView compoundChoice = compound->getChoice();
485 if (!compoundChoice.
empty())
488 auto fieldsIt = std::find_if(
490 return fieldInfo.schemaName == compoundChoice;
492 if (fieldsIt != fields.
end())
494 walkField(compound->getField(compoundChoice), *fieldsIt);
501 for (
const BasicFieldInfo<ALLOC>& fieldInfo : typeInfo.
getFields())
503 if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo))
511 template <
typename ALLOC>
512 bool BasicWalker<ALLOC>::walkField(
513 const IBasicReflectableConstPtr<ALLOC>& reflectable,
const BasicFieldInfo<ALLOC>& fieldInfo)
515 if (reflectable && fieldInfo.isArray)
517 if (m_walkFilter.beforeArray(reflectable, fieldInfo))
519 m_walkObserver.beginArray(reflectable, fieldInfo);
520 for (
size_t i = 0; i < reflectable->size(); ++i)
522 if (!walkFieldValue(reflectable->at(i), fieldInfo, i))
527 m_walkObserver.endArray(reflectable, fieldInfo);
529 return m_walkFilter.afterArray(reflectable, fieldInfo);
533 return walkFieldValue(reflectable, fieldInfo);
537 template <
typename ALLOC>
538 bool BasicWalker<ALLOC>::walkFieldValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable,
539 const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
541 const IBasicTypeInfo<ALLOC>& typeInfo = fieldInfo.typeInfo;
544 if (m_walkFilter.beforeCompound(reflectable, fieldInfo, elementIndex))
546 m_walkObserver.beginCompound(reflectable, fieldInfo, elementIndex);
547 walkFields(reflectable, typeInfo);
548 m_walkObserver.endCompound(reflectable, fieldInfo, elementIndex);
550 return m_walkFilter.afterCompound(reflectable, fieldInfo, elementIndex);
554 if (m_walkFilter.beforeValue(reflectable, fieldInfo, elementIndex))
556 m_walkObserver.visitValue(reflectable, fieldInfo, elementIndex);
558 return m_walkFilter.afterValue(reflectable, fieldInfo, elementIndex);
562 template <
typename ALLOC>
564 m_maxDepth(maxDepth),
568 template <
typename ALLOC>
572 return enterDepthLevel();
575 template <
typename ALLOC>
579 return leaveDepthLevel();
582 template <
typename ALLOC>
586 return enterDepthLevel();
589 template <
typename ALLOC>
593 return leaveDepthLevel();
596 template <
typename ALLOC>
600 return m_depth <= m_maxDepth;
603 template <
typename ALLOC>
610 template <
typename ALLOC>
613 const bool enter = (m_depth <= m_maxDepth);
618 template <
typename ALLOC>
619 bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel()
628 template <
typename ALLOC>
629 string<ALLOC> getCurrentPathImpl(
const vector<string<ALLOC>, ALLOC>& currentPath,
const ALLOC& allocator)
631 string<ALLOC> currentPathStr(allocator);
632 for (
auto it = currentPath.begin(); it != currentPath.end(); ++it)
634 if (!currentPathStr.empty())
636 currentPathStr +=
".";
638 currentPathStr += *it;
640 return currentPathStr;
643 template <
typename ALLOC>
644 void appendPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
645 size_t elementIndex,
const ALLOC& allocator)
647 if (elementIndex == WALKER_NOT_ELEMENT)
649 currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size(), allocator);
654 toString(fieldInfo.schemaName, allocator) +
"[" +
toString(elementIndex, allocator) +
"]";
658 template <
typename ALLOC>
659 void popPathImpl(
vector<string<ALLOC>, ALLOC>& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
660 size_t elementIndex,
const ALLOC& allocator)
662 if (elementIndex == WALKER_NOT_ELEMENT)
664 currentPath.pop_back();
668 currentPath.back() =
toString(fieldInfo.schemaName, allocator);
672 template <
typename ALLOC>
673 class SubtreeRegexWalkFilter :
public IBasicWalkFilter<ALLOC>
676 SubtreeRegexWalkFilter(
const vector<string<ALLOC>, ALLOC>& currentPath,
const std::regex& pathRegex,
677 const ALLOC& allocator) :
678 m_currentPath(currentPath),
679 m_pathRegex(pathRegex),
680 m_allocator(allocator)
688 bool beforeArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo)
override
690 m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size());
691 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
697 bool afterArray(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>&)
override
699 m_currentPath.pop_back();
703 bool beforeCompound(
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);
713 bool afterCompound(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
714 size_t elementIndex)
override
716 popPath(fieldInfo, elementIndex);
720 bool beforeValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
721 size_t elementIndex)
override
723 appendPath(fieldInfo, elementIndex);
724 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
729 bool afterValue(
const IBasicReflectableConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
730 size_t elementIndex)
override
732 popPath(fieldInfo, elementIndex);
737 string<ALLOC> getCurrentPath()
const
739 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
742 void appendPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
744 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
747 void popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
749 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
752 vector<string<ALLOC>, ALLOC> m_currentPath;
753 std::regex m_pathRegex;
755 bool m_matches =
false;
760 template <
typename ALLOC>
762 m_pathRegex(pathRegex),
763 m_allocator(allocator)
766 template <
typename ALLOC>
772 if (std::regex_match(getCurrentPath(), m_pathRegex))
777 for (
size_t i = 0; i < array->size(); ++i)
779 m_currentPath.back() =
782 if (matchSubtree(array->at(i), fieldInfo))
793 template <
typename ALLOC>
797 m_currentPath.pop_back();
801 template <
typename ALLOC>
805 appendPath(fieldInfo, elementIndex);
806 if (std::regex_match(getCurrentPath(), m_pathRegex))
811 return matchSubtree(compound, fieldInfo);
814 template <
typename ALLOC>
818 popPath(fieldInfo, elementIndex);
822 template <
typename ALLOC>
826 appendPath(fieldInfo, elementIndex);
827 return matchSubtree(value, fieldInfo);
830 template <
typename ALLOC>
834 popPath(fieldInfo, elementIndex);
838 template <
typename ALLOC>
841 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
844 template <
typename ALLOC>
845 void BasicRegexWalkFilter<ALLOC>::popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
847 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
850 template <
typename ALLOC>
851 string<ALLOC> BasicRegexWalkFilter<ALLOC>::getCurrentPath()
const
853 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
856 template <
typename ALLOC>
857 bool BasicRegexWalkFilter<ALLOC>::matchSubtree(
858 const IBasicReflectableConstPtr<ALLOC>& value,
const BasicFieldInfo<ALLOC>& fieldInfo)
const
863 BasicDefaultWalkObserver<ALLOC> defaultObserver;
864 detail::SubtreeRegexWalkFilter<ALLOC> subtreeFilter(m_currentPath, m_pathRegex, m_allocator);
865 BasicWalker<ALLOC> walker(defaultObserver, subtreeFilter);
867 return subtreeFilter.matches();
872 return std::regex_match(getCurrentPath(), m_pathRegex);
876 template <
typename ALLOC>
878 m_maxArrayLength(maxArrayLength)
881 template <
typename ALLOC>
888 template <
typename ALLOC>
895 template <
typename ALLOC>
899 return filterArrayElement(elementIndex);
902 template <
typename ALLOC>
906 return filterArrayElement(elementIndex);
909 template <
typename ALLOC>
913 return filterArrayElement(elementIndex);
916 template <
typename ALLOC>
920 return filterArrayElement(elementIndex);
923 template <
typename ALLOC>
926 return elementIndex == WALKER_NOT_ELEMENT ? true : elementIndex < m_maxArrayLength;
929 template <
typename ALLOC>
931 m_walkFilters(walkFilters)
934 template <
typename ALLOC>
941 template <
typename ALLOC>
948 template <
typename ALLOC>
955 template <
typename ALLOC>
962 template <
typename ALLOC>
969 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)