// https://github.com/mfichman/http #pragma once #include namespace std::net { template class ParseResult { public: T value; char const* ch; }; template static ParseResult ParseUntil(char const* str, F func) { ParseResult result{}; char const* ch = str; for (; *ch && !func(*ch); ++ch) { } result.value = std::string(str, ch - str); result.ch = ch; return result; } template static inline ParseResult ParseWhile(char const* str, F func) { ParseResult result{}; char const* ch = str; for (; *ch && func(*ch); ++ch) { } result.value = std::string(str, ch - str); result.ch = ch; return result; } static inline ParseResult ParseToken(char const* str) { auto token = ParseUntil(str, isspace); token.ch = ParseWhile(token.ch, isspace).ch; return token; } static inline ParseResult parseCrLf(char const* str) { auto cr = ParseUntil(str, [](char ch) { return ch == '\r'; }); if (*cr.ch == '\r') cr.ch++; return ParseWhile(cr.ch, [](char ch) { return isspace(ch) && ch != '\r'; }); } static inline ParseResult ParseWhitespace(char const* str) { return ParseWhile(str, isspace); } }