diff options
author | stepych <stepych@yandex-team.ru> | 2022-02-10 16:50:51 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:50:51 +0300 |
commit | e43b253871ab6f365f22f9a139a082da542d32f7 (patch) | |
tree | ff1cbc0a584180ffb1b3cb801e24c53df865044c /library/cpp/uri/qargs.cpp | |
parent | 516d85cb3e198d4461ddfe35c5f05928948a5c40 (diff) | |
download | ydb-e43b253871ab6f365f22f9a139a082da542d32f7.tar.gz |
Restoring authorship annotation for <stepych@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/uri/qargs.cpp')
-rw-r--r-- | library/cpp/uri/qargs.cpp | 158 |
1 files changed, 79 insertions, 79 deletions
diff --git a/library/cpp/uri/qargs.cpp b/library/cpp/uri/qargs.cpp index 23058f81029..0873ca87819 100644 --- a/library/cpp/uri/qargs.cpp +++ b/library/cpp/uri/qargs.cpp @@ -1,21 +1,21 @@ -#include "qargs.h" -#include <string> - -namespace NUri { +#include "qargs.h" +#include <string> + +namespace NUri { namespace NOnStackArgsList { struct TQArgNode { TQArgNode* Prev; TQArgNode* Next; - + TStringBuf Name; TStringBuf Value; TStringBuf All; }; - + TQArgNode MakeArg(TQArgNode* prev) { return {prev, 0, {}, {}, {}}; } - + const char* SkipDelimiter(const char* str, const char* end) { while (str != end) if (*str == '&') @@ -24,41 +24,41 @@ namespace NUri { break; return str; } - + /// return next pos or 0 if error const char* ExtractArgData(const char* pos, const char* end, TQArgNode* arg) { const char* nameStart = pos; - const char* nextArg = strchr(pos, '&'); - const char* valueStart = strchr(pos, '='); - if (valueStart && nextArg && valueStart < nextArg) // a=1& or a=& - { - arg->Name = TStringBuf(nameStart, valueStart - nameStart); - arg->Value = TStringBuf(valueStart + 1, nextArg - valueStart - 1); - arg->All = TStringBuf(nameStart, nextArg - nameStart); - return nextArg; - } else if (valueStart && nextArg && valueStart > nextArg) // a&b=2 - { - arg->Name = TStringBuf(nameStart, nextArg - nameStart); - arg->All = arg->Name; - return nextArg; - } else if (valueStart && !nextArg) // a=1 or a= - { - arg->Name = TStringBuf(nameStart, valueStart - nameStart); - arg->Value = TStringBuf(valueStart + 1, end - valueStart - 1); - arg->All = TStringBuf(nameStart, end - nameStart); - return end; - } else if (!valueStart && nextArg) // a&b - { - arg->Name = TStringBuf(nameStart, nextArg - nameStart); - arg->All = arg->Name; - return nextArg; - } else { // a - arg->Name = TStringBuf(nameStart, end - nameStart); - arg->All = arg->Name; - return end; - } + const char* nextArg = strchr(pos, '&'); + const char* valueStart = strchr(pos, '='); + if (valueStart && nextArg && valueStart < nextArg) // a=1& or a=& + { + arg->Name = TStringBuf(nameStart, valueStart - nameStart); + arg->Value = TStringBuf(valueStart + 1, nextArg - valueStart - 1); + arg->All = TStringBuf(nameStart, nextArg - nameStart); + return nextArg; + } else if (valueStart && nextArg && valueStart > nextArg) // a&b=2 + { + arg->Name = TStringBuf(nameStart, nextArg - nameStart); + arg->All = arg->Name; + return nextArg; + } else if (valueStart && !nextArg) // a=1 or a= + { + arg->Name = TStringBuf(nameStart, valueStart - nameStart); + arg->Value = TStringBuf(valueStart + 1, end - valueStart - 1); + arg->All = TStringBuf(nameStart, end - nameStart); + return end; + } else if (!valueStart && nextArg) // a&b + { + arg->Name = TStringBuf(nameStart, nextArg - nameStart); + arg->All = arg->Name; + return nextArg; + } else { // a + arg->Name = TStringBuf(nameStart, end - nameStart); + arg->All = arg->Name; + return end; + } } - + // arg can be null TQArgNode* GetHead(TQArgNode* arg) { TQArgNode* prev = arg; @@ -68,7 +68,7 @@ namespace NUri { } return arg; } - + // arg can be null TQArgNode* GetLast(TQArgNode* arg) { TQArgNode* next = arg; @@ -78,30 +78,30 @@ namespace NUri { } return arg; } - + int CompareName(const TQArgNode* l, const TQArgNode* r) { return l->Name.compare(r->Name); } - + TQArgNode* Move(TQArgNode* before, TQArgNode* node) { TQArgNode* tn = node->Next; TQArgNode* tp = node->Prev; - + node->Prev = before->Prev; if (node->Prev) node->Prev->Next = node; - + node->Next = before; before->Prev = node; - + if (tn) tn->Prev = tp; if (tp) tp->Next = tn; - + return node; } - + // return new head TQArgNode* QSortByName(TQArgNode* iter, TQArgNode* last) { if (iter == last) @@ -123,32 +123,32 @@ namespace NUri { case -1: head = head ? Move(head, iter) : Move(pivot, iter); break; - + case 0: pivot = Move(pivot, iter); break; - + case 1: tail = iter; break; } - + if (iter == last) break; iter = next; } - + if (head) head = QSortByName(head, pivot->Prev); if (tail) QSortByName(tailPartitionStart->Next, tail); return head ? head : pivot; } - } - } - + } + } + using namespace NOnStackArgsList; - + class TQueryArgProcessing::Pipeline { public: Pipeline(TQueryArgProcessing& parent, TUri& subject) @@ -158,26 +158,26 @@ namespace NUri { , IsDirty(false) { } - + TQueryArg::EProcessed Process() { const TStringBuf& query = Subject.GetField(NUri::TField::FieldQuery); if (query.empty()) return ProcessEmpty(); - + const char* start = query.data(); return Parse(start, start + query.length(), 0); } - + TQueryArg::EProcessed ProcessEmpty() { if (Parent.Flags & TQueryArg::FeatureRemoveEmptyQuery) Subject.FldClr(NUri::TField::FieldQuery); - + return TQueryArg::ProcessedOK; } - + TQueryArg::EProcessed Parse(const char* str, const char* end, TQArgNode* prev) { str = SkipDelimiter(str, end); - + if (str == end) { TQArgNode* head = GetHead(prev); TQArgNode* last = GetLast(prev); @@ -187,16 +187,16 @@ namespace NUri { const char* next = ExtractArgData(str, end, ¤t); if (!next) return TQueryArg::ProcessedMalformed; - + TQArgNode* tail = ApplyFilter(prev, ¤t); - + if (++ArgsCount > MaxCount) return TQueryArg::ProcessedTooMany; - + return Parse(next, end, tail); } } - + TQArgNode* ApplyFilter(TQArgNode* prev, TQArgNode* current) { if (Parent.Flags & TQueryArg::FeatureFilter) { TQueryArg arg = {current->Name, current->Value}; @@ -209,25 +209,25 @@ namespace NUri { if (prev) prev->Next = current; return current; - } - + } + TQueryArg::EProcessed FinalizeParsing(TQArgNode* head, TQArgNode* last) { if (Parent.Flags & TQueryArg::FeatureSortByName) { head = QSortByName(head, last); IsDirty = true; } - + if (!IsDirty) return TQueryArg::ProcessedOK; - + bool dirty = Render(head); - + bool rewrite = Parent.Flags & TQueryArg::FeatureRewriteDirty; if (dirty && rewrite) Subject.Rewrite(); return (!dirty || rewrite) ? TQueryArg::ProcessedOK : TQueryArg::ProcessedDirty; } - + bool Render(TQArgNode* head) { std::string& result = Parent.Buffer; result.clear(); @@ -238,42 +238,42 @@ namespace NUri { first = false; else result.append("&"); - + result.append(head->All); head = head->Next; } - + if (result.empty()) return RenderEmpty(); else return Subject.FldMemSet(NUri::TField::FieldQuery, result); } - + bool RenderEmpty() { if (Parent.Flags & TQueryArg::FeatureRemoveEmptyQuery) Subject.FldClr(NUri::TField::FieldQuery); return false; } - + private: TQueryArgProcessing& Parent; TUri& Subject; - + unsigned ArgsCount; bool IsDirty; - + static const unsigned MaxCount = 100; }; - + TQueryArgProcessing::TQueryArgProcessing(ui32 flags, TQueryArgFilter filter, void* filterData) : Flags(flags) , Filter(filter) , FilterData(filterData) { } - + TQueryArg::EProcessed TQueryArgProcessing::Process(TUri& uri) { Pipeline pipeline(*this, uri); return pipeline.Process(); } -} +} |