25 debugs(24, 5,
"consuming " << n <<
" bytes");
35 return consume(n).
length();
42 debugs(24, 5,
"consuming " << n <<
" bytes");
48 buf_ = result.
consume(buf_.length() - parsed);
57 return consumeTrailing(n).
length();
67 debugs(24, 8,
"no token found for delimiters " << delimiters.
name);
71 returnedToken = consume(tokenLen);
74 returnedToken <<
'\'');
81 SBuf::size_type prefixLen = buf_.substr(0,limit).findFirstNotOf(tokenChars);
83 debugs(24, 8,
"no prefix for set " << tokenChars.
name);
86 if (prefixLen ==
SBuf::npos && (atEnd() || limit == 0)) {
87 debugs(24, 8,
"no char in set " << tokenChars.
name <<
" while looking for prefix");
91 debugs(24, 8,
"whole haystack matched");
94 debugs(24, 8,
"found with length " << prefixLen);
95 returnedToken = consume(prefixLen);
107 if (!prefix(result, tokenChars, limit))
121 if (limit < buf_.length())
122 span.
consume(buf_.length() - limit);
126 while (i != span.
rend() && tokenChars[*i]) {
132 returnedToken = consumeTrailing(found);
140 if (prefixLen == 0) {
141 debugs(24, 8,
"no match when trying to skipAll " << tokenChars.
name);
144 debugs(24, 8,
"skipping all in " << tokenChars.
name <<
" len " << prefixLen);
145 return success(prefixLen);
151 if (skip(tokenToSkip) || tokenToSkip.
isEmpty())
163 if (!buf_.isEmpty() && chars[buf_[0]]) {
164 debugs(24, 8,
"skipping one-of " << chars.
name);
167 debugs(24, 8,
"no match while skipping one-of " << chars.
name);
174 if (buf_.length() < tokenToSkip.
length())
178 if (tokenToSkip.
length() < buf_.length())
179 offset = buf_.length() - tokenToSkip.
length();
181 if (buf_.substr(offset,
SBuf::npos).cmp(tokenToSkip) == 0) {
183 return successTrailing(tokenToSkip.
length());
191 if (buf_.startsWith(tokenToSkip)) {
193 return success(tokenToSkip.
length());
195 debugs(24, 8,
"no match, not skipping '" << tokenToSkip <<
'\'');
202 if (!buf_.isEmpty() && buf_[0] == tokenChar) {
203 debugs(24, 8,
"skipping char '" << tokenChar <<
'\'');
206 debugs(24, 8,
"no match, not skipping char '" << tokenChar <<
'\'');
213 if (!buf_.isEmpty() && skippable[buf_[buf_.length()-1]]) {
214 debugs(24, 8,
"skipping one-of " << skippable.
name);
215 return successTrailing(1);
217 debugs(24, 8,
"no match while skipping one-of " << skippable.
name);
228 if (suffixLen == 0) {
229 debugs(24, 8,
"no match when trying to skip " << skippable.
name);
232 debugs(24, 8,
"skipping in " << skippable.
name <<
" len " << suffixLen);
233 return successTrailing(suffixLen);
240 if (atEnd() || limit == 0)
243 const SBuf range(buf_.substr(0,limit));
254 }
else if (*s ==
'+') {
257 if (s >= end)
return false;
259 if (( base == 0 || base == 16) && *s ==
'0' && (s+1 < end ) &&
260 tolower(*(s+1)) ==
'x') {
271 if (s >= end)
return false;
276 const int cutlim = cutoff %
static_cast<int64_t
>(base);
277 cutoff /=
static_cast<uint64_t
>(base);
286 c -=
xisupper(c) ?
'A' - 10 :
'a' - 10;
292 if (any < 0 ||
static_cast<uint64_t
>(acc) > cutoff || (
static_cast<uint64_t
>(acc) == cutoff && c > cutlim))
326 if (!int64(result, 10,
false, limit))
#define Here()
source code location of the caller
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
optimized set of C chars, with quick membership test and merge support
const char * name
optional set label for debugging (default: "anonymous")
SBuf::size_type skipAllTrailing(const CharacterSet &discardables)
bool prefix(SBuf &returnedToken, const CharacterSet &tokenChars, SBuf::size_type limit=SBuf::npos)
SBuf buf_
yet unparsed input
bool suffix(SBuf &returnedToken, const CharacterSet &tokenChars, SBuf::size_type limit=SBuf::npos)
SBuf::size_type successTrailing(const SBuf::size_type n)
convenience method: consumes up to n last bytes and returns their count
bool skipOne(const CharacterSet &discardables)
bool token(SBuf &returnedToken, const CharacterSet &delimiters)
SBuf consumeTrailing(const SBuf::size_type n)
convenience method: consumes up to n last bytes and returns them
SBuf::size_type success(const SBuf::size_type n)
convenience method: consume()s up to n bytes and returns their count
bool skipSuffix(const SBuf &tokenToSkip)
SBuf::size_type skipAll(const CharacterSet &discardables)
bool int64(int64_t &result, int base=0, bool allowSign=true, SBuf::size_type limit=SBuf::npos)
SBuf consume(const SBuf::size_type n)
convenience method: consumes up to n bytes, counts, and returns them
bool skipOneTrailing(const CharacterSet &discardables)
void skipRequired(const char *description, const SBuf &tokenToSkip)
SBuf::size_type parsed_
bytes successfully parsed, including skipped
int64_t udec64(const char *description, SBuf::size_type limit=SBuf::npos)
int64() wrapper but limited to unsigned decimal integers (for now)
bool skip(const SBuf &tokenToSkip)
const char * rawContent() const
static const size_type npos
SBuf consume(size_type n=npos)
size_type length() const
Returns the number of bytes stored in SBuf.
const_reverse_iterator rbegin() const
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
MemBlob::size_type size_type
const_reverse_iterator rend() const
an std::runtime_error with thrower location info
#define debugs(SECTION, LEVEL, CONTENT)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf