]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/parser/Tokenizer.cc
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 #include "parser/Tokenizer.h"
20 /* Native 64 bit system without strtoll() */
21 #if defined(LONG_MIN) && (SIZEOF_LONG == 8)
22 #define INT64_MIN LONG_MIN
25 #define INT64_MIN (-9223372036854775807LL-1LL)
30 /* Native 64 bit system without strtoll() */
31 #if defined(LONG_MAX) && (SIZEOF_LONG == 8)
32 #define INT64_MAX LONG_MAX
35 #define INT64_MAX 9223372036854775807LL
39 /// convenience method: consumes up to n bytes, counts, and returns them
41 Parser::Tokenizer::consume(const SBuf::size_type n
)
43 // careful: n may be npos!
44 const SBuf result
= buf_
.consume(n
);
45 parsed_
+= result
.length();
49 /// convenience method: consume()s up to n bytes and returns their count
51 Parser::Tokenizer::success(const SBuf::size_type n
)
53 return consume(n
).length();
57 Parser::Tokenizer::token(SBuf
&returnedToken
, const CharacterSet
&delimiters
)
59 const Tokenizer
saved(*this);
61 const SBuf::size_type tokenLen
= buf_
.findFirstOf(delimiters
); // not found = npos => consume to end
62 if (tokenLen
== SBuf::npos
) {
66 returnedToken
= consume(tokenLen
); // cannot be empty
72 Parser::Tokenizer::prefix(SBuf
&returnedToken
, const CharacterSet
&tokenChars
, const SBuf::size_type limit
)
74 const SBuf::size_type prefixLen
= buf_
.substr(0,limit
).findFirstNotOf(tokenChars
);
77 if (prefixLen
== SBuf::npos
&& (atEnd() || limit
== 0))
79 returnedToken
= consume(prefixLen
); // cannot be empty after the npos check
84 Parser::Tokenizer::skipAll(const CharacterSet
&tokenChars
)
86 const SBuf::size_type prefixLen
= buf_
.findFirstNotOf(tokenChars
);
89 return success(prefixLen
);
93 Parser::Tokenizer::skipOne(const CharacterSet
&chars
)
95 if (!buf_
.isEmpty() && chars
[buf_
[0]])
101 Parser::Tokenizer::skip(const SBuf
&tokenToSkip
)
103 if (buf_
.startsWith(tokenToSkip
))
104 return success(tokenToSkip
.length());
109 Parser::Tokenizer::skip(const char tokenChar
)
111 if (!buf_
.isEmpty() && buf_
[0] == tokenChar
)
116 /* reworked from compat/strtoll.c */
118 Parser::Tokenizer::int64(int64_t & result
, int base
)
123 //fixme: account for buf_.size()
125 const char *s
= buf_
.rawContent();
126 const char *end
= buf_
.rawContent() + buf_
.length();
131 } else if (*s
== '+') {
134 if (s
>= end
) return false;
135 if (( base
== 0 || base
== 16) && *s
== '0' && (s
+1 <= end
) &&
136 tolower(*(s
+1)) == 'x') {
148 if (s
>= end
) return false;
152 cutoff
= neg
? -static_cast<uint64_t>(INT64_MIN
) : INT64_MAX
;
153 const int cutlim
= cutoff
% static_cast<int64_t>(base
);
154 cutoff
/= static_cast<uint64_t>(base
);
158 for (c
= *s
++; s
<= end
; c
= *s
++) {
161 } else if (xisalpha(c
)) {
162 c
-= xisupper(c
) ? 'A' - 10 : 'a' - 10;
168 if (any
< 0 || static_cast<uint64_t>(acc
) > cutoff
|| (static_cast<uint64_t>(acc
) == cutoff
&& c
> cutlim
))
177 if (any
== 0) // nothing was parsed
180 acc
= neg
? INT64_MIN
: INT64_MAX
;
187 return success(s
- buf_
.rawContent() - 1);