github.com/ckxng/wakeup@v0.0.0-20190105202853-90356a5f5a15/include/internal/cef_string_wrappers.h (about) 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 #include "include/internal/cef_string_types.h" 37 38 #ifdef BUILDING_CEF_SHARED 39 #include "base/strings/string16.h" 40 #endif 41 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 51 static inline void clear(struct_type *s) { cef_string_wide_clear(s); } 52 static inline int set(const char_type* src, size_t src_size, 53 struct_type* output, int copy) { 54 return cef_string_wide_set(src, src_size, output, copy); 55 } 56 static inline int compare(const struct_type* s1, const struct_type* s2) { 57 return cef_string_wide_cmp(s1, s2); 58 } 59 static inline userfree_struct_type userfree_alloc() { 60 return cef_string_userfree_wide_alloc(); 61 } 62 static inline void userfree_free(userfree_struct_type ufs) { 63 return cef_string_userfree_wide_free(ufs); 64 } 65 66 // Conversion methods. 67 static inline bool from_ascii(const char* str, size_t len, struct_type *s) { 68 return cef_string_ascii_to_wide(str, len, s) ? true : false; 69 } 70 static inline std::string to_string(const struct_type *s) { 71 cef_string_utf8_t cstr; 72 memset(&cstr, 0, sizeof(cstr)); 73 cef_string_wide_to_utf8(s->str, s->length, &cstr); 74 std::string str; 75 if (cstr.length > 0) 76 str = std::string(cstr.str, cstr.length); 77 cef_string_utf8_clear(&cstr); 78 return str; 79 } 80 static inline bool from_string(const std::string& str, struct_type *s) { 81 return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false; 82 } 83 static inline std::wstring to_wstring(const struct_type *s) { 84 return std::wstring(s->str, s->length); 85 } 86 static inline bool from_wstring(const std::wstring& str, struct_type *s) { 87 return cef_string_wide_set(str.c_str(), str.length(), s, true) ? 88 true : false; 89 } 90 #if defined(BUILDING_CEF_SHARED) 91 #if defined(WCHAR_T_IS_UTF32) 92 static inline base::string16 to_string16(const struct_type *s) { 93 cef_string_utf16_t cstr; 94 memset(&cstr, 0, sizeof(cstr)); 95 cef_string_wide_to_utf16(s->str, s->length, &cstr); 96 base::string16 str; 97 if (cstr.length > 0) 98 str = base::string16(cstr.str, cstr.length); 99 cef_string_utf16_clear(&cstr); 100 return str; 101 } 102 static inline bool from_string16(const base::string16& str, 103 struct_type *s) { 104 return cef_string_utf16_to_wide(str.c_str(), str.length(), s) ? 105 true : false; 106 } 107 #else // WCHAR_T_IS_UTF32 108 static inline base::string16 to_string16(const struct_type *s) { 109 return base::string16(s->str, s->length); 110 } 111 static inline bool from_string16(const base::string16& str, struct_type *s) { 112 return cef_string_wide_set(str.c_str(), str.length(), s, true) ? 113 true : false; 114 } 115 #endif // WCHAR_T_IS_UTF32 116 #endif // BUILDING_CEF_SHARED 117 }; 118 119 /// 120 // Traits implementation for utf8 character strings. 121 /// 122 struct CefStringTraitsUTF8 { 123 typedef char char_type; 124 typedef cef_string_utf8_t struct_type; 125 typedef cef_string_userfree_utf8_t userfree_struct_type; 126 127 static inline void clear(struct_type *s) { cef_string_utf8_clear(s); } 128 static inline int set(const char_type* src, size_t src_size, 129 struct_type* output, int copy) { 130 return cef_string_utf8_set(src, src_size, output, copy); 131 } 132 static inline int compare(const struct_type* s1, const struct_type* s2) { 133 return cef_string_utf8_cmp(s1, s2); 134 } 135 static inline userfree_struct_type userfree_alloc() { 136 return cef_string_userfree_utf8_alloc(); 137 } 138 static inline void userfree_free(userfree_struct_type ufs) { 139 return cef_string_userfree_utf8_free(ufs); 140 } 141 142 // Conversion methods. 143 static inline bool from_ascii(const char* str, size_t len, struct_type* s) { 144 return cef_string_utf8_copy(str, len, s) ? true : false; 145 } 146 static inline std::string to_string(const struct_type* s) { 147 return std::string(s->str, s->length); 148 } 149 static inline bool from_string(const std::string& str, struct_type* s) { 150 return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false; 151 } 152 static inline std::wstring to_wstring(const struct_type* s) { 153 cef_string_wide_t cstr; 154 memset(&cstr, 0, sizeof(cstr)); 155 cef_string_utf8_to_wide(s->str, s->length, &cstr); 156 std::wstring str; 157 if (cstr.length > 0) 158 str = std::wstring(cstr.str, cstr.length); 159 cef_string_wide_clear(&cstr); 160 return str; 161 } 162 static inline bool from_wstring(const std::wstring& str, struct_type* s) { 163 return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false; 164 } 165 #if defined(BUILDING_CEF_SHARED) 166 static inline base::string16 to_string16(const struct_type* s) { 167 cef_string_utf16_t cstr; 168 memset(&cstr, 0, sizeof(cstr)); 169 cef_string_utf8_to_utf16(s->str, s->length, &cstr); 170 base::string16 str; 171 if (cstr.length > 0) 172 str = base::string16(cstr.str, cstr.length); 173 cef_string_utf16_clear(&cstr); 174 return str; 175 } 176 static inline bool from_string16(const base::string16& str, struct_type* s) { 177 return cef_string_utf16_to_utf8(str.c_str(), str.length(), s) ? 178 true : false; 179 } 180 #endif // BUILDING_CEF_SHARED 181 }; 182 183 /// 184 // Traits implementation for utf16 character strings. 185 /// 186 struct CefStringTraitsUTF16 { 187 typedef char16 char_type; 188 typedef cef_string_utf16_t struct_type; 189 typedef cef_string_userfree_utf16_t userfree_struct_type; 190 191 static inline void clear(struct_type *s) { cef_string_utf16_clear(s); } 192 static inline int set(const char_type* src, size_t src_size, 193 struct_type* output, int copy) { 194 return cef_string_utf16_set(src, src_size, output, copy); 195 } 196 static inline int compare(const struct_type* s1, const struct_type* s2) { 197 return cef_string_utf16_cmp(s1, s2); 198 } 199 static inline userfree_struct_type userfree_alloc() { 200 return cef_string_userfree_utf16_alloc(); 201 } 202 static inline void userfree_free(userfree_struct_type ufs) { 203 return cef_string_userfree_utf16_free(ufs); 204 } 205 206 // Conversion methods. 207 static inline bool from_ascii(const char* str, size_t len, struct_type* s) { 208 return cef_string_ascii_to_utf16(str, len, s) ? true : false; 209 } 210 static inline std::string to_string(const struct_type* s) { 211 cef_string_utf8_t cstr; 212 memset(&cstr, 0, sizeof(cstr)); 213 cef_string_utf16_to_utf8(s->str, s->length, &cstr); 214 std::string str; 215 if (cstr.length > 0) 216 str = std::string(cstr.str, cstr.length); 217 cef_string_utf8_clear(&cstr); 218 return str; 219 } 220 static inline bool from_string(const std::string& str, struct_type* s) { 221 return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ? 222 true : false; 223 } 224 #if defined(WCHAR_T_IS_UTF32) 225 static inline std::wstring to_wstring(const struct_type* s) { 226 cef_string_wide_t cstr; 227 memset(&cstr, 0, sizeof(cstr)); 228 cef_string_utf16_to_wide(s->str, s->length, &cstr); 229 std::wstring str; 230 if (cstr.length > 0) 231 str = std::wstring(cstr.str, cstr.length); 232 cef_string_wide_clear(&cstr); 233 return str; 234 } 235 static inline bool from_wstring(const std::wstring& str, struct_type* s) { 236 return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ? 237 true : false; 238 } 239 #else // WCHAR_T_IS_UTF32 240 static inline std::wstring to_wstring(const struct_type* s) { 241 return std::wstring(s->str, s->length); 242 } 243 static inline bool from_wstring(const std::wstring& str, struct_type* s) { 244 return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? 245 true : false; 246 } 247 #endif // WCHAR_T_IS_UTF32 248 #if defined(BUILDING_CEF_SHARED) 249 static inline base::string16 to_string16(const struct_type* s) { 250 return base::string16(s->str, s->length); 251 } 252 static inline bool from_string16(const base::string16& str, struct_type* s) { 253 return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? 254 true : false; 255 } 256 #endif // BUILDING_CEF_SHARED 257 }; 258 259 /// 260 // CEF string classes can convert between all supported string types. For 261 // example, the CefStringWide class uses wchar_t as the underlying character 262 // type and provides two approaches for converting data to/from a UTF8 string 263 // (std::string). 264 // <p> 265 // 1. Implicit conversion using the assignment operator overload. 266 // <pre> 267 // CefStringWide aCefString; 268 // std::string aUTF8String; 269 // aCefString = aUTF8String; // Assign std::string to CefStringWide 270 // aUTF8String = aCefString; // Assign CefStringWide to std::string 271 // </pre> 272 // 2. Explicit conversion using the FromString/ToString methods. 273 // <pre> 274 // CefStringWide aCefString; 275 // std::string aUTF8String; 276 // aCefString.FromString(aUTF8String); // Assign std::string to CefStringWide 277 // aUTF8String = aCefString.ToString(); // Assign CefStringWide to std::string 278 // </pre> 279 // Conversion will only occur if the assigned value is a different string type. 280 // Assigning a std::string to a CefStringUTF8, for example, will copy the data 281 // without performing a conversion. 282 // </p> 283 // CEF string classes are safe for reading from multiple threads but not for 284 // modification. It is the user's responsibility to provide synchronization if 285 // modifying CEF strings from multiple threads. 286 /// 287 template <class traits> 288 class CefStringBase { 289 public: 290 typedef typename traits::char_type char_type; 291 typedef typename traits::struct_type struct_type; 292 typedef typename traits::userfree_struct_type userfree_struct_type; 293 294 /// 295 // Default constructor. 296 /// 297 CefStringBase() : string_(NULL), owner_(false) {} 298 299 /// 300 // Create a new string from an existing string. Data will always be copied. 301 /// 302 CefStringBase(const CefStringBase& str) 303 : string_(NULL), owner_(false) { 304 FromString(str.c_str(), str.length(), true); 305 } 306 307 /// 308 // Create a new string from an existing std::string. Data will be always 309 // copied. Translation will occur if necessary based on the underlying string 310 // type. 311 /// 312 CefStringBase(const std::string& src) // NOLINT(runtime/explicit) 313 : string_(NULL), owner_(false) { 314 FromString(src); 315 } 316 CefStringBase(const char* src) // NOLINT(runtime/explicit) 317 : string_(NULL), owner_(false) { 318 if (src) 319 FromString(std::string(src)); 320 } 321 322 /// 323 // Create a new string from an existing std::wstring. Data will be always 324 // copied. Translation will occur if necessary based on the underlying string 325 // type. 326 /// 327 CefStringBase(const std::wstring& src) // NOLINT(runtime/explicit) 328 : string_(NULL), owner_(false) { 329 FromWString(src); 330 } 331 CefStringBase(const wchar_t* src) // NOLINT(runtime/explicit) 332 : string_(NULL), owner_(false) { 333 if (src) 334 FromWString(std::wstring(src)); 335 } 336 337 #if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) 338 /// 339 // Create a new string from an existing string16. Data will be always 340 // copied. Translation will occur if necessary based on the underlying string 341 // type. 342 /// 343 CefStringBase(const base::string16& src) // NOLINT(runtime/explicit) 344 : string_(NULL), owner_(false) { 345 FromString16(src); 346 } 347 CefStringBase(const char16* src) // NOLINT(runtime/explicit) 348 : string_(NULL), owner_(false) { 349 if (src) 350 FromString16(base::string16(src)); 351 } 352 #endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 353 354 /// 355 // Create a new string from an existing character array. If |copy| is true 356 // this class will copy the data. Otherwise, this class will reference the 357 // existing data. Referenced data must exist for the lifetime of this class 358 // and will not be freed by this class. 359 /// 360 CefStringBase(const char_type* src, size_t src_len, bool copy) 361 : string_(NULL), owner_(false) { 362 if (src && src_len > 0) 363 FromString(src, src_len, copy); 364 } 365 366 /// 367 // Create a new string referencing an existing string structure without taking 368 // ownership. Referenced structures must exist for the lifetime of this class 369 // and will not be freed by this class. 370 /// 371 CefStringBase(const struct_type* src) // NOLINT(runtime/explicit) 372 : string_(NULL), owner_(false) { 373 if (!src) 374 return; 375 // Reference the existing structure without taking ownership. 376 Attach(const_cast<struct_type*>(src), false); 377 } 378 379 virtual ~CefStringBase() { ClearAndFree(); } 380 381 382 // The following methods are named for compatibility with the standard library 383 // string template types. 384 385 /// 386 // Return a read-only pointer to the string data. 387 /// 388 const char_type* c_str() const { return (string_ ? string_->str : NULL); } 389 390 /// 391 // Return the length of the string data. 392 /// 393 size_t length() const { return (string_ ? string_->length : 0); } 394 395 /// 396 // Return the length of the string data. 397 /// 398 inline size_t size() const { return length(); } 399 400 /// 401 // Returns true if the string is empty. 402 /// 403 bool empty() const { return (string_ == NULL || string_->length == 0); } 404 405 /// 406 // Compare this string to the specified string. 407 /// 408 int compare(const CefStringBase& str) const { 409 if (empty() && str.empty()) 410 return 0; 411 if (empty()) 412 return -1; 413 if (str.empty()) 414 return 1; 415 return traits::compare(string_, str.GetStruct()); 416 } 417 418 /// 419 // Clear the string data. 420 /// 421 void clear() { 422 if (string_) 423 traits::clear(string_); 424 } 425 426 /// 427 // Swap this string's contents with the specified string. 428 /// 429 void swap(CefStringBase& str) { 430 struct_type* tmp_string = string_; 431 bool tmp_owner = owner_; 432 string_ = str.string_; 433 owner_ = str.owner_; 434 str.string_ = tmp_string; 435 str.owner_ = tmp_owner; 436 } 437 438 439 // The following methods are unique to CEF string template types. 440 441 /// 442 // Returns true if this class owns the underlying string structure. 443 /// 444 bool IsOwner() const { return owner_; } 445 446 /// 447 // Returns a read-only pointer to the underlying string structure. May return 448 // NULL if no structure is currently allocated. 449 /// 450 const struct_type* GetStruct() const { return string_; } 451 452 /// 453 // Returns a writable pointer to the underlying string structure. Will never 454 // return NULL. 455 /// 456 struct_type* GetWritableStruct() { 457 AllocIfNeeded(); 458 return string_; 459 } 460 461 /// 462 // Clear the state of this class. The underlying string structure and data 463 // will be freed if this class owns the structure. 464 /// 465 void ClearAndFree() { 466 if (!string_) 467 return; 468 if (owner_) { 469 clear(); 470 delete string_; 471 } 472 string_ = NULL; 473 owner_ = false; 474 } 475 476 /// 477 // Attach to the specified string structure. If |owner| is true this class 478 // will take ownership of the structure. 479 /// 480 void Attach(struct_type* str, bool owner) { 481 // Free the previous structure and data, if any. 482 ClearAndFree(); 483 484 string_ = str; 485 owner_ = owner; 486 } 487 488 /// 489 // Take ownership of the specified userfree structure's string data. The 490 // userfree structure itself will be freed. Only use this method with userfree 491 // structures. 492 /// 493 void AttachToUserFree(userfree_struct_type str) { 494 // Free the previous structure and data, if any. 495 ClearAndFree(); 496 497 if (!str) 498 return; 499 500 AllocIfNeeded(); 501 owner_ = true; 502 memcpy(string_, str, sizeof(struct_type)); 503 504 // Free the |str| structure but not the data. 505 memset(str, 0, sizeof(struct_type)); 506 traits::userfree_free(str); 507 } 508 509 /// 510 // Detach from the underlying string structure. To avoid memory leaks only use 511 // this method if you already hold a pointer to the underlying string 512 // structure. 513 /// 514 void Detach() { 515 string_ = NULL; 516 owner_ = false; 517 } 518 519 /// 520 // Create a userfree structure and give it ownership of this class' string 521 // data. This class will be disassociated from the data. May return NULL if 522 // this string class currently contains no data. 523 /// 524 userfree_struct_type DetachToUserFree() { 525 if (empty()) 526 return NULL; 527 528 userfree_struct_type str = traits::userfree_alloc(); 529 memcpy(str, string_, sizeof(struct_type)); 530 531 // Free this class' structure but not the data. 532 memset(string_, 0, sizeof(struct_type)); 533 ClearAndFree(); 534 535 return str; 536 } 537 538 /// 539 // Set this string's data to the specified character array. If |copy| is true 540 // this class will copy the data. Otherwise, this class will reference the 541 // existing data. Referenced data must exist for the lifetime of this class 542 // and will not be freed by this class. 543 /// 544 bool FromString(const char_type* src, size_t src_len, bool copy) { 545 if (src == NULL || src_len == 0) { 546 clear(); 547 return true; 548 } 549 AllocIfNeeded(); 550 return traits::set(src, src_len, string_, copy) ? true : false; 551 } 552 553 /// 554 // Set this string's data from an existing ASCII string. Data will be always 555 // copied. Translation will occur if necessary based on the underlying string 556 // type. 557 /// 558 bool FromASCII(const char* str) { 559 size_t len = str ? strlen(str) : 0; 560 if (len == 0) { 561 clear(); 562 return true; 563 } 564 AllocIfNeeded(); 565 return traits::from_ascii(str, len, string_); 566 } 567 568 /// 569 // Return this string's data as a std::string. Translation will occur if 570 // necessary based on the underlying string type. 571 /// 572 std::string ToString() const { 573 if (empty()) 574 return std::string(); 575 return traits::to_string(string_); 576 } 577 578 /// 579 // Set this string's data from an existing std::string. Data will be always 580 // copied. Translation will occur if necessary based on the underlying string 581 // type. 582 /// 583 bool FromString(const std::string& str) { 584 if (str.empty()) { 585 clear(); 586 return true; 587 } 588 AllocIfNeeded(); 589 return traits::from_string(str, string_); 590 } 591 592 /// 593 // Return this string's data as a std::wstring. Translation will occur if 594 // necessary based on the underlying string type. 595 /// 596 std::wstring ToWString() const { 597 if (empty()) 598 return std::wstring(); 599 return traits::to_wstring(string_); 600 } 601 602 /// 603 // Set this string's data from an existing std::wstring. Data will be always 604 // copied. Translation will occur if necessary based on the underlying string 605 // type. 606 /// 607 bool FromWString(const std::wstring& str) { 608 if (str.empty()) { 609 clear(); 610 return true; 611 } 612 AllocIfNeeded(); 613 return traits::from_wstring(str, string_); 614 } 615 #if defined(BUILDING_CEF_SHARED) 616 /// 617 // Return this string's data as a string16. Translation will occur if 618 // necessary based on the underlying string type. 619 /// 620 base::string16 ToString16() const { 621 if (empty()) 622 return base::string16(); 623 return traits::to_string16(string_); 624 } 625 626 /// 627 // Set this string's data from an existing string16. Data will be always 628 // copied. Translation will occur if necessary based on the underlying string 629 // type. 630 /// 631 bool FromString16(const base::string16& str) { 632 if (str.empty()) { 633 clear(); 634 return true; 635 } 636 AllocIfNeeded(); 637 return traits::from_string16(str, string_); 638 } 639 #endif // BUILDING_CEF_SHARED 640 641 /// 642 // Comparison operator overloads. 643 /// 644 bool operator<(const CefStringBase& str) const { 645 return (compare(str) < 0); 646 } 647 bool operator<=(const CefStringBase& str) const { 648 return (compare(str) <= 0); 649 } 650 bool operator>(const CefStringBase& str) const { 651 return (compare(str) > 0); 652 } 653 bool operator>=(const CefStringBase& str) const { 654 return (compare(str) >= 0); 655 } 656 bool operator==(const CefStringBase& str) const { 657 return (compare(str) == 0); 658 } 659 bool operator!=(const CefStringBase& str) const { 660 return (compare(str) != 0); 661 } 662 663 /// 664 // Assignment operator overloads. 665 /// 666 CefStringBase& operator=(const CefStringBase& str) { 667 FromString(str.c_str(), str.length(), true); 668 return *this; 669 } 670 operator std::string() const { 671 return ToString(); 672 } 673 CefStringBase& operator=(const std::string& str) { 674 FromString(str); 675 return *this; 676 } 677 CefStringBase& operator=(const char* str) { 678 FromString(std::string(str)); 679 return *this; 680 } 681 operator std::wstring() const { 682 return ToWString(); 683 } 684 CefStringBase& operator=(const std::wstring& str) { 685 FromWString(str); 686 return *this; 687 } 688 CefStringBase& operator=(const wchar_t* str) { 689 FromWString(std::wstring(str)); 690 return *this; 691 } 692 #if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) 693 operator base::string16() const { 694 return ToString16(); 695 } 696 CefStringBase& operator=(const base::string16& str) { 697 FromString16(str); 698 return *this; 699 } 700 CefStringBase& operator=(const char16* str) { 701 FromString16(base::string16(str)); 702 return *this; 703 } 704 #endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 705 706 private: 707 // Allocate the string structure if it doesn't already exist. 708 void AllocIfNeeded() { 709 if (string_ == NULL) { 710 string_ = new struct_type; 711 memset(string_, 0, sizeof(struct_type)); 712 owner_ = true; 713 } 714 } 715 716 struct_type* string_; 717 bool owner_; 718 }; 719 720 721 typedef CefStringBase<CefStringTraitsWide> CefStringWide; 722 typedef CefStringBase<CefStringTraitsUTF8> CefStringUTF8; 723 typedef CefStringBase<CefStringTraitsUTF16> CefStringUTF16; 724 725 #endif // CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_