• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //    * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //    * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //    * Neither the name of Google Inc. nor the name Chromium Embedded
14 // Framework nor the names of its contributors may be used to endorse
15 // or promote products derived from this software without specific prior
16 // written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
31 #define CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
32 #pragma once
33 
34 #include <memory.h>
35 #include <string>
36 
37 #include "include/internal/cef_string_types.h"
38 
39 #if defined(USING_CHROMIUM_INCLUDES)
40 #include "base/files/file_path.h"
41 #endif
42 
43 ///
44 // Traits implementation for wide character strings.
45 ///
46 struct CefStringTraitsWide {
47   typedef wchar_t char_type;
48   typedef cef_string_wide_t struct_type;
49   typedef cef_string_userfree_wide_t userfree_struct_type;
50 
clearCefStringTraitsWide51   static inline void clear(struct_type* s) { cef_string_wide_clear(s); }
setCefStringTraitsWide52   static inline int set(const char_type* src,
53                         size_t src_size,
54                         struct_type* output,
55                         int copy) {
56     return cef_string_wide_set(src, src_size, output, copy);
57   }
compareCefStringTraitsWide58   static inline int compare(const struct_type* s1, const struct_type* s2) {
59     return cef_string_wide_cmp(s1, s2);
60   }
userfree_allocCefStringTraitsWide61   static inline userfree_struct_type userfree_alloc() {
62     return cef_string_userfree_wide_alloc();
63   }
userfree_freeCefStringTraitsWide64   static inline void userfree_free(userfree_struct_type ufs) {
65     return cef_string_userfree_wide_free(ufs);
66   }
67 
68   // Conversion methods.
from_asciiCefStringTraitsWide69   static inline bool from_ascii(const char* str, size_t len, struct_type* s) {
70     return cef_string_ascii_to_wide(str, len, s) ? true : false;
71   }
to_stringCefStringTraitsWide72   static inline std::string to_string(const struct_type* s) {
73     cef_string_utf8_t cstr;
74     memset(&cstr, 0, sizeof(cstr));
75     cef_string_wide_to_utf8(s->str, s->length, &cstr);
76     std::string str;
77     if (cstr.length > 0)
78       str = std::string(cstr.str, cstr.length);
79     cef_string_utf8_clear(&cstr);
80     return str;
81   }
from_stringCefStringTraitsWide82   static inline bool from_string(const std::string& str, struct_type* s) {
83     return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false;
84   }
to_wstringCefStringTraitsWide85   static inline std::wstring to_wstring(const struct_type* s) {
86     return std::wstring(s->str, s->length);
87   }
from_wstringCefStringTraitsWide88   static inline bool from_wstring(const std::wstring& str, struct_type* s) {
89     return cef_string_wide_set(str.c_str(), str.length(), s, true) ? true
90                                                                    : false;
91   }
92 #if defined(WCHAR_T_IS_UTF32)
to_string16CefStringTraitsWide93   static inline std::u16string to_string16(const struct_type* s) {
94     cef_string_utf16_t cstr;
95     memset(&cstr, 0, sizeof(cstr));
96     cef_string_wide_to_utf16(s->str, s->length, &cstr);
97     std::u16string str;
98     if (cstr.length > 0) {
99       str = std::u16string(
100           reinterpret_cast<std::u16string::value_type*>(cstr.str), cstr.length);
101     }
102     cef_string_utf16_clear(&cstr);
103     return str;
104   }
from_string16CefStringTraitsWide105   static inline bool from_string16(const std::u16string& str, struct_type* s) {
106     return cef_string_utf16_to_wide(
107                reinterpret_cast<const char16*>(str.c_str()), str.length(), s)
108                ? true
109                : false;
110   }
111 #else   // WCHAR_T_IS_UTF32
to_string16CefStringTraitsWide112   static inline std::u16string to_string16(const struct_type* s) {
113     return std::u16string(
114         reinterpret_cast<const std::u16string::value_type*>(s->str), s->length);
115   }
from_string16CefStringTraitsWide116   static inline bool from_string16(const std::u16string& str, struct_type* s) {
117     return cef_string_wide_set(reinterpret_cast<const wchar_t*>(str.c_str()),
118                                str.length(), s, true)
119                ? true
120                : false;
121   }
122 #endif  // WCHAR_T_IS_UTF32
123 };
124 
125 ///
126 // Traits implementation for utf8 character strings.
127 ///
128 struct CefStringTraitsUTF8 {
129   typedef char char_type;
130   typedef cef_string_utf8_t struct_type;
131   typedef cef_string_userfree_utf8_t userfree_struct_type;
132 
clearCefStringTraitsUTF8133   static inline void clear(struct_type* s) { cef_string_utf8_clear(s); }
setCefStringTraitsUTF8134   static inline int set(const char_type* src,
135                         size_t src_size,
136                         struct_type* output,
137                         int copy) {
138     return cef_string_utf8_set(src, src_size, output, copy);
139   }
compareCefStringTraitsUTF8140   static inline int compare(const struct_type* s1, const struct_type* s2) {
141     return cef_string_utf8_cmp(s1, s2);
142   }
userfree_allocCefStringTraitsUTF8143   static inline userfree_struct_type userfree_alloc() {
144     return cef_string_userfree_utf8_alloc();
145   }
userfree_freeCefStringTraitsUTF8146   static inline void userfree_free(userfree_struct_type ufs) {
147     return cef_string_userfree_utf8_free(ufs);
148   }
149 
150   // Conversion methods.
from_asciiCefStringTraitsUTF8151   static inline bool from_ascii(const char* str, size_t len, struct_type* s) {
152     return cef_string_utf8_copy(str, len, s) ? true : false;
153   }
to_stringCefStringTraitsUTF8154   static inline std::string to_string(const struct_type* s) {
155     return std::string(s->str, s->length);
156   }
from_stringCefStringTraitsUTF8157   static inline bool from_string(const std::string& str, struct_type* s) {
158     return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false;
159   }
to_wstringCefStringTraitsUTF8160   static inline std::wstring to_wstring(const struct_type* s) {
161     cef_string_wide_t cstr;
162     memset(&cstr, 0, sizeof(cstr));
163     cef_string_utf8_to_wide(s->str, s->length, &cstr);
164     std::wstring str;
165     if (cstr.length > 0)
166       str = std::wstring(cstr.str, cstr.length);
167     cef_string_wide_clear(&cstr);
168     return str;
169   }
from_wstringCefStringTraitsUTF8170   static inline bool from_wstring(const std::wstring& str, struct_type* s) {
171     return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false;
172   }
to_string16CefStringTraitsUTF8173   static inline std::u16string to_string16(const struct_type* s) {
174     cef_string_utf16_t cstr;
175     memset(&cstr, 0, sizeof(cstr));
176     cef_string_utf8_to_utf16(s->str, s->length, &cstr);
177     std::u16string str;
178     if (cstr.length > 0) {
179       str = std::u16string(
180           reinterpret_cast<std::u16string::value_type*>(cstr.str), cstr.length);
181     }
182     cef_string_utf16_clear(&cstr);
183     return str;
184   }
from_string16CefStringTraitsUTF8185   static inline bool from_string16(const std::u16string& str, struct_type* s) {
186     return cef_string_utf16_to_utf8(
187                reinterpret_cast<const char16*>(str.c_str()), str.length(), s)
188                ? true
189                : false;
190   }
191 };
192 
193 ///
194 // Traits implementation for utf16 character strings.
195 ///
196 struct CefStringTraitsUTF16 {
197   typedef char16 char_type;
198   typedef cef_string_utf16_t struct_type;
199   typedef cef_string_userfree_utf16_t userfree_struct_type;
200 
clearCefStringTraitsUTF16201   static inline void clear(struct_type* s) { cef_string_utf16_clear(s); }
setCefStringTraitsUTF16202   static inline int set(const char_type* src,
203                         size_t src_size,
204                         struct_type* output,
205                         int copy) {
206     return cef_string_utf16_set(src, src_size, output, copy);
207   }
compareCefStringTraitsUTF16208   static inline int compare(const struct_type* s1, const struct_type* s2) {
209     return cef_string_utf16_cmp(s1, s2);
210   }
userfree_allocCefStringTraitsUTF16211   static inline userfree_struct_type userfree_alloc() {
212     return cef_string_userfree_utf16_alloc();
213   }
userfree_freeCefStringTraitsUTF16214   static inline void userfree_free(userfree_struct_type ufs) {
215     return cef_string_userfree_utf16_free(ufs);
216   }
217 
218   // Conversion methods.
from_asciiCefStringTraitsUTF16219   static inline bool from_ascii(const char* str, size_t len, struct_type* s) {
220     return cef_string_ascii_to_utf16(str, len, s) ? true : false;
221   }
to_stringCefStringTraitsUTF16222   static inline std::string to_string(const struct_type* s) {
223     cef_string_utf8_t cstr;
224     memset(&cstr, 0, sizeof(cstr));
225     cef_string_utf16_to_utf8(s->str, s->length, &cstr);
226     std::string str;
227     if (cstr.length > 0)
228       str = std::string(cstr.str, cstr.length);
229     cef_string_utf8_clear(&cstr);
230     return str;
231   }
from_stringCefStringTraitsUTF16232   static inline bool from_string(const std::string& str, struct_type* s) {
233     return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ? true
234                                                                   : false;
235   }
236 #if defined(WCHAR_T_IS_UTF32)
to_wstringCefStringTraitsUTF16237   static inline std::wstring to_wstring(const struct_type* s) {
238     cef_string_wide_t cstr;
239     memset(&cstr, 0, sizeof(cstr));
240     cef_string_utf16_to_wide(s->str, s->length, &cstr);
241     std::wstring str;
242     if (cstr.length > 0)
243       str = std::wstring(cstr.str, cstr.length);
244     cef_string_wide_clear(&cstr);
245     return str;
246   }
from_wstringCefStringTraitsUTF16247   static inline bool from_wstring(const std::wstring& str, struct_type* s) {
248     return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ? true
249                                                                   : false;
250   }
251 #else   // WCHAR_T_IS_UTF32
to_wstringCefStringTraitsUTF16252   static inline std::wstring to_wstring(const struct_type* s) {
253     return std::wstring(s->str, s->length);
254   }
from_wstringCefStringTraitsUTF16255   static inline bool from_wstring(const std::wstring& str, struct_type* s) {
256     return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? true
257                                                                     : false;
258   }
259 #endif  // WCHAR_T_IS_UTF32
to_string16CefStringTraitsUTF16260   static inline std::u16string to_string16(const struct_type* s) {
261     return std::u16string(
262         reinterpret_cast<const std::u16string::value_type*>(s->str), s->length);
263   }
from_string16CefStringTraitsUTF16264   static inline bool from_string16(const std::u16string& str, struct_type* s) {
265     return cef_string_utf16_set(reinterpret_cast<const char16*>(str.c_str()),
266                                 str.length(), s, true)
267                ? true
268                : false;
269   }
270 };
271 
272 ///
273 // CEF string classes can convert between all supported string types. For
274 // example, the CefStringWide class uses wchar_t as the underlying character
275 // type and provides two approaches for converting data to/from a UTF8 string
276 // (std::string).
277 // <p>
278 // 1. Implicit conversion using the assignment operator overload.
279 // <pre>
280 //   CefStringWide aCefString;
281 //   std::string aUTF8String;
282 //   aCefString = aUTF8String; // Assign std::string to CefStringWide
283 //   aUTF8String = aCefString; // Assign CefStringWide to std::string
284 // </pre>
285 // 2. Explicit conversion using the FromString/ToString methods.
286 // <pre>
287 //   CefStringWide aCefString;
288 //   std::string aUTF8String;
289 //   aCefString.FromString(aUTF8String); // Assign std::string to CefStringWide
290 //   aUTF8String = aCefString.ToString(); // Assign CefStringWide to std::string
291 // </pre>
292 // Conversion will only occur if the assigned value is a different string type.
293 // Assigning a std::string to a CefStringUTF8, for example, will copy the data
294 // without performing a conversion.
295 // </p>
296 // CEF string classes are safe for reading from multiple threads but not for
297 // modification. It is the user's responsibility to provide synchronization if
298 // modifying CEF strings from multiple threads.
299 ///
300 template <class traits>
301 class CefStringBase {
302  public:
303   typedef typename traits::char_type char_type;
304   typedef typename traits::struct_type struct_type;
305   typedef typename traits::userfree_struct_type userfree_struct_type;
306 
307   ///
308   // Default constructor.
309   ///
CefStringBase()310   CefStringBase() : string_(NULL), owner_(false) {}
311 
312   ///
313   // Create a new string from an existing string. Data will always be copied.
314   ///
CefStringBase(const CefStringBase & str)315   CefStringBase(const CefStringBase& str) : string_(NULL), owner_(false) {
316     FromString(str.c_str(), str.length(), true);
317   }
318 
319   ///
320   // Create a new string from an existing std::string. Data will be always
321   // copied. Translation will occur if necessary based on the underlying string
322   // type.
323   ///
CefStringBase(const std::string & src)324   CefStringBase(const std::string& src) : string_(NULL), owner_(false) {
325     FromString(src);
326   }
CefStringBase(const char * src)327   CefStringBase(const char* src) : string_(NULL), owner_(false) {
328     if (src)
329       FromString(std::string(src));
330   }
331 
332   ///
333   // Create a new string from an existing std::wstring. Data will be always
334   // copied. Translation will occur if necessary based on the underlying string
335   // type.
336   ///
CefStringBase(const std::wstring & src)337   CefStringBase(const std::wstring& src) : string_(NULL), owner_(false) {
338     FromWString(src);
339   }
CefStringBase(const wchar_t * src)340   CefStringBase(const wchar_t* src) : string_(NULL), owner_(false) {
341     if (src)
342       FromWString(std::wstring(src));
343   }
344 
345   ///
346   // Create a new string from an existing string16. Data will be always
347   // copied. Translation will occur if necessary based on the underlying string
348   // type.
349   ///
CefStringBase(const std::u16string & src)350   CefStringBase(const std::u16string& src) : string_(NULL), owner_(false) {
351     FromString16(src);
352   }
CefStringBase(const std::u16string::value_type * src)353   CefStringBase(const std::u16string::value_type* src)
354       : string_(NULL), owner_(false) {
355     if (src)
356       FromString16(std::u16string(src));
357   }
358 #if defined(WCHAR_T_IS_UTF32)
CefStringBase(const char16 * src)359   CefStringBase(const char16* src) : string_(NULL), owner_(false) {
360     if (src) {
361       FromString16(std::u16string(
362           reinterpret_cast<const std::u16string::value_type*>(src)));
363     }
364   }
365 #endif  // WCHAR_T_IS_UTF32
366 
367   ///
368   // Create a new string from an existing character array. If |copy| is true
369   // this class will copy the data. Otherwise, this class will reference the
370   // existing data. Referenced data must exist for the lifetime of this class
371   // and will not be freed by this class.
372   ///
CefStringBase(const char_type * src,size_t src_len,bool copy)373   CefStringBase(const char_type* src, size_t src_len, bool copy)
374       : string_(NULL), owner_(false) {
375     if (src && src_len > 0)
376       FromString(src, src_len, copy);
377   }
378 
379   ///
380   // Create a new string referencing an existing string structure without taking
381   // ownership. Referenced structures must exist for the lifetime of this class
382   // and will not be freed by this class.
383   ///
CefStringBase(const struct_type * src)384   CefStringBase(const struct_type* src) : string_(NULL), owner_(false) {
385     if (!src)
386       return;
387     // Reference the existing structure without taking ownership.
388     Attach(const_cast<struct_type*>(src), false);
389   }
390 
~CefStringBase()391   virtual ~CefStringBase() { ClearAndFree(); }
392 
393   // The following methods are named for compatibility with the standard library
394   // string template types.
395 
396   ///
397   // Return a read-only pointer to the string data.
398   ///
c_str()399   const char_type* c_str() const { return (string_ ? string_->str : NULL); }
400 
401   ///
402   // Return the length of the string data.
403   ///
length()404   size_t length() const { return (string_ ? string_->length : 0); }
405 
406   ///
407   // Return the length of the string data.
408   ///
size()409   inline size_t size() const { return length(); }
410 
411   ///
412   // Returns true if the string is empty.
413   ///
empty()414   bool empty() const { return (string_ == NULL || string_->length == 0); }
415 
416   ///
417   // Compare this string to the specified string.
418   ///
compare(const CefStringBase & str)419   int compare(const CefStringBase& str) const {
420     if (empty() && str.empty())
421       return 0;
422     if (empty())
423       return -1;
424     if (str.empty())
425       return 1;
426     return traits::compare(string_, str.GetStruct());
427   }
428 
429   ///
430   // Clear the string data.
431   ///
clear()432   void clear() {
433     if (string_)
434       traits::clear(string_);
435   }
436 
437   ///
438   // Swap this string's contents with the specified string.
439   ///
swap(CefStringBase & str)440   void swap(CefStringBase& str) {
441     struct_type* tmp_string = string_;
442     bool tmp_owner = owner_;
443     string_ = str.string_;
444     owner_ = str.owner_;
445     str.string_ = tmp_string;
446     str.owner_ = tmp_owner;
447   }
448 
449   // The following methods are unique to CEF string template types.
450 
451   ///
452   // Returns true if this class owns the underlying string structure.
453   ///
IsOwner()454   bool IsOwner() const { return owner_; }
455 
456   ///
457   // Returns a read-only pointer to the underlying string structure. May return
458   // NULL if no structure is currently allocated.
459   ///
GetStruct()460   const struct_type* GetStruct() const { return string_; }
461 
462   ///
463   // Returns a writable pointer to the underlying string structure. Will never
464   // return NULL.
465   ///
GetWritableStruct()466   struct_type* GetWritableStruct() {
467     AllocIfNeeded();
468     return string_;
469   }
470 
471   ///
472   // Clear the state of this class. The underlying string structure and data
473   // will be freed if this class owns the structure.
474   ///
ClearAndFree()475   void ClearAndFree() {
476     if (!string_)
477       return;
478     if (owner_) {
479       clear();
480       delete string_;
481     }
482     string_ = NULL;
483     owner_ = false;
484   }
485 
486   ///
487   // Attach to the specified string structure. If |owner| is true this class
488   // will take ownership of the structure.
489   ///
Attach(struct_type * str,bool owner)490   void Attach(struct_type* str, bool owner) {
491     // Free the previous structure and data, if any.
492     ClearAndFree();
493 
494     string_ = str;
495     owner_ = owner;
496   }
497 
498   ///
499   // Take ownership of the specified userfree structure's string data. The
500   // userfree structure itself will be freed. Only use this method with userfree
501   // structures.
502   ///
AttachToUserFree(userfree_struct_type str)503   void AttachToUserFree(userfree_struct_type str) {
504     // Free the previous structure and data, if any.
505     ClearAndFree();
506 
507     if (!str)
508       return;
509 
510     AllocIfNeeded();
511     owner_ = true;
512     memcpy(string_, str, sizeof(struct_type));
513 
514     // Free the |str| structure but not the data.
515     memset(str, 0, sizeof(struct_type));
516     traits::userfree_free(str);
517   }
518 
519   ///
520   // Detach from the underlying string structure. To avoid memory leaks only use
521   // this method if you already hold a pointer to the underlying string
522   // structure.
523   ///
Detach()524   void Detach() {
525     string_ = NULL;
526     owner_ = false;
527   }
528 
529   ///
530   // Create a userfree structure and give it ownership of this class' string
531   // data. This class will be disassociated from the data. May return NULL if
532   // this string class currently contains no data.
533   ///
DetachToUserFree()534   userfree_struct_type DetachToUserFree() {
535     if (empty())
536       return NULL;
537 
538     userfree_struct_type str = traits::userfree_alloc();
539     memcpy(str, string_, sizeof(struct_type));
540 
541     // Free this class' structure but not the data.
542     memset(string_, 0, sizeof(struct_type));
543     ClearAndFree();
544 
545     return str;
546   }
547 
548   ///
549   // Set this string's data to the specified character array. If |copy| is true
550   // this class will copy the data. Otherwise, this class will reference the
551   // existing data. Referenced data must exist for the lifetime of this class
552   // and will not be freed by this class.
553   ///
FromString(const char_type * src,size_t src_len,bool copy)554   bool FromString(const char_type* src, size_t src_len, bool copy) {
555     if (src == NULL || src_len == 0) {
556       clear();
557       return true;
558     }
559     AllocIfNeeded();
560     return traits::set(src, src_len, string_, copy) ? true : false;
561   }
562 
563   ///
564   // Set this string's data from an existing ASCII string. Data will be always
565   // copied. Translation will occur if necessary based on the underlying string
566   // type.
567   ///
FromASCII(const char * str)568   bool FromASCII(const char* str) {
569     size_t len = str ? strlen(str) : 0;
570     if (len == 0) {
571       clear();
572       return true;
573     }
574     AllocIfNeeded();
575     return traits::from_ascii(str, len, string_);
576   }
577 
578   ///
579   // Return this string's data as a std::string. Translation will occur if
580   // necessary based on the underlying string type.
581   ///
ToString()582   std::string ToString() const {
583     if (empty())
584       return std::string();
585     return traits::to_string(string_);
586   }
587 
588   ///
589   // Set this string's data from an existing std::string. Data will be always
590   // copied. Translation will occur if necessary based on the underlying string
591   // type.
592   ///
FromString(const std::string & str)593   bool FromString(const std::string& str) {
594     if (str.empty()) {
595       clear();
596       return true;
597     }
598     AllocIfNeeded();
599     return traits::from_string(str, string_);
600   }
601 
602   ///
603   // Return this string's data as a std::wstring. Translation will occur if
604   // necessary based on the underlying string type.
605   ///
ToWString()606   std::wstring ToWString() const {
607     if (empty())
608       return std::wstring();
609     return traits::to_wstring(string_);
610   }
611 
612   ///
613   // Set this string's data from an existing std::wstring. Data will be always
614   // copied. Translation will occur if necessary based on the underlying string
615   // type.
616   ///
FromWString(const std::wstring & str)617   bool FromWString(const std::wstring& str) {
618     if (str.empty()) {
619       clear();
620       return true;
621     }
622     AllocIfNeeded();
623     return traits::from_wstring(str, string_);
624   }
625 
626   ///
627   // Return this string's data as a string16. Translation will occur if
628   // necessary based on the underlying string type.
629   ///
ToString16()630   std::u16string ToString16() const {
631     if (empty())
632       return std::u16string();
633     return traits::to_string16(string_);
634   }
635 
636   ///
637   // Set this string's data from an existing string16. Data will be always
638   // copied. Translation will occur if necessary based on the underlying string
639   // type.
640   ///
FromString16(const std::u16string & str)641   bool FromString16(const std::u16string& str) {
642     if (str.empty()) {
643       clear();
644       return true;
645     }
646     AllocIfNeeded();
647     return traits::from_string16(str, string_);
648   }
649 
650   ///
651   // Comparison operator overloads.
652   ///
653   bool operator<(const CefStringBase& str) const { return (compare(str) < 0); }
654   bool operator<=(const CefStringBase& str) const {
655     return (compare(str) <= 0);
656   }
657   bool operator>(const CefStringBase& str) const { return (compare(str) > 0); }
658   bool operator>=(const CefStringBase& str) const {
659     return (compare(str) >= 0);
660   }
661   bool operator==(const CefStringBase& str) const {
662     return (compare(str) == 0);
663   }
664   bool operator!=(const CefStringBase& str) const {
665     return (compare(str) != 0);
666   }
667 
668   ///
669   // Assignment operator overloads.
670   ///
671   CefStringBase& operator=(const CefStringBase& str) {
672     FromString(str.c_str(), str.length(), true);
673     return *this;
674   }
string()675   operator std::string() const { return ToString(); }
676   CefStringBase& operator=(const std::string& str) {
677     FromString(str);
678     return *this;
679   }
680   CefStringBase& operator=(const char* str) {
681     FromString(std::string(str));
682     return *this;
683   }
wstring()684   operator std::wstring() const { return ToWString(); }
685   CefStringBase& operator=(const std::wstring& str) {
686     FromWString(str);
687     return *this;
688   }
689   CefStringBase& operator=(const wchar_t* str) {
690     FromWString(std::wstring(str));
691     return *this;
692   }
u16string()693   operator std::u16string() const { return ToString16(); }
694   CefStringBase& operator=(const std::u16string& str) {
695     FromString16(str);
696     return *this;
697   }
698   CefStringBase& operator=(const std::u16string::value_type* str) {
699     FromString16(std::u16string(str));
700     return *this;
701   }
702 #if defined(WCHAR_T_IS_UTF32)
703   CefStringBase& operator=(const char16* str) {
704     FromString16(std::u16string(
705         reinterpret_cast<const std::u16string::value_type*>(str)));
706     return *this;
707   }
708 #endif  // WCHAR_T_IS_UTF32
709 #if defined(USING_CHROMIUM_INCLUDES)
710   // The base::FilePath constructor is marked as explicit so provide the
711   // conversion here for convenience.
FilePath()712   operator base::FilePath() const {
713 #if defined(OS_WIN)
714     return base::FilePath(ToWString());
715 #else
716     return base::FilePath(ToString());
717 #endif
718   }
719 #endif  // USING_CHROMIUM_INCLUDES
720 
721  private:
722   // Allocate the string structure if it doesn't already exist.
AllocIfNeeded()723   void AllocIfNeeded() {
724     if (string_ == NULL) {
725       string_ = new struct_type;
726       memset(string_, 0, sizeof(struct_type));
727       owner_ = true;
728     }
729   }
730 
731   struct_type* string_;
732   bool owner_;
733 };
734 
735 typedef CefStringBase<CefStringTraitsWide> CefStringWide;
736 typedef CefStringBase<CefStringTraitsUTF8> CefStringUTF8;
737 typedef CefStringBase<CefStringTraitsUTF16> CefStringUTF16;
738 
739 #endif  // CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
740