Bug 109947

Summary: Add CString operators for comparison with const char*
Product: WebKit Reporter: Chris Dumez <cdumez>
Component: Web Template FrameworkAssignee: Chris Dumez <cdumez>
Status: RESOLVED FIXED    
Severity: Normal CC: andersca, ap, benjamin, cmarcelo, laszlo.gombos, ojan.autocc, roger_fong, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
darin: review+, darin: commit-queue-
Patch for landing none

Description Chris Dumez 2013-02-15 08:23:23 PST
CString currently has the following comparison operators:
bool operator==(const CString& a, const CString& b);
inline bool operator!=(const CString& a, const CString& b);

This means that if the caller does:
CString testString = "a";
if (testString == "a")
  // ...

It will construct a CString from the const char*, which involves a copy and a call to strlen(). I have seen such CString / const char* comparison done in WebKit.

We could add the following comparison operators to CString in order to make sure such comparison code is not expensive:
bool operator==(const CString& a, const char* b);
inline bool operator!=(const CString& a, const char* b);
Comment 1 Chris Dumez 2013-02-15 08:31:24 PST
Created attachment 188579 [details]
Patch
Comment 2 Darin Adler 2013-02-15 09:42:27 PST
Comment on attachment 188579 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=188579&action=review

Seems OK. Please fix the memcmp issue too if you are touching this code.

> Source/WTF/wtf/text/CString.cpp:113
> +    return !strncmp(a.data(), b.data(), a.length());

This code should use memcmp. We don’t want the code to scan for null characters, so strncmp is the wrong function.
Comment 3 Benjamin Poulain 2013-02-15 10:26:02 PST
Comment on attachment 188579 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=188579&action=review

This is great. Some comment bellow:

>> Source/WTF/wtf/text/CString.cpp:113
>> +    return !strncmp(a.data(), b.data(), a.length());
> 
> This code should use memcmp. We don’t want the code to scan for null characters, so strncmp is the wrong function.

Or StringImpl's equal(LChar, LChar, size_t).

> Source/WTF/wtf/text/CString.cpp:116
> +bool operator==(const CString& a, const char* b)

Would it be useful to have a version for literal?:
template<size_t bLength>
bool operator==(const CString& a, const char (&b)[bLength])

You could have compile assertions for bLength > 0, remove both branches, and go straight to memcmp/equal.

> Tools/TestWebKitAPI/Tests/WTF/CString.cpp:135
> +    CString c;
> +    const char* d = 0;
> +    ASSERT_TRUE(c == d);
> +    ASSERT_FALSE(c != d);

