1#ifndef ZSERIO_WALKER_H_INC
2#define ZSERIO_WALKER_H_INC
21template <
typename ALLOC>
22class BasicDefaultWalkFilter;
28template <
typename ALLOC = std::allocator<u
int8_t>>
88template <
typename ALLOC = std::allocator<u
int8_t>>
138template <
typename ALLOC = std::allocator<u
int8_t>>
201template <
typename ALLOC = std::allocator<u
int8_t>>
246 bool enterDepthLevel();
247 bool leaveDepthLevel();
262template <
typename ALLOC = std::allocator<u
int8_t>>
316 std::regex m_pathRegex;
323template <
typename ALLOC = std::allocator<u
int8_t>>
370 size_t m_maxArrayLength;
379template <
typename ALLOC = std::allocator<u
int8_t>>
452template <
typename ALLOC>
455 m_walkFilter(m_defaultWalkFilter)
458template <
typename ALLOC>
464template <
typename ALLOC>
476 <<
typeInfo.getSchemaName() <<
"' is not a compound type!";
484template <
typename ALLOC>
496 return fieldInfo.schemaName == compoundChoice;
507 for (
const BasicFieldInfo<ALLOC>& fieldInfo :
typeInfo.getFields())
509 if (!walkField(compound->getField(fieldInfo.schemaName), fieldInfo))
517template <
typename ALLOC>
518bool 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);
543template <
typename ALLOC>
544bool 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);
568template <
typename ALLOC>
574template <
typename ALLOC>
578 return enterDepthLevel();
581template <
typename ALLOC>
585 return leaveDepthLevel();
588template <
typename ALLOC>
592 return enterDepthLevel();
595template <
typename ALLOC>
599 return leaveDepthLevel();
602template <
typename ALLOC>
606 return m_depth <= m_maxDepth;
609template <
typename ALLOC>
616template <
typename ALLOC>
619 const bool enter = (m_depth <= m_maxDepth);
624template <
typename ALLOC>
625bool BasicDepthWalkFilter<ALLOC>::leaveDepthLevel()
634template <
typename PATH,
typename ALLOC>
635BasicString<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;
649template <
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) +
"]";
664template <
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);
678template <
typename ALLOC>
679class SubtreeRegexWalkFilter :
public IBasicWalkFilter<ALLOC>
682 SubtreeRegexWalkFilter(
const typename IBasicWalkFilter<ALLOC>::Path& currentPath,
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);
759 typename IBasicWalkFilter<ALLOC>::Path m_currentPath;
760 std::regex m_pathRegex;
762 bool m_matches =
false;
767template <
typename ALLOC>
773template <
typename ALLOC>
779 if (std::regex_match(getCurrentPath(), m_pathRegex))
784 for (
size_t i = 0;
i <
array->size(); ++
i)
786 m_currentPath.back() =
800template <
typename ALLOC>
804 m_currentPath.pop_back();
808template <
typename ALLOC>
813 if (std::regex_match(getCurrentPath(), m_pathRegex))
821template <
typename ALLOC>
829template <
typename ALLOC>
837template <
typename ALLOC>
845template <
typename ALLOC>
851template <
typename ALLOC>
852void BasicRegexWalkFilter<ALLOC>::popPath(
const BasicFieldInfo<ALLOC>& fieldInfo,
size_t elementIndex)
854 detail::popPathImpl(m_currentPath, fieldInfo, elementIndex, m_allocator);
857template <
typename ALLOC>
858BasicString<RebindAlloc<ALLOC, char>> BasicRegexWalkFilter<ALLOC>::getCurrentPath()
const
860 return detail::getCurrentPathImpl(m_currentPath, m_allocator);
863template <
typename ALLOC>
864bool 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);
883template <
typename ALLOC>
888template <
typename ALLOC>
895template <
typename ALLOC>
902template <
typename ALLOC>
909template <
typename ALLOC>
916template <
typename ALLOC>
923template <
typename ALLOC>
930template <
typename ALLOC>
936template <
typename ALLOC>
941template <
typename ALLOC>
948template <
typename ALLOC>
955template <
typename ALLOC>
962template <
typename ALLOC>
969template <
typename ALLOC>
976template <
typename ALLOC>
BasicAndWalkFilter(const WalkFilters &walkFilters)
std::reference_wrapper< IBasicWalkFilter< ALLOC > > WalkFilterRef
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicAndWalkFilter & operator=(BasicAndWalkFilter &&other)=delete
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(BasicAndWalkFilter &&other)=delete
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicAndWalkFilter & operator=(const BasicAndWalkFilter &other)=delete
BasicArrayLengthWalkFilter & operator=(const BasicArrayLengthWalkFilter &other)=delete
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
BasicArrayLengthWalkFilter & operator=(BasicArrayLengthWalkFilter &&other)=delete
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(size_t maxArrayLength)
bool beforeArray(const IBasicReflectableDataConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
BasicDefaultWalkFilter(BasicDefaultWalkFilter &&other)=delete
bool beforeValue(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkFilter & operator=(BasicDefaultWalkFilter &&other)=delete
BasicDefaultWalkFilter & operator=(const BasicDefaultWalkFilter &other)=delete
bool afterArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
bool beforeCompound(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkFilter()=default
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(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
BasicDefaultWalkObserver & operator=(const BasicDefaultWalkObserver &other)=delete
void endArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
BasicDefaultWalkObserver(const BasicDefaultWalkObserver &other)=delete
void beginArray(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &) override
void visitValue(const IBasicReflectableDataConstPtr< ALLOC > &, const BasicFieldInfo< ALLOC > &, size_t) override
BasicDefaultWalkObserver & operator=(BasicDefaultWalkObserver &&other)=delete
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
BasicDepthWalkFilter & operator=(BasicDepthWalkFilter &&other)=delete
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(BasicDepthWalkFilter &&other)=delete
BasicDepthWalkFilter(const BasicDepthWalkFilter &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
BasicRegexWalkFilter & operator=(BasicRegexWalkFilter &&other)=delete
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 & operator=(const BasicWalker &other)=delete
BasicWalker(IBasicWalkObserver< ALLOC > &walkObserver)
BasicWalker(const BasicWalker &other)=delete
BasicWalker(BasicWalker &&other)=delete
void walk(const IBasicReflectableDataConstPtr< ALLOC > &compound)
BasicWalker & operator=(BasicWalker &&other)=delete
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
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
const IBasicTypeInfo< ALLOC > & typeInfo()
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)