HTMLParserIdioms.cpp [plain text]
#include "config.h"
#include "HTMLParserIdioms.h"
#include <limits>
#include <wtf/MathExtras.h>
#include <wtf/dtoa.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
String stripLeadingAndTrailingHTMLSpaces(const String& string)
{
const UChar* characters = string.characters();
unsigned length = string.length();
unsigned numLeadingSpaces;
for (numLeadingSpaces = 0; numLeadingSpaces < length; ++numLeadingSpaces) {
if (isNotHTMLSpace(characters[numLeadingSpaces]))
break;
}
if (numLeadingSpaces == length)
return string.isNull() ? string : emptyAtom.string();
unsigned numTrailingSpaces;
for (numTrailingSpaces = 0; numTrailingSpaces < length; ++numTrailingSpaces) {
if (isNotHTMLSpace(characters[length - numTrailingSpaces - 1]))
break;
}
ASSERT(numLeadingSpaces + numTrailingSpaces < length);
return string.substring(numLeadingSpaces, length - (numLeadingSpaces + numTrailingSpaces));
}
String serializeForNumberType(double number)
{
NumberToStringBuffer buffer;
return String(numberToString(number, buffer));
}
bool parseToDoubleForNumberType(const String& string, double* result)
{
UChar firstCharacter = string[0];
if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
return false;
bool valid = false;
double value = string.toDouble(&valid);
if (!valid)
return false;
if (!isfinite(value))
return false;
if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
return false;
if (result) {
*result = value ? value : 0;
}
return true;
}
bool parseToDoubleForNumberTypeWithDecimalPlaces(const String& string, double *result, unsigned *decimalPlaces)
{
if (decimalPlaces)
*decimalPlaces = 0;
if (!parseToDoubleForNumberType(string, result))
return false;
if (!decimalPlaces)
return true;
size_t dotIndex = string.find('.');
size_t eIndex = string.find('e');
if (eIndex == notFound)
eIndex = string.find('E');
unsigned baseDecimalPlaces = 0;
if (dotIndex != notFound) {
if (eIndex == notFound)
baseDecimalPlaces = string.length() - dotIndex - 1;
else
baseDecimalPlaces = eIndex - dotIndex - 1;
}
int exponent = 0;
if (eIndex != notFound) {
unsigned cursor = eIndex + 1, cursorSaved;
int digit, exponentSign;
int32_t exponent32;
size_t length = string.length();
exponentSign = 0;
switch (digit = string[cursor]) {
case '-':
exponentSign = 1;
case '+':
digit = string[++cursor];
}
if (digit >= '0' && digit <= '9') {
while (cursor < length && digit == '0')
digit = string[++cursor];
if (digit > '0' && digit <= '9') {
exponent32 = digit - '0';
cursorSaved = cursor;
while (cursor < length && (digit = string[++cursor]) >= '0' && digit <= '9')
exponent32 = (10 * exponent32) + digit - '0';
if (cursor - cursorSaved > 8 || exponent32 > 19999)
exponent = 19999;
else
exponent = static_cast<int>(exponent32);
if (exponentSign)
exponent = -exponent;
} else
exponent = 0;
}
}
int intDecimalPlaces = baseDecimalPlaces - exponent;
if (intDecimalPlaces < 0)
*decimalPlaces = 0;
else if (intDecimalPlaces > 19999)
*decimalPlaces = 19999;
else
*decimalPlaces = static_cast<unsigned>(intDecimalPlaces);
return true;
}
bool parseHTMLInteger(const String& input, int& value)
{
const UChar* position = input.characters();
const UChar* end = position + input.length();
int sign = 1;
while (position < end) {
if (!isHTMLSpace(*position))
break;
++position;
}
if (position == end)
return false;
ASSERT(position < end);
if (*position == '-') {
sign = -1;
++position;
} else if (*position == '+')
++position;
if (position == end)
return false;
ASSERT(position < end);
if (!isASCIIDigit(*position))
return false;
StringBuilder digits;
while (position < end) {
if (!isASCIIDigit(*position))
break;
digits.append(*position++);
}
bool ok;
value = sign * charactersToIntStrict(digits.characters(), digits.length(), &ok);
return ok;
}
bool parseHTMLNonNegativeInteger(const String& input, unsigned int& value)
{
const UChar* position = input.characters();
const UChar* end = position + input.length();
while (position < end) {
if (!isHTMLSpace(*position))
break;
++position;
}
if (position == end)
return false;
ASSERT(position < end);
if (*position == '+')
++position;
if (position == end)
return false;
ASSERT(position < end);
if (!isASCIIDigit(*position))
return false;
StringBuilder digits;
while (position < end) {
if (!isASCIIDigit(*position))
break;
digits.append(*position++);
}
bool ok;
value = charactersToUIntStrict(digits.characters(), digits.length(), &ok);
return ok;
}
}