bool VTTScanner::scanFloat(float& number) { Run integerRun = collectWhile<isASCIIDigit>(); seekTo(integerRun.end()); Run decimalRun(getPosition(), getPosition(), m_is8Bit); if (scan('.')) { decimalRun = collectWhile<isASCIIDigit>(); seekTo(decimalRun.end()); } // At least one digit required. if (integerRun.isEmpty() && decimalRun.isEmpty()) { // Restore to starting position. seekTo(integerRun.start()); return false; } size_t lengthOfFloat = Run(integerRun.start(), getPosition(), m_is8Bit).length(); bool validNumber; if (m_is8Bit) number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber); else number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber); if (!validNumber) number = std::numeric_limits<float>::max(); return true; }
static float numericPrefix(const String& keyString, const String& valueString, Document* document, bool* ok = 0) { size_t parsedLength; float value; if (valueString.is8Bit()) value = charactersToFloat(valueString.characters8(), valueString.length(), parsedLength); else value = charactersToFloat(valueString.characters16(), valueString.length(), parsedLength); if (!parsedLength) { reportViewportWarning(document, UnrecognizedViewportArgumentValueError, valueString, keyString); if (ok) *ok = false; return 0; } if (parsedLength < valueString.length()) reportViewportWarning(document, TruncatedViewportArgumentValueError, valueString, keyString); if (ok) *ok = true; return value; }
float toFloat(const CharType* attribute, bool& isValid) { // Make sure the is a valid floating point number // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number unsigned lengthExcludingDescriptor = length - 1; if (lengthExcludingDescriptor > 0 && *(attribute + start) == '+') { isValid = false; return 0; } return charactersToFloat(attribute + start, lengthExcludingDescriptor, &isValid); }
// See the specifications for more details about the algorithm to follow. // http://www.w3.org/TR/2013/WD-html-srcset-20130228/#processing-the-image-candidates. static void parseImagesWithScaleFromSrcsetAttribute(const String& srcsetAttribute, ImageCandidates& imageCandidates) { ASSERT(imageCandidates.isEmpty()); size_t imageCandidateStart = 0; unsigned srcsetAttributeLength = srcsetAttribute.length(); while (imageCandidateStart < srcsetAttributeLength) { float imageScaleFactor = 1; size_t separator; // 4. Splitting loop: Skip whitespace. size_t imageURLStart = srcsetAttribute.find(isNotHTMLSpace, imageCandidateStart); if (imageURLStart == notFound) break; // If The current candidate is either totally empty or only contains space, skipping. if (srcsetAttribute[imageURLStart] == ',') { imageCandidateStart = imageURLStart + 1; continue; } // 5. Collect a sequence of characters that are not space characters, and let that be url. size_t imageURLEnd = srcsetAttribute.find(isHTMLSpace, imageURLStart + 1); if (imageURLEnd == notFound) { imageURLEnd = srcsetAttributeLength; separator = srcsetAttributeLength; } else if (srcsetAttribute[imageURLEnd - 1] == ',') { --imageURLEnd; separator = imageURLEnd; } else { // 7. Collect a sequence of characters that are not "," (U+002C) characters, and let that be descriptors. size_t imageScaleStart = srcsetAttribute.find(isNotHTMLSpace, imageURLEnd + 1); if (imageScaleStart == notFound) separator = srcsetAttributeLength; else if (srcsetAttribute[imageScaleStart] == ',') separator = imageScaleStart; else { // This part differs from the spec as the current implementation only supports pixel density descriptors for now. size_t imageScaleEnd = srcsetAttribute.find(isHTMLSpaceOrComma, imageScaleStart + 1); imageScaleEnd = (imageScaleEnd == notFound) ? srcsetAttributeLength : imageScaleEnd; size_t commaPosition = imageScaleEnd; // Make sure there are no other descriptors. while ((commaPosition < srcsetAttributeLength - 1) && isHTMLSpace(srcsetAttribute[commaPosition])) ++commaPosition; // If the first not html space character after the scale modifier is not a comma, // the current candidate is an invalid input. if ((commaPosition < srcsetAttributeLength - 1) && srcsetAttribute[commaPosition] != ',') { // Find the nearest comma and skip the input. commaPosition = srcsetAttribute.find(',', commaPosition + 1); if (commaPosition == notFound) break; imageCandidateStart = commaPosition + 1; continue; } separator = commaPosition; if (srcsetAttribute[imageScaleEnd - 1] != 'x') { imageCandidateStart = separator + 1; continue; } bool validScaleFactor = false; size_t scaleFactorLengthWithoutUnit = imageScaleEnd - imageScaleStart - 1; imageScaleFactor = charactersToFloat(srcsetAttribute.characters() + imageScaleStart, scaleFactorLengthWithoutUnit, &validScaleFactor); if (!validScaleFactor) { imageCandidateStart = separator + 1; continue; } } } ImageWithScale image; image.imageURL = String(srcsetAttribute.characters() + imageURLStart, imageURLEnd - imageURLStart); image.scaleFactor = imageScaleFactor; imageCandidates.append(image); // 11. Return to the step labeled splitting loop. imageCandidateStart = separator + 1; } }
float toFloat(const CharType* attribute, bool& isValid) { return charactersToFloat(attribute + start, length - 1, &isValid); }
float StringImpl::toFloat(bool* ok) { return charactersToFloat(m_data, m_length, ok); }