123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #pragma once
- #include <util/generic/algorithm.h>
- #include <util/generic/strbuf.h>
- #include <util/generic/yexception.h>
- #include <util/string/cast.h>
- #include <util/system/yassert.h>
- #include <iterator>
- class TDelimStringIter {
- public:
- using value_type = TStringBuf;
- using difference_type = ptrdiff_t;
- using pointer = const TStringBuf*;
- using reference = const TStringBuf&;
- using iterator_category = std::forward_iterator_tag;
- inline TDelimStringIter(const char* begin, const char* strEnd, TStringBuf delim)
- : TDelimStringIter(TStringBuf(begin, strEnd), delim)
- {
- }
- inline TDelimStringIter(TStringBuf str, TStringBuf delim)
- : IsValid(true)
- , Str(str)
- , Delim(delim)
- {
- UpdateCurrent();
- }
- inline TDelimStringIter()
- : IsValid(false)
- {
- }
- inline explicit operator bool() const {
- return IsValid;
- }
- // NOTE: this is a potentially unsafe operation (no overrun check)
- inline TDelimStringIter& operator++() {
- if (Current.end() != Str.end()) {
- Str.Skip(Current.length() + Delim.length());
- UpdateCurrent();
- } else {
- Str.Clear();
- Current.Clear();
- IsValid = false;
- }
- return *this;
- }
- inline void operator+=(size_t n) {
- for (; n > 0; --n) {
- ++(*this);
- }
- }
- inline bool operator==(const TDelimStringIter& rhs) const {
- return (IsValid == rhs.IsValid) && (!IsValid || (Current.begin() == rhs.Current.begin()));
- }
- inline bool operator!=(const TDelimStringIter& rhs) const {
- return !(*this == rhs);
- }
- inline TStringBuf operator*() const {
- return Current;
- }
- inline const TStringBuf* operator->() const {
- return &Current;
- }
- // Get & advance
- template <class T>
- inline bool TryNext(T& t) {
- if (IsValid) {
- t = FromString<T>(Current);
- operator++();
- return true;
- } else {
- return false;
- }
- }
- template <class T>
- inline TDelimStringIter& Next(T& t) // Get & advance
- {
- if (!TryNext(t))
- ythrow yexception() << "No valid field";
- return *this;
- }
- template <class T>
- inline T GetNext() {
- T res;
- Next(res);
- return res;
- }
- inline const char* GetBegin() const {
- return Current.begin();
- }
- inline const char* GetEnd() const {
- return Current.end();
- }
- inline bool Valid() const {
- return IsValid;
- }
- // contents from next token to the end of string
- inline TStringBuf Cdr() const {
- return Str.SubStr(Current.length() + Delim.length());
- }
- inline TDelimStringIter IterEnd() const {
- return TDelimStringIter();
- }
- private:
- inline void UpdateCurrent() {
- // it is much faster than TStringBuf::find
- size_t pos = std::search(Str.begin(), Str.end(), Delim.begin(), Delim.end()) - Str.begin();
- Current = Str.Head(pos);
- }
- private:
- bool IsValid;
- TStringBuf Str;
- TStringBuf Current;
- TStringBuf Delim;
- };
- //example: for (TStringBuf field: TDelimStroka(line, "@@")) { ... }
- struct TDelimStroka {
- TStringBuf S;
- TStringBuf Delim;
- inline TDelimStroka(TStringBuf s, TStringBuf delim)
- : S(s)
- , Delim(delim)
- {
- }
- inline TDelimStringIter begin() const {
- return TDelimStringIter(S, Delim);
- }
- inline TDelimStringIter end() const {
- return TDelimStringIter();
- }
- };
- inline TDelimStringIter begin_delim(const TString& str, TStringBuf delim) {
- return TDelimStringIter(str, delim);
- }
- inline TDelimStringIter begin_delim(TStringBuf str, TStringBuf delim) {
- return TDelimStringIter(str.begin(), str.end(), delim);
- }
- inline TDelimStringIter end_delim(const TString& /*str*/, TStringBuf /*delim*/) {
- return TDelimStringIter();
- }
- class TKeyValueDelimStringIter {
- public:
- TKeyValueDelimStringIter(const TStringBuf str, const TStringBuf delim);
- bool Valid() const;
- TKeyValueDelimStringIter& operator++();
- const TStringBuf& Key() const;
- const TStringBuf& Value() const;
- private:
- TDelimStringIter DelimIter;
- TStringBuf ChunkKey, ChunkValue;
- private:
- void ReadKeyAndValue();
- };
|