Another interesting boundary is empty string.
Comment 4 Chris Dumez 2013-02-15 10:35:15 PST
(In reply to comment #3)
> (From update of attachment 188579 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=188579&action=review
> 
> This is great. Some comment bellow:
> 
> >> Source/WTF/wtf/text/CString.cpp:113
> >> +    return !strncmp(a.data(), b.data(), a.length());
> > 
> > This code should use memcmp. We don’t want the code to scan for null characters, so strncmp is the wrong function.
> 
> Or StringImpl's equal(LChar, LChar, size_t).
> 
> > Source/WTF/wtf/text/CString.cpp:116
> > +bool operator==(const CString& a, const char* b)
> 
> Would it be useful to have a version for literal?:
> template<size_t bLength>
> bool operator==(const CString& a, const char (&b)[bLength])
> 
> You could have compile assertions for bLength > 0, remove both branches, and go straight to memcmp/equal.

Would you like me to add it in the same patch?

> 
> > Tools/TestWebKitAPI/Tests/WTF/CString.cpp:135
> > +    CString c;
> > +    const char* d = 0;
> > +    ASSERT_TRUE(c == d);
> > +    ASSERT_FALSE(c != d);
> 
> Another interesting boundary is empty string.

Right, I forgot about this case. I'll improve the test case, thanks.
Comment 5 Alexey Proskuryakov 2013-02-15 10:38:18 PST
What code needs to compare CString to a literal?

I think of CString as a temporary object for platform interfaces, not something that should be used in places that have logic.
Comment 6 Benjamin Poulain 2013-02-15 10:48:50 PST
(In reply to comment #5)
> What code needs to compare CString to a literal?

EFL uses CString quite a bit, which is why I ask.
Comment 7 Chris Dumez 2013-02-15 10:52:48 PST
I don't know that the literal version would be useful yet. However, I have seen code in the soup backend comparing CString to const char* values returned by libsoup.

Can I keep the patch as it is then and simply improve the test case as suggested by Benjamin?
Comment 8 Benjamin Poulain 2013-02-15 10:56:33 PST
(In reply to comment #7)
> Can I keep the patch as it is then and simply improve the test case as suggested by Benjamin?

Yep + the comments of Darin. :)
Comment 9 Chris Dumez 2013-02-15 10:57:06 PST
(In reply to comment #8)
> (In reply to comment #7)
> > Can I keep the patch as it is then and simply improve the test case as suggested by Benjamin?
> 
> Yep + the comments of Darin. :)

Of course :)
Comment 10 Chris Dumez 2013-02-15 11:33:56 PST
Created attachment 188608 [details]
Patch for landing

Could someone please take a quick look before landing?
Comment 11 Benjamin Poulain 2013-02-15 13:17:53 PST
Comment on attachment 188608 [details]
Patch for landing

Thank you for updating the test.
Comment 12 WebKit Review Bot 2013-02-15 13:54:46 PST
Comment on attachment 188608 [details]
Patch for landing

Clearing flags on attachment: 188608

Committed r143049: <http://trac.webkit.org/changeset/143049>
Comment 13 WebKit Review Bot 2013-02-15 13:54:51 PST
All reviewed patches have been landed.  Closing bug.
Comment 14 Roger Fong 2013-02-15 18:47:17 PST
This broke the Windows build.
Here's the output:
http://build-safari.apple.com/builders/Windows%20Release%20Archive/builds/19153/steps/build%20archive/logs/build%20log

Win EWS bots are really far behind :( ... might be why they bubble doesn't show up.
Comment 15 Benjamin Poulain 2013-02-15 19:16:53 PST
(In reply to comment #14)
> This broke the Windows build.
> Here's the output:
> http://build-safari.apple.com/builders/Windows%20Release%20Archive/builds/19153/steps/build%20archive/logs/build%20log
> 
> Win EWS bots are really far behind :( ... might be why they bubble doesn't show up.

It cannot find the symbol for the new operator==. Is it because of WTF_EXPORT_PRIVATE?
I forgot the difference between WTF_EXPORT_STRING_API, WTF_EXPORT_PRIVATE and WTF_EXPORT
Comment 16 Chris Dumez 2013-02-15 23:56:52 PST
(In reply to comment #15)
> (In reply to comment #14)
> > This broke the Windows build.
> > Here's the output:
> > http://build-safari.apple.com/builders/Windows%20Release%20Archive/builds/19153/steps/build%20archive/logs/build%20log
> > 
> > Win EWS bots are really far behind :( ... might be why they bubble doesn't show up.
> 
> It cannot find the symbol for the new operator==. Is it because of WTF_EXPORT_PRIVATE?
> I forgot the difference between WTF_EXPORT_STRING_API, WTF_EXPORT_PRIVATE and WTF_EXPORT

Sorry about that. According to http://trac.webkit.org/wiki/ExportingSymbols, we need to add the new symbol to JavaScriptCoreExports.def in addition to using WTF_EXPORT_PRIVATE.

However, it seems build.webkit.org and your link are both inaccessible at the moment :/
Comment 17 Chris Dumez 2013-02-16 00:53:20 PST
Windows build fix landed in http://trac.webkit.org/changeset/143099.