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>>
88 template <
typename ALLOC = std::allocator<u
int8_t>>
138 template <
typename ALLOC = std::allocator<u
int8_t>>
201 template <
typename ALLOC = std::allocator<u
int8_t>>
241 size_t elementIndex)
override;
243 size_t elementIndex)
override;
246 bool enterDepthLevel();
247 bool leaveDepthLevel();
262 template <
typename ALLOC = std::allocator<u
int8_t>>
302 size_t elementIndex)
override;
304 size_t elementIndex)
override;
311 StringType getCurrentPath()
const;
316 std::regex m_pathRegex;
323 template <
typename ALLOC = std::allocator<u
int8_t>>
363 size_t elementIndex)
override;
365 size_t elementIndex)
override;
368 bool filterArrayElement(
size_t elementIndex);
370 size_t m_maxArrayLength;
379 template <
typename ALLOC = std::allocator<u
int8_t>>
422 size_t elementIndex)
override;
424 size_t elementIndex)
override;
427 template <
typename FILTER_FUNC,
typename... ARGS>
428 bool applyFilters(FILTER_FUNC filterFunc, ARGS... args)
433 result &= (walkFilter.*filterFunc)(args...);
452 template <
typename ALLOC>
454 m_walkObserver(walkObserver),
455 m_walkFilter(m_defaultWalkFilter)
458 template <
typename ALLOC>
460 m_walkObserver(walkObserver),
461 m_walkFilter(walkFilter)
464 template <
typename ALLOC>
479 m_walkObserver.beginRoot(compound);
481 m_walkObserver.endRoot(compound);
484 template <
typename ALLOC>
490 std::string_view compoundChoice = compound->getChoice();
491 if (!compoundChoice.empty())
494 auto fieldsIt = std::find_if(
496 return fieldInfo.schemaName == compoundChoice;
498 if (fieldsIt != fields.
end())
500 walkField(compound->getField(compoundChoice), *fieldsIt);
509 if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo))
517 template <
typename ALLOC>
518 bool BasicWalker<ALLOC>::walkField(
519 const IBasicReflectableDataConstPtr<ALLOC>&
reflectable,
const BasicFieldInfo<ALLOC>& fieldInfo)
523 if (m_walkFilter.beforeArray(
reflectable, fieldInfo))
528 if (!walkFieldValue(
reflectable->at(i), fieldInfo, i))
535 return m_walkFilter.afterArray(
reflectable, fieldInfo);
543 template <
typename ALLOC>
544 bool BasicWalker<ALLOC>::walkFieldValue(
const IBasicReflectableDataConstPtr<ALLOC>&
reflectable,
545 const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
547 const IBasicTypeInfo<ALLOC>&
typeInfo = fieldInfo.typeInfo;
550 if (m_walkFilter.beforeCompound(
reflectable, fieldInfo, elementIndex))
552 m_walkObserver.beginCompound(
reflectable, fieldInfo, elementIndex);
554 m_walkObserver.endCompound(
reflectable, fieldInfo, elementIndex);
556 return m_walkFilter.afterCompound(
reflectable, fieldInfo, elementIndex);
560 if (m_walkFilter.beforeValue(
reflectable, fieldInfo, elementIndex))
562 m_walkObserver.visitValue(
reflectable, fieldInfo, elementIndex);
564 return m_walkFilter.afterValue(
reflectable, fieldInfo, elementIndex);
568 template <
typename ALLOC>
570 m_maxDepth(maxDepth),
574 template <
typename ALLOC>
578 return enterDepthLevel();
581 template <
typename ALLOC>
585 return leaveDepthLevel();
588 template <
typename ALLOC>
592 return enterDepthLevel();
595 template <
typename ALLOC>
599 return leaveDepthLevel();
602 template <
typename ALLOC>
606 return m_depth <= m_maxDepth;
609 template <
typename ALLOC>
616 template <
typename ALLOC>
619 const bool enter = (m_depth <= m_maxDepth);
624 template <
typename ALLOC>
625 bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel()
634 template <
typename PATH,
typename ALLOC>
635 BasicString<RebindAlloc<ALLOC, char>> getCurrentPathImpl(
const PATH& currentPath,
const ALLOC& allocator)
637 BasicString<RebindAlloc<ALLOC, char>> currentPathStr(allocator);
638 for (
auto it = currentPath.begin(); it != currentPath.end(); ++it)
640 if (!currentPathStr.empty())
642 currentPathStr +=
".";
644 currentPathStr += *it;
646 return currentPathStr;
649 template <
typename PATH,
typename ALLOC>
651 PATH& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex,
const ALLOC& allocator)
653 if (elementIndex == WALKER_NOT_ELEMENT)
655 currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size());
660 toString(fieldInfo.schemaName, allocator) +
"[" +
toString(elementIndex, allocator) +
"]";
664 template <
typename PATH,
typename ALLOC>
666 PATH& currentPath,
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex,
const ALLOC& allocator)
668 if (elementIndex == WALKER_NOT_ELEMENT)
670 currentPath.pop_back();
674 currentPath.back() =
toString(fieldInfo.schemaName, allocator);
678 template <
typename ALLOC>
679 class SubtreeRegexWalkFilter :
public IBasicWalkFilter<ALLOC>
683 const std::regex& pathRegex,
const ALLOC& allocator) :
684 m_currentPath(currentPath),
685 m_pathRegex(pathRegex),
686 m_allocator(allocator)
695 const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo)
override
697 m_currentPath.emplace_back(fieldInfo.schemaName.data(), fieldInfo.schemaName.size());
698 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
704 bool afterArray(
const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>&)
override
706 m_currentPath.pop_back();
710 bool beforeCompound(
const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
711 size_t elementIndex)
override
713 appendPath(fieldInfo, elementIndex);
714 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
720 bool afterCompound(
const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
721 size_t elementIndex)
override
723 popPath(fieldInfo, elementIndex);
727 bool beforeValue(
const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
728 size_t elementIndex)
override
730 appendPath(fieldInfo, elementIndex);
731 m_matches = std::regex_match(getCurrentPath(), m_pathRegex);
736 bool afterValue(
const IBasicReflectableDataConstPtr<ALLOC>&,
const BasicFieldInfo<ALLOC>& fieldInfo,
737 size_t elementIndex)
override
739 popPath(fieldInfo, elementIndex);
744 BasicString<RebindAlloc<ALLOC, char>> getCurrentPath()
const
746 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
749 void appendPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
751 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
754 void popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
756 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
760 std::regex m_pathRegex;
762 bool m_matches =
false;
767 template <
typename ALLOC>
769 m_pathRegex(pathRegex),
770 m_allocator(allocator)
773 template <
typename ALLOC>
779 if (std::regex_match(getCurrentPath(), m_pathRegex))
784 for (
size_t i = 0; i < array->size(); ++i)
786 m_currentPath.back() =
789 if (matchSubtree(array->at(i), fieldInfo))
800 template <
typename ALLOC>
804 m_currentPath.pop_back();
808 template <
typename ALLOC>
812 appendPath(fieldInfo, elementIndex);
813 if (std::regex_match(getCurrentPath(), m_pathRegex))
818 return matchSubtree(compound, fieldInfo);
821 template <
typename ALLOC>
825 popPath(fieldInfo, elementIndex);
829 template <
typename ALLOC>
833 appendPath(fieldInfo, elementIndex);
834 return matchSubtree(value, fieldInfo);
837 template <
typename ALLOC>
841 popPath(fieldInfo, elementIndex);
845 template <
typename ALLOC>
848 detail::appendPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
851 template <
typename ALLOC>
852 void BasicRegexWalkFilter<ALLOC>::popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
854 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
857 template <
typename ALLOC>
858 BasicString<RebindAlloc<ALLOC, char>> BasicRegexWalkFilter<ALLOC>::getCurrentPath()
const
860 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
863 template <
typename ALLOC>
864 bool BasicRegexWalkFilter<ALLOC>::matchSubtree(
865 const IBasicReflectableDataConstPtr<ALLOC>& value,
const BasicFieldInfo<ALLOC>& fieldInfo)
const
870 BasicDefaultWalkObserver<ALLOC> defaultObserver;
871 detail::SubtreeRegexWalkFilter<ALLOC> subtreeFilter(m_currentPath, m_pathRegex, m_allocator);
872 BasicWalker<ALLOC> walker(defaultObserver, subtreeFilter);
874 return subtreeFilter.matches();
879 return std::regex_match(getCurrentPath(), m_pathRegex);
883 template <
typename ALLOC>
885 m_maxArrayLength(maxArrayLength)
888 template <
typename ALLOC>
895 template <
typename ALLOC>
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>
927 return filterArrayElement(elementIndex);
930 template <
typename ALLOC>
933 return elementIndex == WALKER_NOT_ELEMENT ? true : elementIndex < m_maxArrayLength;
936 template <
typename ALLOC>
938 m_walkFilters(walkFilters)
941 template <
typename ALLOC>
948 template <
typename ALLOC>
955 template <
typename ALLOC>
962 template <
typename ALLOC>
969 template <
typename ALLOC>
976 template <
typename ALLOC>
BasicAndWalkFilter(const WalkFilters &walkFilters)
std::reference_wrapper< IBasicWalkFilter< ALLOC > > WalkFilterRef
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
Vector< WalkFilterRef, RebindAlloc< ALLOC, WalkFilterRef > > WalkFilters
bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicAndWalkFilter(const BasicAndWalkFilter &other)=delete
~BasicAndWalkFilter() override=default
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicAndWalkFilter & operator=(const BasicAndWalkFilter &other)=delete
BasicAndWalkFilter & operator=(BasicAndWalkFilter &&other)=delete
BasicAndWalkFilter(BasicAndWalkFilter &&other)=delete
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicArrayLengthWalkFilter(BasicArrayLengthWalkFilter &&other)=delete
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicArrayLengthWalkFilter(const BasicArrayLengthWalkFilter &other)=delete
~BasicArrayLengthWalkFilter() override=default
bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicArrayLengthWalkFilter & operator=(BasicArrayLengthWalkFilter &&other)=delete
BasicArrayLengthWalkFilter(size_t maxArrayLength)
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicArrayLengthWalkFilter & operator=(const BasicArrayLengthWalkFilter &other)=delete
BasicDefaultWalkFilter(BasicDefaultWalkFilter &&other)=delete
BasicDefaultWalkFilter & operator=(const BasicDefaultWalkFilter &other)=delete
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkFilter()=default
BasicDefaultWalkFilter & operator=(BasicDefaultWalkFilter &&other)=delete
BasicDefaultWalkFilter(const BasicDefaultWalkFilter &other)=delete
~BasicDefaultWalkFilter() override=default
bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
~BasicDefaultWalkObserver() override=default
BasicDefaultWalkObserver & operator=(BasicDefaultWalkObserver &&other)=delete
BasicDefaultWalkObserver(BasicDefaultWalkObserver &&other)=delete
void endCompound(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
void endRoot(const IBasicReflectableDataConstPtr< ALLOC > &) override
void beginRoot(const IBasicReflectableDataConstPtr< ALLOC > &) override
void beginCompound(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkObserver()=default
void endArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
BasicDefaultWalkObserver(const BasicDefaultWalkObserver &other)=delete
void beginArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
BasicDefaultWalkObserver & operator=(const BasicDefaultWalkObserver &other)=delete
void visitValue(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicDepthWalkFilter(size_t maxDepth)
BasicDepthWalkFilter & operator=(const BasicDepthWalkFilter &other)=delete
~BasicDepthWalkFilter() override=default
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicDepthWalkFilter & operator=(BasicDepthWalkFilter &&other)=delete
BasicDepthWalkFilter(BasicDepthWalkFilter &&other)=delete
BasicDepthWalkFilter(const BasicDepthWalkFilter &other)=delete
BasicRegexWalkFilter & operator=(BasicRegexWalkFilter &&other)=delete
BasicRegexWalkFilter & operator=(const BasicRegexWalkFilter &other)=delete
~BasicRegexWalkFilter() override=default
BasicRegexWalkFilter(const char *pathRegex, const ALLOC &allocator=ALLOC())
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicRegexWalkFilter(const BasicRegexWalkFilter &other)=delete
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicRegexWalkFilter(BasicRegexWalkFilter &&other)=delete
bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
BasicWalker(IBasicWalkObserver< ALLOC > &walkObserver)
BasicWalker & operator=(BasicWalker &&other)=delete
BasicWalker & operator=(const BasicWalker &other)=delete
BasicWalker(const BasicWalker &other)=delete
BasicWalker(BasicWalker &&other)=delete
void walk(const IBasicReflectableDataConstPtr< ALLOC > &compound)
virtual Span< const BasicFieldInfo< ALLOC > > getFields() const =0
virtual SchemaType getSchemaType() const =0
virtual std::string_view getSchemaName() const =0
virtual bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo)=0
virtual bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
Vector< BasicString< RebindAlloc< ALLOC, char > >, RebindAlloc< ALLOC, BasicString< RebindAlloc< ALLOC, char > >> > Path
virtual bool afterValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo)=0
virtual bool afterCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
virtual bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex)=0
constexpr iterator end() const noexcept
constexpr iterator begin() const noexcept
typename IBasicReflectableData< ALLOC >::ConstPtr IBasicReflectableDataConstPtr
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
std::vector< T, ALLOC > Vector
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
const IBasicTypeInfo< ALLOC > & typeInfo()
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
std::string_view schemaName
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)