Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: third_party/WebKit/Source/wtf/text/StringToNumber.cpp

Issue 2058613002: Move WTF string to number converter functions to StringToNumber.h (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: missing files. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringToNumber.h ('k') | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/wtf/text/StringToNumber.cpp
diff --git a/third_party/WebKit/Source/wtf/text/StringToNumber.cpp b/third_party/WebKit/Source/wtf/text/StringToNumber.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..227f64b9f1d4bdafa02be544eb7abf15fc50b20e
--- /dev/null
+++ b/third_party/WebKit/Source/wtf/text/StringToNumber.cpp
@@ -0,0 +1,282 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "wtf/text/StringToNumber.h"
+
+#include "wtf/ASCIICType.h"
+#include "wtf/dtoa.h"
+#include "wtf/text/StringImpl.h"
+
+namespace WTF {
+
+static bool isCharacterAllowedInBase(UChar c, int base)
+{
+ if (c > 0x7F)
+ return false;
+ if (isASCIIDigit(c))
+ return c - '0' < base;
+ if (isASCIIAlpha(c)) {
+ if (base > 36)
+ base = 36;
+ return (c >= 'a' && c < 'a' + base - 10)
+ || (c >= 'A' && c < 'A' + base - 10);
+ }
+ return false;
+}
+
+template <typename IntegralType, typename CharType>
+static inline IntegralType toIntegralType(const CharType* data, size_t length, bool* ok, int base)
+{
+ static const IntegralType integralMax = std::numeric_limits<IntegralType>::max();
+ static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
+ const IntegralType maxMultiplier = integralMax / base;
+
+ IntegralType value = 0;
+ bool isOk = false;
+ bool isNegative = false;
+
+ if (!data)
+ goto bye;
+
+ // skip leading whitespace
+ while (length && isSpaceOrNewline(*data)) {
+ --length;
+ ++data;
+ }
+
+ if (isSigned && length && *data == '-') {
+ --length;
+ ++data;
+ isNegative = true;
+ } else if (length && *data == '+') {
+ --length;
+ ++data;
+ }
+
+ if (!length || !isCharacterAllowedInBase(*data, base))
+ goto bye;
+
+ while (length && isCharacterAllowedInBase(*data, base)) {
+ --length;
+ IntegralType digitValue;
+ CharType c = *data;
+ if (isASCIIDigit(c))
+ digitValue = c - '0';
+ else if (c >= 'a')
+ digitValue = c - 'a' + 10;
+ else
+ digitValue = c - 'A' + 10;
+
+ if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative))
+ goto bye;
+
+ value = base * value + digitValue;
+ ++data;
+ }
+
+#if COMPILER(MSVC)
+#pragma warning(push, 0)
+#pragma warning(disable:4146)
+#endif
+
+ if (isNegative)
+ value = -value;
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+ // skip trailing space
+ while (length && isSpaceOrNewline(*data)) {
+ --length;
+ ++data;
+ }
+
+ if (!length)
+ isOk = true;
+bye:
+ if (ok)
+ *ok = isOk;
+ return isOk ? value : 0;
+}
+
+template <typename CharType>
+static unsigned lengthOfCharactersAsInteger(const CharType* data, size_t length)
+{
+ size_t i = 0;
+
+ // Allow leading spaces.
+ for (; i != length; ++i) {
+ if (!isSpaceOrNewline(data[i]))
+ break;
+ }
+
+ // Allow sign.
+ if (i != length && (data[i] == '+' || data[i] == '-'))
+ ++i;
+
+ // Allow digits.
+ for (; i != length; ++i) {
+ if (!isASCIIDigit(data[i]))
+ break;
+ }
+
+ return i;
+}
+
+int charactersToIntStrict(const LChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<int, LChar>(data, length, ok, base);
+}
+
+int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<int, UChar>(data, length, ok, base);
+}
+
+unsigned charactersToUIntStrict(const LChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<unsigned, LChar>(data, length, ok, base);
+}
+
+unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<unsigned, UChar>(data, length, ok, base);
+}
+
+int64_t charactersToInt64Strict(const LChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<int64_t, LChar>(data, length, ok, base);
+}
+
+int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<int64_t, UChar>(data, length, ok, base);
+}
+
+uint64_t charactersToUInt64Strict(const LChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<uint64_t, LChar>(data, length, ok, base);
+}
+
+uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, int base)
+{
+ return toIntegralType<uint64_t, UChar>(data, length, ok, base);
+}
+
+int charactersToInt(const LChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<int, LChar>(data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
+}
+
+int charactersToInt(const UChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<int, UChar>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+unsigned charactersToUInt(const LChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<unsigned, LChar>(data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
+}
+
+unsigned charactersToUInt(const UChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<unsigned, UChar>(data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
+}
+
+int64_t charactersToInt64(const LChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<int64_t, LChar>(data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
+}
+
+int64_t charactersToInt64(const UChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<int64_t, UChar>(data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
+}
+
+uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<uint64_t, LChar>(data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
+}
+
+uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok)
+{
+ return toIntegralType<uint64_t, UChar>(data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
+}
+
+enum TrailingJunkPolicy { DisallowTrailingJunk, AllowTrailingJunk };
+
+template <typename CharType, TrailingJunkPolicy policy>
+static inline double toDoubleType(const CharType* data, size_t length, bool* ok, size_t& parsedLength)
+{
+ size_t leadingSpacesLength = 0;
+ while (leadingSpacesLength < length && isASCIISpace(data[leadingSpacesLength]))
+ ++leadingSpacesLength;
+
+ double number = parseDouble(data + leadingSpacesLength, length - leadingSpacesLength, parsedLength);
+ if (!parsedLength) {
+ if (ok)
+ *ok = false;
+ return 0.0;
+ }
+
+ parsedLength += leadingSpacesLength;
+ if (ok)
+ *ok = policy == AllowTrailingJunk || parsedLength == length;
+ return number;
+}
+
+double charactersToDouble(const LChar* data, size_t length, bool* ok)
+{
+ size_t parsedLength;
+ return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLength);
+}
+
+double charactersToDouble(const UChar* data, size_t length, bool* ok)
+{
+ size_t parsedLength;
+ return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLength);
+}
+
+double charactersToDouble(const LChar* data, size_t length, size_t& parsedLength)
+{
+ return toDoubleType<LChar, AllowTrailingJunk>(data, length, nullptr, parsedLength);
+}
+
+double charactersToDouble(const UChar* data, size_t length, size_t& parsedLength)
+{
+ return toDoubleType<UChar, AllowTrailingJunk>(data, length, nullptr, parsedLength);
+}
+
+float charactersToFloat(const LChar* data, size_t length, bool* ok)
+{
+ // FIXME: This will return ok even when the string fits into a double but
+ // not a float.
+ size_t parsedLength;
+ return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLength));
+}
+
+float charactersToFloat(const UChar* data, size_t length, bool* ok)
+{
+ // FIXME: This will return ok even when the string fits into a double but
+ // not a float.
+ size_t parsedLength;
+ return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLength));
+}
+
+float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength)
+{
+ // FIXME: This will return ok even when the string fits into a double but
+ // not a float.
+ return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, length, 0, parsedLength));
+}
+
+float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength)
+{
+ // FIXME: This will return ok even when the string fits into a double but
+ // not a float.
+ return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, length, 0, parsedLength));
+}
+
+} // namespace WTF
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringToNumber.h ('k') | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698