Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> | 2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> |
| 3 * Copyright (C) 2006, 2009 Apple Inc. | 3 * Copyright (C) 2006, 2009 Apple Inc. |
| 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "core/XMLNames.h" | 30 #include "core/XMLNames.h" |
| 31 #include "core/dom/Attr.h" | 31 #include "core/dom/Attr.h" |
| 32 #include "core/dom/Element.h" | 32 #include "core/dom/Element.h" |
| 33 #include "core/dom/ProcessingInstruction.h" | 33 #include "core/dom/ProcessingInstruction.h" |
| 34 #include "core/dom/TreeScope.h" | 34 #include "core/dom/TreeScope.h" |
| 35 #include "core/xml/XPathUtil.h" | 35 #include "core/xml/XPathUtil.h" |
| 36 #include "core/xml/XPathValue.h" | 36 #include "core/xml/XPathValue.h" |
| 37 #include "wtf/MathExtras.h" | 37 #include "wtf/MathExtras.h" |
| 38 #include "wtf/text/StringBuilder.h" | 38 #include "wtf/text/StringBuilder.h" |
| 39 | 39 |
| 40 #include <algorithm> | |
| 41 #include <limits> | |
| 42 | |
| 40 namespace blink { | 43 namespace blink { |
| 41 namespace XPath { | 44 namespace XPath { |
| 42 | 45 |
| 43 static inline bool isWhitespace(UChar c) { | 46 static inline bool isWhitespace(UChar c) { |
| 44 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; | 47 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; |
| 45 } | 48 } |
| 46 | 49 |
| 47 #define DEFINE_FUNCTION_CREATOR(Class) \ | 50 #define DEFINE_FUNCTION_CREATOR(Class) \ |
| 48 static Function* create##Class() { return new Class; } | 51 static Function* create##Class() { return new Class; } |
| 49 | 52 |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 String s1 = arg(0)->evaluate(context).toString(); | 526 String s1 = arg(0)->evaluate(context).toString(); |
| 524 String s2 = arg(1)->evaluate(context).toString(); | 527 String s2 = arg(1)->evaluate(context).toString(); |
| 525 | 528 |
| 526 size_t i = s1.find(s2); | 529 size_t i = s1.find(s2); |
| 527 if (i == kNotFound) | 530 if (i == kNotFound) |
| 528 return ""; | 531 return ""; |
| 529 | 532 |
| 530 return s1.substring(i + s2.length()); | 533 return s1.substring(i + s2.length()); |
| 531 } | 534 } |
| 532 | 535 |
| 536 // Returns |value| clipped to the range [lo, hi]. | |
| 537 static double clip(const double& lo, const double& value, const double& hi) { | |
|
yosin_UTC9
2016/10/24 05:45:36
It is better to use |double| instead of |const dou
yosin_UTC9
2016/10/24 06:07:42
Oops, there is |std::clamp(v, lo, hi)|; all parame
yosin_UTC9
2016/10/24 06:08:31
Sorry for confusion. |std::clamp()| is available f
| |
| 538 return std::min(hi, std::max(lo, value)); | |
| 539 } | |
| 540 | |
| 541 // Computes the 1-based start and end (exclusive) string indices for | |
| 542 // substring. This is all the positions [1, maxLen (inclusive)] where | |
| 543 // start <= position < start + len | |
| 544 static std::pair<unsigned, unsigned> findSubstringStartEnd(double start, | |
|
yosin_UTC9
2016/10/24 05:45:36
|computeSubstringStartEnd()|? as comment says?
| |
| 545 double len, | |
| 546 double maxLen) { | |
| 547 DCHECK(std::isfinite(maxLen)); | |
| 548 double end = start + len; | |
| 549 if (std::isnan(start) || std::isnan(end)) | |
| 550 return std::make_pair(1, 1); | |
| 551 // Neither start nor end are NaN, but may still be +/- Inf | |
| 552 start = clip(1., start, maxLen + 1); | |
|
yosin_UTC9
2016/10/24 05:45:36
nit: s/1./1.0/ to avoid sequential punctuation.
| |
| 553 end = clip(start, end, maxLen + 1); | |
|
yosin_UTC9
2016/10/24 05:45:36
Better to use another variable rather than changin
| |
| 554 return std::make_pair(static_cast<unsigned>(start), | |
| 555 static_cast<unsigned>(end)); | |
| 556 } | |
| 557 | |
| 558 // substring(string, number pos, number? len) | |
| 559 // | |
| 560 // Characters in string are indexed from 1. Numbers are doubles and | |
| 561 // substring is specified to work with IEEE-754 infinity, NaN, and | |
| 562 // XPath's bespoke rounding function, round. | |
| 563 // | |
| 564 // <https://www.w3.org/TR/xpath/#function-substring> | |
| 533 Value FunSubstring::evaluate(EvaluationContext& context) const { | 565 Value FunSubstring::evaluate(EvaluationContext& context) const { |
| 534 String s = arg(0)->evaluate(context).toString(); | 566 String sourceString = arg(0)->evaluate(context).toString(); |
| 535 double doublePos = arg(1)->evaluate(context).toNumber(); | 567 double pos = FunRound::round(arg(1)->evaluate(context).toNumber()); |
|
yosin_UTC9
2016/10/24 05:45:36
nit: s/double/const double/
| |
| 536 if (std::isnan(doublePos)) | 568 double len = argCount() == 3 |
|
yosin_UTC9
2016/10/24 05:45:36
nit: s/double/const double/
| |
| 569 ? FunRound::round(arg(2)->evaluate(context).toNumber()) | |
| 570 : std::numeric_limits<double>::infinity(); | |
| 571 auto bounds = findSubstringStartEnd(pos, len, sourceString.length()); | |
|
yosin_UTC9
2016/10/24 05:45:36
nit: s/auto/const auto/
| |
| 572 if (bounds.second <= bounds.first) | |
| 537 return ""; | 573 return ""; |
| 538 long pos = static_cast<long>(FunRound::round(doublePos)); | 574 return sourceString.substring(bounds.first - 1, bounds.second - bounds.first); |
| 539 bool haveLength = argCount() == 3; | |
| 540 long len = -1; | |
| 541 if (haveLength) { | |
| 542 double doubleLen = arg(2)->evaluate(context).toNumber(); | |
| 543 if (std::isnan(doubleLen)) | |
| 544 return ""; | |
| 545 len = static_cast<long>(FunRound::round(doubleLen)); | |
| 546 } | |
| 547 | |
| 548 if (pos > long(s.length())) | |
| 549 return ""; | |
| 550 | |
| 551 if (pos < 1) { | |
| 552 if (haveLength) { | |
| 553 len -= 1 - pos; | |
| 554 if (len < 1) | |
| 555 return ""; | |
| 556 } | |
| 557 pos = 1; | |
| 558 } | |
| 559 | |
| 560 return s.substring(pos - 1, len); | |
| 561 } | 575 } |
| 562 | 576 |
| 563 Value FunStringLength::evaluate(EvaluationContext& context) const { | 577 Value FunStringLength::evaluate(EvaluationContext& context) const { |
| 564 if (!argCount()) | 578 if (!argCount()) |
| 565 return Value(context.node.get()).toString().length(); | 579 return Value(context.node.get()).toString().length(); |
| 566 return arg(0)->evaluate(context).toString().length(); | 580 return arg(0)->evaluate(context).toString().length(); |
| 567 } | 581 } |
| 568 | 582 |
| 569 Value FunNormalizeSpace::evaluate(EvaluationContext& context) const { | 583 Value FunNormalizeSpace::evaluate(EvaluationContext& context) const { |
| 570 if (!argCount()) { | 584 if (!argCount()) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 return nullptr; | 764 return nullptr; |
| 751 | 765 |
| 752 Function* function = functionRec->factoryFn(); | 766 Function* function = functionRec->factoryFn(); |
| 753 function->setArguments(args); | 767 function->setArguments(args); |
| 754 function->setName(name); | 768 function->setName(name); |
| 755 return function; | 769 return function; |
| 756 } | 770 } |
| 757 | 771 |
| 758 } // namespace XPath | 772 } // namespace XPath |
| 759 } // namespace blink | 773 } // namespace blink |
| OLD | NEW |