<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[163792] trunk/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/163792">163792</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2014-02-10 09:46:33 -0800 (Mon, 10 Feb 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Stop using String::deprecatedCharacters to call WTF::Collator
https://bugs.webkit.org/show_bug.cgi?id=128517
Source/JavaScriptCore:
Reviewed by Alexey Proskuryakov.
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncLocaleCompare): Use the default constructor for Collator, which now
gives the default locale collation rules. Use the new arguments for Collator::collate, which
are now StringView. These two changes together eliminate the need for a separate helper function.
Source/WebCore:
Reviewed by Alexey Proskuryakov.
* xml/XSLTUnicodeSort.cpp:
(WebCore::xsltUnicodeSortFunction): Create the collator in a single line using the
new constructor that takes a shouldSortLowercaseFirst boolean. Use the new
collateUTF8 function instead of upconverting UTF-8 strings to UTF-16 as the old code did.
Source/WTF:
WTF passes ICU’s deprecated ULOC_REQUESTED_LOCALE to ucol_getLocaleByType()
rdar://problem/15183390
Reviewed by Alexey Proskuryakov.
This patch fixes both bugs above by reworking WTF::Collator.
* wtf/unicode/Collator.h: Fixed formatting. Got rid of the Collator::Result type,
since the collator uses the same return value scheme as strcmp and as ICU; an int
will do for the return type. Simplified the support for UCONFIG_NO_COLLATION by
using a separate copy of the class definition. (We should check if anyone needs
UCONFIG_NO_COLLATION support, and remove it if not.) Changed the lower-first flag
from a separate function to a constructor argument. Changed the arguments to
the collate function to StringView. Added a collate UTF8 function. Changed the
m_collate data member to no longer be mutable since we no longer allocate it lazily.
* wtf/unicode/CollatorDefault.cpp:
(WTF::Collator::collate): Rewrote to be simpler.
(WTF::Collator::collateUTF8): Added. Converts from UTF-8 to a String and then calls
the collate function above.
* wtf/unicode/icu/CollatorICU.cpp: Added a FIXME about the fact that this file
has the wrong name and location. Since we always use ICU, there's no need to mention
it in the file name.
(WTF::copyASCIIString): Added.
(WTF::copyDefaultLocale): Added.
(WTF::resolveDefaultLocale): Added. Maps null locale to a default on Mac and iOS,
since on those platforms ICU does not use the correct default locale when passed null.
(WTF::localesMatch): Added.
(WTF::Collator::Collator): Moved most of the code from createCollator here.
Simplified it by storing the collator configuration along with the collator in globals.
(WTF::Collator::~Collator): Moved most of the code from releaseCollator here.
(WTF::getIndexLatin1): Added.
(WTF::moveLatin1): Added.
(WTF::hasNextLatin1): Added.
(WTF::hasPreviousLatin1): Added.
(WTF::currentLatin1): Added.
(WTF::nextLatin1): Added.
(WTF::previousLatin1): Added.
(WTF::getStateLatin1): Added.
(WTF::setStateLatin1): Added.
(WTF::createLatin1Iterator): Added. Uses the functions above to make a UCharIterator
that works for a WTF::StringView-style Latin-1 string.
(WTF::createIterator): Added. Uses either createLatin1Iterator or uiter_setString to
make a UCharIterator that works for a WTF::StringView.
(WTF::Collator::collate): Changed to use ucol_strcollIter.
(WTF::createIteratorUTF8): Added. Uses uiter_setUTF8.
(WTF::Collator::collateUTF8): Added. Like collate, but for null-terminated UTF-8 strings.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStringPrototypecpp">trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfunicodeCollatorh">trunk/Source/WTF/wtf/unicode/Collator.h</a></li>
<li><a href="#trunkSourceWTFwtfunicodeCollatorDefaultcpp">trunk/Source/WTF/wtf/unicode/CollatorDefault.cpp</a></li>
<li><a href="#trunkSourceWTFwtfunicodeicuCollatorICUcpp">trunk/Source/WTF/wtf/unicode/icu/CollatorICU.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorexmlXSLTUnicodeSortcpp">trunk/Source/WebCore/xml/XSLTUnicodeSort.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-02-10 Darin Adler <darin@apple.com>
+
+ Stop using String::deprecatedCharacters to call WTF::Collator
+ https://bugs.webkit.org/show_bug.cgi?id=128517
+
+ Reviewed by Alexey Proskuryakov.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncLocaleCompare): Use the default constructor for Collator, which now
+ gives the default locale collation rules. Use the new arguments for Collator::collate, which
+ are now StringView. These two changes together eliminate the need for a separate helper function.
+
</ins><span class="cx"> 2014-02-10 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> <1/100 probability FTL failure: v8-v6/v8-deltablue.js.ftl-eager: Exception: TypeError: undefined is not an object (evaluating 'c.isInput')
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include "RegExpObject.h"
</span><span class="cx"> #include <wtf/ASCIICType.h>
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><ins>+#include <wtf/text/StringView.h>
</ins><span class="cx"> #include <wtf/unicode/Collator.h>
</span><span class="cx">
</span><span class="cx"> using namespace WTF;
</span><span class="lines">@@ -231,13 +232,7 @@
</span><span class="cx"> return replacement;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static inline int localeCompare(const String& a, const String& b)
-{
- return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.deprecatedCharacters()), a.length(), reinterpret_cast<const ::UChar*>(b.deprecatedCharacters()), b.length());
-}
-
</del><span class="cx"> struct StringRange {
</span><del>-public:
</del><span class="cx"> StringRange(int pos, int len)
</span><span class="cx"> : position(pos)
</span><span class="cx"> , length(len)
</span><span class="lines">@@ -1295,7 +1290,7 @@
</span><span class="cx"> String s = thisValue.toString(exec)->value(exec);
</span><span class="cx">
</span><span class="cx"> JSValue a0 = exec->argument(0);
</span><del>- return JSValue::encode(jsNumber(localeCompare(s, a0.toString(exec)->value(exec))));
</del><ins>+ return JSValue::encode(jsNumber(Collator().collate(s, a0.toString(exec)->value(exec))));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WTF/ChangeLog        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2014-02-10 Darin Adler <darin@apple.com>
+
+ Stop using String::deprecatedCharacters to call WTF::Collator
+ https://bugs.webkit.org/show_bug.cgi?id=128517
+
+ WTF passes ICU’s deprecated ULOC_REQUESTED_LOCALE to ucol_getLocaleByType()
+ rdar://problem/15183390
+
+ Reviewed by Alexey Proskuryakov.
+
+ This patch fixes both bugs above by reworking WTF::Collator.
+
+ * wtf/unicode/Collator.h: Fixed formatting. Got rid of the Collator::Result type,
+ since the collator uses the same return value scheme as strcmp and as ICU; an int
+ will do for the return type. Simplified the support for UCONFIG_NO_COLLATION by
+ using a separate copy of the class definition. (We should check if anyone needs
+ UCONFIG_NO_COLLATION support, and remove it if not.) Changed the lower-first flag
+ from a separate function to a constructor argument. Changed the arguments to
+ the collate function to StringView. Added a collate UTF8 function. Changed the
+ m_collate data member to no longer be mutable since we no longer allocate it lazily.
+
+ * wtf/unicode/CollatorDefault.cpp:
+ (WTF::Collator::collate): Rewrote to be simpler.
+ (WTF::Collator::collateUTF8): Added. Converts from UTF-8 to a String and then calls
+ the collate function above.
+
+ * wtf/unicode/icu/CollatorICU.cpp: Added a FIXME about the fact that this file
+ has the wrong name and location. Since we always use ICU, there's no need to mention
+ it in the file name.
+ (WTF::copyASCIIString): Added.
+ (WTF::copyDefaultLocale): Added.
+ (WTF::resolveDefaultLocale): Added. Maps null locale to a default on Mac and iOS,
+ since on those platforms ICU does not use the correct default locale when passed null.
+ (WTF::localesMatch): Added.
+ (WTF::Collator::Collator): Moved most of the code from createCollator here.
+ Simplified it by storing the collator configuration along with the collator in globals.
+ (WTF::Collator::~Collator): Moved most of the code from releaseCollator here.
+ (WTF::getIndexLatin1): Added.
+ (WTF::moveLatin1): Added.
+ (WTF::hasNextLatin1): Added.
+ (WTF::hasPreviousLatin1): Added.
+ (WTF::currentLatin1): Added.
+ (WTF::nextLatin1): Added.
+ (WTF::previousLatin1): Added.
+ (WTF::getStateLatin1): Added.
+ (WTF::setStateLatin1): Added.
+ (WTF::createLatin1Iterator): Added. Uses the functions above to make a UCharIterator
+ that works for a WTF::StringView-style Latin-1 string.
+ (WTF::createIterator): Added. Uses either createLatin1Iterator or uiter_setString to
+ make a UCharIterator that works for a WTF::StringView.
+ (WTF::Collator::collate): Changed to use ucol_strcollIter.
+ (WTF::createIteratorUTF8): Added. Uses uiter_setUTF8.
+ (WTF::Collator::collateUTF8): Added. Like collate, but for null-terminated UTF-8 strings.
+
</ins><span class="cx"> 2014-02-10 Tamas Gergely <tgergely.u-szeged@partner.samsung.com>
</span><span class="cx">
</span><span class="cx"> Code cleanup: Remove BUILDING_ON / TARGETING definitions.
</span></span></pre></div>
<a id="trunkSourceWTFwtfunicodeCollatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/unicode/Collator.h (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/unicode/Collator.h        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WTF/wtf/unicode/Collator.h        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -30,36 +30,45 @@
</span><span class="cx"> #define WTF_Collator_h
</span><span class="cx">
</span><span class="cx"> #include <unicode/uconfig.h>
</span><del>-#include <unicode/utypes.h>
</del><span class="cx"> #include <wtf/Noncopyable.h>
</span><del>-#include <wtf/OwnPtr.h>
</del><span class="cx">
</span><span class="cx"> struct UCollator;
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><del>- class Collator {
- WTF_MAKE_NONCOPYABLE(Collator); WTF_MAKE_FAST_ALLOCATED;
- public:
- enum Result { Equal = 0, Greater = 1, Less = -1 };
</del><ins>+class StringView;
</ins><span class="cx">
</span><del>- WTF_EXPORT_PRIVATE Collator(const char* locale); // Parsing is lenient; e.g. language identifiers (such as "en-US") are accepted, too.
- WTF_EXPORT_PRIVATE ~Collator();
- WTF_EXPORT_PRIVATE void setOrderLowerFirst(bool);
</del><ins>+#if UCONFIG_NO_COLLATION
</ins><span class="cx">
</span><del>- WTF_EXPORT_PRIVATE static std::unique_ptr<Collator> userDefault();
</del><ins>+class Collator {
+public:
+ explicit Collator(const char* = nullptr, bool = false) { }
</ins><span class="cx">
</span><del>- WTF_EXPORT_PRIVATE Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const;
</del><ins>+ WTF_EXPORT_PRIVATE static int collate(StringView, StringView);
+ WTF_EXPORT_PRIVATE static int collateUTF8(const char*, const char*);
+};
</ins><span class="cx">
</span><del>- private:
-#if !UCONFIG_NO_COLLATION
- void createCollator() const;
- void releaseCollator();
- mutable UCollator* m_collator;
</del><ins>+#else
+
+class Collator {
+ WTF_MAKE_NONCOPYABLE(Collator);
+public:
+ // The value nullptr is a special one meaning the system default locale.
+ // Locale name parsing is lenient; e.g. language identifiers (such as "en-US") are accepted, too.
+ WTF_EXPORT_PRIVATE explicit Collator(const char* locale = nullptr, bool shouldSortLowercaseFirst = false);
+ WTF_EXPORT_PRIVATE ~Collator();
+
+ WTF_EXPORT_PRIVATE int collate(StringView, StringView) const;
+ WTF_EXPORT_PRIVATE int collateUTF8(const char*, const char*) const;
+
+private:
+ char* m_locale;
+ bool m_shouldSortLowercaseFirst;
+ UCollator* m_collator;
+};
+
</ins><span class="cx"> #endif
</span><del>- char* m_locale;
- bool m_lowerFirst;
- };
</del><ins>+
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> using WTF::Collator;
</span></span></pre></div>
<a id="trunkSourceWTFwtfunicodeCollatorDefaultcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/unicode/CollatorDefault.cpp (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/unicode/CollatorDefault.cpp        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WTF/wtf/unicode/CollatorDefault.cpp        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,43 +33,29 @@
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><del>-Collator::Collator(const char*)
</del><ins>+int Collator::collate(StringView a, StringView b) const
</ins><span class="cx"> {
</span><del>-}
</del><ins>+ unsigned commonLength = std::min(a.length(), b.length());
+ for (unsigned i = 0; i < commonLength; ++i) {
+ if (a[i] < b[i])
+ return -1;
+ if (a[i] > b[i])
+ return 1;
+ }
</ins><span class="cx">
</span><del>-Collator::~Collator()
-{
-}
</del><ins>+ if (a.length() < b.length())
+ return -1;
+ if (a.length() > b.length())
+ return 1;
</ins><span class="cx">
</span><del>-void Collator::setOrderLowerFirst(bool)
-{
</del><ins>+ return 0;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-std::unique_ptr<Collator> Collator::userDefault()
</del><ins>+int Collator::collateUTF8(const char* a, const char* b) const
</ins><span class="cx"> {
</span><del>- return std::make_unique<Collator>(nullptr);
</del><ins>+ return collate(String::fromUTF8(a), String::fromUTF8(b));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-// A default implementation for platforms that lack Unicode-aware collation.
-Collator::Result Collator::collate(const UChar* lhs, size_t lhsLength, const UChar* rhs, size_t rhsLength) const
-{
- int lmin = lhsLength < rhsLength ? lhsLength : rhsLength;
- int l = 0;
- while (l < lmin && *lhs == *rhs) {
- lhs++;
- rhs++;
- l++;
- }
-
- if (l < lmin)
- return (*lhs > *rhs) ? Greater : Less;
-
- if (lhsLength == rhsLength)
- return Equal;
-
- return (lhsLength > rhsLength) ? Greater : Less;
</del><span class="cx"> }
</span><span class="cx">
</span><del>-}
-
</del><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWTFwtfunicodeicuCollatorICUcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/unicode/icu/CollatorICU.cpp (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/unicode/icu/CollatorICU.cpp        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WTF/wtf/unicode/icu/CollatorICU.cpp        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,22 +29,25 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include <wtf/unicode/Collator.h>
</span><span class="cx">
</span><ins>+// FIXME: Merge this with CollatorDefault.cpp into a single Collator.cpp source file.
+
</ins><span class="cx"> #if !UCONFIG_NO_COLLATION
</span><span class="cx">
</span><span class="cx"> #include <mutex>
</span><del>-#include <wtf/Assertions.h>
</del><ins>+#include <unicode/ucol.h>
</ins><span class="cx"> #include <wtf/StringExtras.h>
</span><del>-#include <unicode/ucol.h>
-#include <string.h>
</del><ins>+#include <wtf/text/StringView.h>
</ins><span class="cx">
</span><del>-#if OS(DARWIN)
</del><ins>+#if OS(DARWIN) && USE(CF)
+#include <CoreFoundation/CoreFoundation.h>
</ins><span class="cx"> #include <wtf/RetainPtr.h>
</span><del>-#include <CoreFoundation/CoreFoundation.h>
</del><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><span class="cx"> static UCollator* cachedCollator;
</span><ins>+static char* cachedCollatorLocale;
+static bool cachedCollatorShouldSortLowercaseFirst;
</ins><span class="cx">
</span><span class="cx"> static std::mutex& cachedCollatorMutex()
</span><span class="cx"> {
</span><span class="lines">@@ -53,107 +56,232 @@
</span><span class="cx"> std::call_once(onceFlag, []{
</span><span class="cx"> mutex = std::make_unique<std::mutex>().release();
</span><span class="cx"> });
</span><del>-
</del><span class="cx"> return *mutex;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-Collator::Collator(const char* locale)
- : m_collator(0)
- , m_locale(locale ? strdup(locale) : 0)
- , m_lowerFirst(false)
</del><ins>+#if !(OS(DARWIN) && USE(CF))
+
+static inline const char* resolveDefaultLocale(const char* locale)
</ins><span class="cx"> {
</span><ins>+ return locale;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-std::unique_ptr<Collator> Collator::userDefault()
</del><ins>+#else
+
+static inline char* copyShortASCIIString(CFStringRef string)
</ins><span class="cx"> {
</span><del>-#if OS(DARWIN) && USE(CF)
- // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
-#if !OS(IOS)
- RetainPtr<CFLocaleRef> currentLocale = adoptCF(CFLocaleCopyCurrent());
- CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier);
-#else
- RetainPtr<CFStringRef> collationOrderRetainer = adoptCF((CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
- CFStringRef collationOrder = collationOrderRetainer.get();
-#endif
- char buf[256];
- if (!collationOrder)
- return std::make_unique<Collator>("");
- CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII);
- return std::make_unique<Collator>(buf);
-#else
- return std::make_unique<Collator>(static_cast<const char*>(0));
-#endif
</del><ins>+ // OK to have a fixed size buffer and to only handle ASCII since we only use this for locale names.
+ char buffer[256];
+ if (!CFStringGetCString(string, buffer, sizeof(buffer), kCFStringEncodingASCII))
+ return strdup("");
+ return strdup(buffer);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-Collator::~Collator()
</del><ins>+static char* copyDefaultLocale()
</ins><span class="cx"> {
</span><del>- releaseCollator();
- free(m_locale);
</del><ins>+#if !PLATFORM(IOS)
+ return copyShortASCIIString(static_cast<CFStringRef>(CFLocaleGetValue(adoptCF(CFLocaleCopyCurrent()).get(), kCFLocaleCollatorIdentifier)));
+#else
+ // FIXME: Documentation claims the code above would work on iOS 4.0 and later. After test that works, we should remove this and use that instead.
+ return copyShortASCIIString(adoptCF(static_cast<CFStringRef>(CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost))).get());
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void Collator::setOrderLowerFirst(bool lowerFirst)
</del><ins>+static inline const char* resolveDefaultLocale(const char* locale)
</ins><span class="cx"> {
</span><del>- m_lowerFirst = lowerFirst;
</del><ins>+ if (locale)
+ return locale;
+ // Since iOS and OS X don't set UNIX locale to match the user's selected locale, the ICU default locale is not the right one.
+ // So, instead of passing null to ICU, we pass the name of the user's selected locale.
+ static char* defaultLocale;
+ static std::once_flag initializeDefaultLocaleOnce;
+ std::call_once(initializeDefaultLocaleOnce, []{
+ defaultLocale = copyDefaultLocale();
+ });
+ return defaultLocale;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-Collator::Result Collator::collate(const UChar* lhs, size_t lhsLength, const UChar* rhs, size_t rhsLength) const
</del><ins>+#endif
+
+static inline bool localesMatch(const char* a, const char* b)
</ins><span class="cx"> {
</span><del>- if (!m_collator)
- createCollator();
-
- return static_cast<Result>(ucol_strcoll(m_collator, lhs, lhsLength, rhs, rhsLength));
</del><ins>+ // Two null locales are equal, other locales are compared with strcmp.
+ return a == b || (a && b && !strcmp(a, b));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void Collator::createCollator() const
</del><ins>+Collator::Collator(const char* locale, bool shouldSortLowercaseFirst)
</ins><span class="cx"> {
</span><del>- ASSERT(!m_collator);
</del><span class="cx"> UErrorCode status = U_ZERO_ERROR;
</span><span class="cx">
</span><span class="cx"> {
</span><span class="cx"> std::lock_guard<std::mutex> lock(cachedCollatorMutex());
</span><del>- if (cachedCollator) {
- const char* cachedCollatorLocale = ucol_getLocaleByType(cachedCollator, ULOC_REQUESTED_LOCALE, &status);
- ASSERT(U_SUCCESS(status));
- ASSERT(cachedCollatorLocale);
-
- UColAttributeValue cachedCollatorLowerFirst = ucol_getAttribute(cachedCollator, UCOL_CASE_FIRST, &status);
- ASSERT(U_SUCCESS(status));
-
- // FIXME: default locale is never matched, because ucol_getLocaleByType returns the actual one used, not 0.
- if (m_locale && 0 == strcmp(cachedCollatorLocale, m_locale)
- && ((UCOL_LOWER_FIRST == cachedCollatorLowerFirst && m_lowerFirst) || (UCOL_UPPER_FIRST == cachedCollatorLowerFirst && !m_lowerFirst))) {
- m_collator = cachedCollator;
- cachedCollator = nullptr;
- return;
- }
</del><ins>+ if (cachedCollator && localesMatch(cachedCollatorLocale, locale) && cachedCollatorShouldSortLowercaseFirst == shouldSortLowercaseFirst) {
+ m_collator = cachedCollator;
+ m_locale = cachedCollatorLocale;
+ m_shouldSortLowercaseFirst = shouldSortLowercaseFirst;
+ cachedCollator = nullptr;
+ cachedCollatorLocale = nullptr;
+ return;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- m_collator = ucol_open(m_locale, &status);
</del><ins>+ m_collator = ucol_open(resolveDefaultLocale(locale), &status);
</ins><span class="cx"> if (U_FAILURE(status)) {
</span><span class="cx"> status = U_ZERO_ERROR;
</span><del>- m_collator = ucol_open("", &status); // Fallback to Unicode Collation Algorithm.
</del><ins>+ m_collator = ucol_open("", &status); // Fall back to Unicode Collation Algorithm.
</ins><span class="cx"> }
</span><span class="cx"> ASSERT(U_SUCCESS(status));
</span><span class="cx">
</span><del>- ucol_setAttribute(m_collator, UCOL_CASE_FIRST, m_lowerFirst ? UCOL_LOWER_FIRST : UCOL_UPPER_FIRST, &status);
</del><ins>+ ucol_setAttribute(m_collator, UCOL_CASE_FIRST, shouldSortLowercaseFirst ? UCOL_LOWER_FIRST : UCOL_UPPER_FIRST, &status);
</ins><span class="cx"> ASSERT(U_SUCCESS(status));
</span><span class="cx">
</span><span class="cx"> ucol_setAttribute(m_collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
</span><span class="cx"> ASSERT(U_SUCCESS(status));
</span><ins>+
+ m_locale = locale ? strdup(locale) : nullptr;
+ m_shouldSortLowercaseFirst = shouldSortLowercaseFirst;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void Collator::releaseCollator()
</del><ins>+Collator::~Collator()
</ins><span class="cx"> {
</span><span class="cx"> {
</span><span class="cx"> std::lock_guard<std::mutex> lock(cachedCollatorMutex());
</span><span class="cx"> if (cachedCollator)
</span><span class="cx"> ucol_close(cachedCollator);
</span><span class="cx"> cachedCollator = m_collator;
</span><ins>+ cachedCollatorLocale = m_locale;
+ cachedCollatorShouldSortLowercaseFirst = m_shouldSortLowercaseFirst;
</ins><span class="cx"> m_collator = nullptr;
</span><ins>+ m_locale = nullptr;
</ins><span class="cx"> }
</span><ins>+
+ free(m_locale);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+static int32_t getIndexLatin1(UCharIterator* iterator, UCharIteratorOrigin origin)
+{
+ switch (origin) {
+ case UITER_START:
+ return iterator->start;
+ case UITER_CURRENT:
+ return iterator->index;
+ case UITER_LIMIT:
+ return iterator->limit;
+ case UITER_ZERO:
+ return 0;
+ case UITER_LENGTH:
+ return iterator->length;
+ }
+ ASSERT_NOT_REACHED();
+ return U_SENTINEL;
+}
+
+static int32_t moveLatin1(UCharIterator* iterator, int32_t delta, UCharIteratorOrigin origin)
+{
+ return iterator->index = getIndexLatin1(iterator, origin) + delta;
+}
+
+static UBool hasNextLatin1(UCharIterator* iterator)
+{
+ return iterator->index < iterator->limit;
+}
+
+static UBool hasPreviousLatin1(UCharIterator* iterator)
+{
+ return iterator->index > iterator->start;
+}
+
+static UChar32 currentLatin1(UCharIterator* iterator)
+{
+ ASSERT(iterator->index >= iterator->start);
+ if (iterator->index >= iterator->limit)
+ return U_SENTINEL;
+ return static_cast<const LChar*>(iterator->context)[iterator->index];
+}
+
+static UChar32 nextLatin1(UCharIterator* iterator)
+{
+ ASSERT(iterator->index >= iterator->start);
+ if (iterator->index >= iterator->limit)
+ return U_SENTINEL;
+ return static_cast<const LChar*>(iterator->context)[iterator->index++];
+}
+
+static UChar32 previousLatin1(UCharIterator* iterator)
+{
+ if (iterator->index <= iterator->start)
+ return U_SENTINEL;
+ return static_cast<const LChar*>(iterator->context)[--iterator->index];
+}
+
+static uint32_t getStateLatin1(const UCharIterator* iterator)
+{
+ return iterator->index;
+}
+
+static void setStateLatin1(UCharIterator* iterator, uint32_t state, UErrorCode*)
+{
+ iterator->index = state;
+}
+
+static UCharIterator createLatin1Iterator(const LChar* characters, int length)
+{
+ UCharIterator iterator;
+ iterator.context = characters;
+ iterator.length = length;
+ iterator.start = 0;
+ iterator.index = 0;
+ iterator.limit = length;
+ iterator.reservedField = 0;
+ iterator.getIndex = getIndexLatin1;
+ iterator.move = moveLatin1;
+ iterator.hasNext = hasNextLatin1;
+ iterator.hasPrevious = hasPreviousLatin1;
+ iterator.current = currentLatin1;
+ iterator.next = nextLatin1;
+ iterator.previous = previousLatin1;
+ iterator.reservedFn = nullptr;
+ iterator.getState = getStateLatin1;
+ iterator.setState = setStateLatin1;
+ return iterator;
+}
+
+static UCharIterator createIterator(StringView string)
+{
+ if (string.is8Bit())
+ return createLatin1Iterator(string.characters8(), string.length());
+ UCharIterator iterator;
+ uiter_setString(&iterator, string.characters16(), string.length());
+ return iterator;
+}
+
+int Collator::collate(StringView a, StringView b) const
+{
+ UCharIterator iteratorA = createIterator(a);
+ UCharIterator iteratorB = createIterator(b);
+ UErrorCode status = U_ZERO_ERROR;
+ int result = ucol_strcollIter(m_collator, &iteratorA, &iteratorB, &status);
+ ASSERT(U_SUCCESS(status));
+ return result;
+}
+
+static UCharIterator createIteratorUTF8(const char* string)
+{
+ UCharIterator iterator;
+ uiter_setUTF8(&iterator, string, strlen(string));
+ return iterator;
+}
+
+int Collator::collateUTF8(const char* a, const char* b) const
+{
+ UCharIterator iteratorA = createIteratorUTF8(a);
+ UCharIterator iteratorB = createIteratorUTF8(b);
+ UErrorCode status = U_ZERO_ERROR;
+ int result = ucol_strcollIter(m_collator, &iteratorA, &iteratorB, &status);
+ ASSERT(U_SUCCESS(status));
+ return result;
+}
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WebCore/ChangeLog        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-02-10 Darin Adler <darin@apple.com>
+
+ Stop using String::deprecatedCharacters to call WTF::Collator
+ https://bugs.webkit.org/show_bug.cgi?id=128517
+
+ Reviewed by Alexey Proskuryakov.
+
+ * xml/XSLTUnicodeSort.cpp:
+ (WebCore::xsltUnicodeSortFunction): Create the collator in a single line using the
+ new constructor that takes a shouldSortLowercaseFirst boolean. Use the new
+ collateUTF8 function instead of upconverting UTF-8 strings to UTF-16 as the old code did.
+
</ins><span class="cx"> 2014-02-10 Changhun Kang <temoochin@company100.net>
</span><span class="cx">
</span><span class="cx"> Remove unnecessary comment lines.
</span></span></pre></div>
<a id="trunkSourceWebCorexmlXSLTUnicodeSortcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/XSLTUnicodeSort.cpp (163791 => 163792)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/XSLTUnicodeSort.cpp        2014-02-10 17:37:44 UTC (rev 163791)
+++ trunk/Source/WebCore/xml/XSLTUnicodeSort.cpp        2014-02-10 17:46:33 UTC (rev 163792)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx">
</span><span class="cx"> #include <libxslt/templates.h>
</span><span class="cx"> #include <libxslt/xsltutils.h>
</span><del>-#include <wtf/text/WTFString.h>
</del><span class="cx"> #include <wtf/unicode/Collator.h>
</span><span class="cx">
</span><span class="cx"> #if OS(DARWIN) && !PLATFORM(EFL) && !PLATFORM(GTK)
</span><span class="lines">@@ -162,10 +161,9 @@
</span><span class="cx">
</span><span class="cx"> // We are passing a language identifier to a function that expects a locale identifier.
</span><span class="cx"> // The implementation of Collator should be lenient, and accept both "en-US" and "en_US", for example.
</span><del>- // This lets an author to really specify sorting rules, e.g. "de_DE@collation=phonebook", which isn't
</del><ins>+ // This lets an author specify sorting rules, e.g. "de_DE@collation=phonebook", which isn't
</ins><span class="cx"> // possible with language alone.
</span><del>- Collator collator(comp->has_lang ? (const char*)comp->lang : "en");
- collator.setOrderLowerFirst(comp->lower_first);
</del><ins>+ Collator collator(comp->has_lang ? reinterpret_cast<const char*>(comp->lang) : "en", comp->lower_first);
</ins><span class="cx">
</span><span class="cx"> /* Shell's sort of node-set */
</span><span class="cx"> for (incr = len / 2; incr > 0; incr /= 2) {
</span><span class="lines">@@ -195,11 +193,8 @@
</span><span class="cx"> results[j + incr]->floatval)
</span><span class="cx"> tst = 1;
</span><span class="cx"> else tst = -1;
</span><del>- } else {
- String str1 = String::fromUTF8((const char*)results[j]->stringval);
- String str2 = String::fromUTF8((const char*)results[j + incr]->stringval);
- tst = collator.collate(str1.deprecatedCharacters(), str1.length(), str2.deprecatedCharacters(), str2.length());
- }
</del><ins>+ } else
+ tst = collator.collateUTF8(reinterpret_cast<const char*>(results[j]->stringval), reinterpret_cast<const char*>(results[j + incr]->stringval));
</ins><span class="cx"> if (descending)
</span><span class="cx"> tst = -tst;
</span><span class="cx"> }
</span><span class="lines">@@ -250,11 +245,8 @@
</span><span class="cx"> res[j + incr]->floatval)
</span><span class="cx"> tst = 1;
</span><span class="cx"> else tst = -1;
</span><del>- } else {
- String str1 = String::fromUTF8((const char*)res[j]->stringval);
- String str2 = String::fromUTF8((const char*)res[j + incr]->stringval);
- tst = collator.collate(str1.deprecatedCharacters(), str1.length(), str2.deprecatedCharacters(), str2.length());
- }
</del><ins>+ } else
+ tst = collator.collateUTF8(reinterpret_cast<const char*>(res[j]->stringval), reinterpret_cast<const char*>(res[j + incr]->stringval));
</ins><span class="cx"> if (desc)
</span><span class="cx"> tst = -tst;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>
</body>
</html>