// Parses a date with the format YYYY[-MM[-DD]].
// Year parsing is lenient, allows any number of digits, and +/-.
// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
static char* parseES5DatePortion(const char* currentPosition, int& year, long& month, long& day)
{
    char* postParsePosition;

    // This is a bit more lenient on the year string than ES5 specifies:
    // instead of restricting to 4 digits (or 6 digits with mandatory +/-),
    // it accepts any integer value. Consider this an implementation fallback.
    if (!parseInt(currentPosition, &postParsePosition, 10, &year))
        return 0;

    // Check for presence of -MM portion.
    if (*postParsePosition != '-')
        return postParsePosition;
    currentPosition = postParsePosition + 1;

    if (!isASCIIDigit(*currentPosition))
        return 0;
    if (!parseLong(currentPosition, &postParsePosition, 10, &month))
        return 0;
    if ((postParsePosition - currentPosition) != 2)
        return 0;

    // Check for presence of -DD portion.
    if (*postParsePosition != '-')
        return postParsePosition;
    currentPosition = postParsePosition + 1;

    if (!isASCIIDigit(*currentPosition))
        return 0;
    if (!parseLong(currentPosition, &postParsePosition, 10, &day))
        return 0;
    if ((postParsePosition - currentPosition) != 2)
        return 0;
    return postParsePosition;
}
Ejemplo n.º 2
0
double WebVTTParser::collectTimeStamp(const String& line, unsigned* position)
{
    // 4.8.10.13.3 Collect a WebVTT timestamp.
    // 1-4 - Initial checks, let most significant units be minutes.
    enum Mode { minutes, hours };
    Mode mode = minutes;
    if (*position >= line.length() || !isASCIIDigit(line[*position]))
        return malformedTime;

    // 5-6 - Collect a sequence of characters that are 0-9.
    String digits1 = collectDigits(line, position);
    int value1 = digits1.toInt();

    // 7 - If not 2 characters or value is greater than 59, interpret as hours.
    if (digits1.length() != 2 || value1 > 59)
        mode = hours;

    // 8-12 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
    if (*position >= line.length() || line[(*position)++] != ':')
        return malformedTime;
    if (*position >= line.length() || !isASCIIDigit(line[(*position)]))
        return malformedTime;
    String digits2 = collectDigits(line, position);
    int value2 = digits2.toInt();
    if (digits2.length() != 2)
        return malformedTime;

    // 13 - Detect whether this timestamp includes hours.
    int value3;
    if (mode == hours || (*position < line.length() && line[*position] == ':')) {
        if (*position >= line.length() || line[(*position)++] != ':')
            return malformedTime;
        if (*position >= line.length() || !isASCIIDigit(line[*position]))
            return malformedTime;
        String digits3 = collectDigits(line, position);
        if (digits3.length() != 2)
            return malformedTime;
        value3 = digits3.toInt();
    } else {
        value3 = value2;
        value2 = value1;
        value1 = 0;
    }

    // 14-19 - Collect next sequence of 0-9 after '.' (must be 3 chars).
    if (*position >= line.length() || line[(*position)++] != '.')
        return malformedTime;
    if (*position >= line.length() || !isASCIIDigit(line[*position]))
        return malformedTime;
    String digits4 = collectDigits(line, position);
    if (digits4.length() != 3)
        return malformedTime;
    int value4 = digits4.toInt();
    if (value2 > 59 || value3 > 59)
        return malformedTime;

    // 20-21 - Calculate result.
    return (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond);
}
Ejemplo n.º 3
0
inline bool SearchBuffer::isWordStartMatch(size_t start, size_t length) const
{
    ASSERT(m_options & AtWordStarts);

    if (!start)
        return true;

    int size = m_buffer.size();
    int offset = start;
    UChar32 firstCharacter;
    U16_GET(m_buffer.data(), 0, offset, size, firstCharacter);

    if (m_options & TreatMedialCapitalAsWordStart) {
        UChar32 previousCharacter;
        U16_PREV(m_buffer.data(), 0, offset, previousCharacter);

        if (isSeparator(firstCharacter)) {
            // The start of a separator run is a word start (".org" in "webkit.org").
            if (!isSeparator(previousCharacter))
                return true;
        } else if (isASCIIUpper(firstCharacter)) {
            // The start of an uppercase run is a word start ("Kit" in "WebKit").
            if (!isASCIIUpper(previousCharacter))
                return true;
            // The last character of an uppercase run followed by a non-separator, non-digit
            // is a word start ("Request" in "XMLHTTPRequest").
            offset = start;
            U16_FWD_1(m_buffer.data(), offset, size);
            UChar32 nextCharacter = 0;
            if (offset < size)
                U16_GET(m_buffer.data(), 0, offset, size, nextCharacter);
            if (!isASCIIUpper(nextCharacter) && !isASCIIDigit(nextCharacter) && !isSeparator(nextCharacter))
                return true;
        } else if (isASCIIDigit(firstCharacter)) {
            // The start of a digit run is a word start ("2" in "WebKit2").
            if (!isASCIIDigit(previousCharacter))
                return true;
        } else if (isSeparator(previousCharacter) || isASCIIDigit(previousCharacter)) {
            // The start of a non-separator, non-uppercase, non-digit run is a word start,
            // except after an uppercase. ("org" in "webkit.org", but not "ore" in "WebCore").
            return true;
        }
    }

    // Chinese and Japanese lack word boundary marks, and there is no clear agreement on what constitutes
    // a word, so treat the position before any CJK character as a word start.
    if (Character::isCJKIdeographOrSymbol(firstCharacter))
        return true;

    size_t wordBreakSearchStart = start + length;
    while (wordBreakSearchStart > start)
        wordBreakSearchStart = findNextWordFromIndex(m_buffer.data(), m_buffer.size(), wordBreakSearchStart, false /* backwards */);
    if (wordBreakSearchStart != start)
        return false;
    if (m_options & WholeWord)
        return static_cast<int>(start + length) == findWordEndBoundary(m_buffer.data(), m_buffer.size(), wordBreakSearchStart);
    return true;
}
// http://www.w3.org/TR/css3-syntax/#starts-with-a-number
bool CSSTokenizer::nextCharsAreNumber(UChar first)
{
    UChar second = m_input.nextInputChar();
    if (isASCIIDigit(first))
        return true;
    if (first == '+' || first == '-')
        return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input.peek(1))));
    if (first =='.')
        return (isASCIIDigit(second));
    return false;
}
Ejemplo n.º 5
0
static inline bool isTenthAlpha(const CharacterType* string, const int length)
{
    // "0.X"
    if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
        return true;

    // ".X"
    if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
        return true;

    return false;
}
Ejemplo n.º 6
0
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
bool parseHTMLInteger(const String& input, int& value)
{
    // Step 1
    // Step 2
    const UChar* position = input.characters();
    const UChar* end = position + input.length();

    // Step 3
    int sign = 1;

    // Step 4
    while (position < end) {
        if (!isHTMLSpace(*position))
            break;
        ++position;
    }

    // Step 5
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 6
    if (*position == '-') {
        sign = -1;
        ++position;
    } else if (*position == '+')
        ++position;
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 7
    if (!isASCIIDigit(*position))
        return false;

    // Step 8
    StringBuilder digits;
    while (position < end) {
        if (!isASCIIDigit(*position))
            break;
        digits.append(*position++);
    }

    // Step 9
    bool ok;
    value = sign * charactersToIntStrict(digits.characters(), digits.length(), &ok);
    return ok;
}
Ejemplo n.º 7
0
static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
{
    int length = end - string;
    if (length < 1)
        return 0;

    bool decimalMarkSeen = false;
    int processedLength = 0;

    for (int i = 0; i < length; ++i) {
        if (string[i] == terminator) {
            processedLength = i;
            break;
        }
        if (!isASCIIDigit(string[i])) {
            if (!decimalMarkSeen && string[i] == '.')
                decimalMarkSeen = true;
            else
                return 0;
        }
    }

    if (decimalMarkSeen && processedLength == 1)
        return 0;

    return processedLength;
}
Ejemplo n.º 8
0
double Value::toNumber() const
{
    switch (m_type) {
    case NodeSetValue:
        return Value(toString()).toNumber();
    case NumberValue:
        return m_number;
    case StringValue: {
        const String& str = m_data->m_string.simplifyWhiteSpace();

        // String::toDouble() supports exponential notation, which is not
        // allowed in XPath.
        unsigned len = str.length();
        for (unsigned i = 0; i < len; ++i) {
            UChar c = str[i];
            if (!isASCIIDigit(c) && c != '.'  && c != '-')
                return std::numeric_limits<double>::quiet_NaN();
        }

        bool canConvert;
        double value = str.toDouble(&canConvert);
        if (canConvert)
            return value;
        return std::numeric_limits<double>::quiet_NaN();
    }
    case BooleanValue:
        return m_bool;
    }
    ASSERT_NOT_REACHED();
    return 0.0;
}
Ejemplo n.º 9
0
bool LocaleWin::isLocalizedDigit(UChar ch)
{
    String normalizedDigit = convertFromLocalizedNumber(String(&ch, 1));
    if (normalizedDigit.length() != 1)
        return false;
    return isASCIIDigit(normalizedDigit[0]);
}
bool parseToDoubleForNumberType(const String& string, double* result)
{
    // See HTML5 2.4.4.3 `Real numbers.'

    // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
    UChar firstCharacter = string[0];
    if (firstCharacter != '-' && !isASCIIDigit(firstCharacter))
        return false;

    bool valid = false;
    double value = string.toDouble(&valid);
    if (!valid)
        return false;

    // NaN and infinity are considered valid by String::toDouble, but not valid here.
    if (!isfinite(value))
        return false;

    if (result) {
        // The following expression converts -0 to +0.
        *result = value ? value : 0;
    }

    return true;
}
Ejemplo n.º 11
0
String WebVTTParser::collectDigits(const String& input, unsigned* position)
{
    StringBuilder digits;
    while (*position < input.length() && isASCIIDigit(input[*position]))
        digits.append(input[(*position)++]);
    return digits.toString();
}
Ejemplo n.º 12
0
// https://tools.ietf.org/html/rfc6455#section-4.1
// "The HTTP version MUST be at least 1.1."
static inline bool headerHasValidHTTPVersion(StringView httpStatusLine)
{
    const char* httpVersionStaticPreambleLiteral = "HTTP/";
    StringView httpVersionStaticPreamble(reinterpret_cast<const LChar*>(httpVersionStaticPreambleLiteral), strlen(httpVersionStaticPreambleLiteral));
    if (!httpStatusLine.startsWith(httpVersionStaticPreamble))
        return false;

    // Check that there is a version number which should be at least three characters after "HTTP/"
    unsigned preambleLength = httpVersionStaticPreamble.length();
    if (httpStatusLine.length() < preambleLength + 3)
        return false;

    auto dotPosition = httpStatusLine.find('.', preambleLength);
    if (dotPosition == notFound)
        return false;

    StringView majorVersionView = httpStatusLine.substring(preambleLength, dotPosition - preambleLength);
    bool isValid;
    int majorVersion = majorVersionView.toIntStrict(isValid);
    if (!isValid)
        return false;

    unsigned minorVersionLength;
    unsigned charactersLeftAfterDotPosition = httpStatusLine.length() - dotPosition;
    for (minorVersionLength = 1; minorVersionLength < charactersLeftAfterDotPosition; minorVersionLength++) {
        if (!isASCIIDigit(httpStatusLine[dotPosition + minorVersionLength]))
            break;
    }
    int minorVersion = (httpStatusLine.substring(dotPosition + 1, minorVersionLength)).toIntStrict(isValid);
    if (!isValid)
        return false;

    return (majorVersion >= 1 && minorVersion >= 1) || majorVersion >= 2;
}
bool parseToDoubleForNumberType(const String& string, double* result)
{
    // See HTML5 2.4.4.3 `Real numbers.'
    
    // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
   // UChar firstCharacter = string[0]; Ricardo: comentando para poner lo sig
    char string1[] = "";
    UChar firstCharacter = string1[0];
    if (firstCharacter != '-' && !isASCIIDigit(firstCharacter))
        return false;

    bool valid = false;
    double value = string.toDouble(&valid);
    if (!valid)
        return false;

    // NaN and infinity are considered valid by String::toDouble, but not valid here.
    if (!isfinite(value))
        return false;

    // Numbers are considered finite IEEE 754 single-precision floating point values.
    // See HTML5 2.4.4.3 `Real numbers.'
    if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
        return false;

    if (result) {
        // The following expression converts -0 to +0.
        *result = value ? value : 0;
    }

    return true;
}
Ejemplo n.º 14
0
void ParsedCookie::setMaxAge(const String& maxAge)
{
    // According to the HTTP Cookie specification (RFC6265, http://tools.ietf.org/html/rfc6265),
    // the first character can be a DIGIT or a "-", and the reminder
    // of the value can only contain DIGIT characters.
    if (maxAge.isEmpty() || (maxAge[0] != '-' && !isASCIIDigit(maxAge[0]))) {
        LOG_ERROR("Could not parse Max-Age : %s, first character can only be '-' or ascii digit.", maxAge.ascii().data());
        return;
    }

    bool ok;
    int value = maxAge.toIntStrict(&ok);

    if (!ok) {
        LOG_ERROR("Could not parse Max-Age : %s", maxAge.ascii().data());
        return;
    }
    m_expiry = value;
    m_isMaxAgeSet = true;
    m_isSession = false;

    // If maxAge value is not positive, let expiry-time be the earliest representable time.
    if (m_expiry > 0)
        m_expiry += currentTime();
    else
        m_expiry = 0;
}
Ejemplo n.º 15
0
double parseToDoubleForNumberType(const String& string, double fallbackValue)
{
    // See HTML5 2.5.4.3 `Real numbers.'

    // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
    UChar firstCharacter = string[0];
    if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
        return fallbackValue;

    bool valid = false;
    double value = string.toDouble(&valid);
    if (!valid)
        return fallbackValue;

    // NaN and infinity are considered valid by String::toDouble, but not valid here.
    if (!std::isfinite(value))
        return fallbackValue;

    // Numbers are considered finite IEEE 754 single-precision floating point values.
    // See HTML5 2.5.4.3 `Real numbers.'
    if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
        return fallbackValue;

    // The following expression converts -0 to +0.
    return value ? value : 0;
}
Ejemplo n.º 16
0
static bool parseHTMLIntegerInternal(const CharacterType* position, const CharacterType* end, int& value)
{
    // Step 3
    int sign = 1;

    // Step 4
    while (position < end) {
        if (!isHTMLSpace<CharacterType>(*position))
            break;
        ++position;
    }

    // Step 5
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 6
    if (*position == '-') {
        sign = -1;
        ++position;
    } else if (*position == '+')
        ++position;
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 7
    if (!isASCIIDigit(*position))
        return false;

    // Step 8
    StringBuilder digits;
    while (position < end) {
        if (!isASCIIDigit(*position))
            break;
        digits.append(*position++);
    }

    // Step 9
    bool ok;
    if (digits.is8Bit())
        value = sign * charactersToIntStrict(digits.characters8(), digits.length(), &ok);
    else
        value = sign * charactersToIntStrict(digits.characters16(), digits.length(), &ok);
    return ok;
}
Ejemplo n.º 17
0
static unsigned countDigits(const String& src, unsigned start) {
  unsigned index = start;
  for (; index < src.length(); ++index) {
    if (!isASCIIDigit(src[index]))
      break;
  }
  return index - start;
}
static double getFraction(CSSTokenizerInputStream& input, unsigned& offset)
{
    if (input.peek(offset) != '.' || !isASCIIDigit(input.peek(offset + 1)))
        return 0;
    unsigned startOffset = offset;
    offset = input.skipWhilePredicate<isASCIIDigit>(offset + 1);
    return input.getDouble(startOffset, offset);
}
Ejemplo n.º 19
0
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
bool parseHTMLNonNegativeInteger(const String& input, unsigned int& value)
{
    // Step 1
    // Step 2
    const UChar* position = input.characters();
    const UChar* end = position + input.length();

    // Step 3
    while (position < end) {
        if (!isHTMLSpace(*position))
            break;
        ++position;
    }

    // Step 4
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 5
    if (*position == '+')
        ++position;

    // Step 6
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 7
    if (!isASCIIDigit(*position))
        return false;

    // Step 8
    StringBuilder digits;
    while (position < end) {
        if (!isASCIIDigit(*position))
            break;
        digits.append(*position++);
    }

    // Step 9
    bool ok;
    value = charactersToUIntStrict(digits.characters(), digits.length(), &ok);
    return ok;
}
Ejemplo n.º 20
0
static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
{
    unsigned index = start;
    for (; index < length; ++index) {
        if (!isASCIIDigit(src[index]))
            break;
    }
    return index - start;
}
Ejemplo n.º 21
0
static String collectDigits(const LChar* input, unsigned length, unsigned& position)
{
    StringBuilder digits;

    // http://www.ietf.org/rfc/rfc2326.txt
    // DIGIT ; any positive number
    while (position < length && isASCIIDigit(input[position]))
        digits.append(input[position++]);
    return digits.toString();
}
Ejemplo n.º 22
0
OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting)
    : m_protocol(protocol.convertToASCIILowercase())
    , m_host(host.convertToASCIILowercase())
    , m_subdomainSettings(subdomainSetting)
{
    ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);

    // Assume that any host that ends with a digit is trying to be an IP address.
    m_hostIsIPAddress = !m_host.isEmpty() && isASCIIDigit(m_host[m_host.length() - 1]);
}
Ejemplo n.º 23
0
static bool parseHTMLNonNegativeIntegerInternal(const CharacterType* position, const CharacterType* end, unsigned& value)
{
    // Step 3
    while (position < end) {
        if (!isHTMLSpace(*position))
            break;
        ++position;
    }

    // Step 4
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 5
    if (*position == '+')
        ++position;

    // Step 6
    if (position == end)
        return false;
    ASSERT(position < end);

    // Step 7
    if (!isASCIIDigit(*position))
        return false;

    // Step 8
    StringBuilder digits;
    while (position < end) {
        if (!isASCIIDigit(*position))
            break;
        digits.append(*position++);
    }

    // Step 9
    bool ok;
    if (digits.is8Bit())
        value = charactersToUIntStrict(digits.characters8(), digits.length(), &ok);
    else
        value = charactersToUIntStrict(digits.characters16(), digits.length(), &ok);
    return ok;
}
Ejemplo n.º 24
0
// Returns -1 if parsing fails.
static int parseNumber(const String& input, unsigned& index)
{
    unsigned digitsStart = index;
    while (index < input.length() && isASCIIDigit(input[index]))
        index++;
    if (digitsStart == index)
        return -1;
    bool ok = false;
    int number = input.substring(digitsStart, index - digitsStart).toInt(&ok);
    return ok ? number : -1;
}
Ejemplo n.º 25
0
static inline bool parseAlphaValue(const CharacterType*& string,
                                   const CharacterType* end,
                                   const char terminator,
                                   int& value) {
  while (string != end && isHTMLSpace<CharacterType>(*string))
    string++;

  bool negative = false;

  if (string != end && *string == '-') {
    negative = true;
    string++;
  }

  value = 0;

  int length = end - string;
  if (length < 2)
    return false;

  if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
    return false;

  if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
    if (checkForValidDouble(string, end, terminator)) {
      value = negative ? 0 : 255;
      string = end;
      return true;
    }
    return false;
  }

  if (length == 2 && string[0] != '.') {
    value = !negative && string[0] == '1' ? 255 : 0;
    string = end;
    return true;
  }

  if (isTenthAlpha(string, length - 1)) {
    static const int tenthAlphaValues[] = {0,   25,  51,  76,  102,
                                           127, 153, 179, 204, 230};
    value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
    string = end;
    return true;
  }

  double alpha = 0;
  if (!parseDouble(string, end, terminator, alpha))
    return false;
  value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
  string = end;
  return true;
}
Ejemplo n.º 26
0
static double getFraction(MediaQueryInputStream& input, unsigned& offset, unsigned& digitsNumber)
{
    unsigned fractionStartPos = 0;
    unsigned fractionEndPos = 0;
    if (input.peek(offset) == '.' && isASCIIDigit(input.peek(++offset))) {
        fractionStartPos = offset - 1;
        offset = input.skipWhilePredicate<isASCIIDigit>(offset);
        fractionEndPos = offset;
    }
    digitsNumber = fractionEndPos- fractionStartPos;
    return input.getDouble(fractionStartPos, fractionEndPos);
}
Ejemplo n.º 27
0
static Length parseLength(const UChar* data, unsigned length)
{
    if (length == 0)
        return Length(1, Relative);

    unsigned i = 0;
    while (i < length && isSpaceOrNewline(data[i]))
        ++i;
    if (i < length && (data[i] == '+' || data[i] == '-'))
        ++i;
    while (i < length && isASCIIDigit(data[i]))
        ++i;
    unsigned intLength = i;
    while (i < length && (isASCIIDigit(data[i]) || data[i] == '.'))
        ++i;
    unsigned doubleLength = i;

    // IE quirk: Skip whitespace between the number and the % character (20 % => 20%).
    while (i < length && isSpaceOrNewline(data[i]))
        ++i;

    bool ok;
    UChar next = (i < length) ? data[i] : ' ';
    if (next == '%') {
        // IE quirk: accept decimal fractions for percentages.
        double r = charactersToDouble(data, doubleLength, &ok);
        if (ok)
            return Length(r, Percent);
        return Length(1, Relative);
    }
    int r = charactersToIntStrict(data, intLength, &ok);
    if (next == '*') {
        if (ok)
            return Length(r, Relative);
        return Length(1, Relative);
    }
    if (ok)
        return Length(r, Fixed);
    return Length(0, Relative);
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
LiteralParser::TokenType LiteralParser::Lexer::lexNumber(LiteralParserToken& token)
{
    bool beginsWithDot = *m_ptr == '.';
    ++m_ptr;
    while (m_ptr < m_end && isASCIIDigit(*m_ptr))
        ++m_ptr;

    if (!beginsWithDot && m_ptr < m_end - 1 && *m_ptr == '.') {
        ++m_ptr;
        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
            ++m_ptr;
    }

    if (m_ptr < m_end) {
        if (*m_ptr == 'x' || *m_ptr == 'X' || *m_ptr == 'e' || *m_ptr == 'E') {
            token.type = TokError;
            return TokError;
        }
    }
    token.type = TokNumber;
    token.end = m_ptr;
    return TokNumber;
}
Ejemplo n.º 30
0
static String collectFraction(const LChar* input, unsigned length, unsigned& position)
{
    StringBuilder digits;

    // http://www.ietf.org/rfc/rfc2326.txt
    // [ "." *DIGIT ]
    if (input[position] != '.')
        return String();

    digits.append(input[position++]);
    while (position < length && isASCIIDigit(input[position]))
        digits.append(input[position++]);
    return digits.toString();
}