Introduce CefString and cef_string_t implementations that support string type conversions and customization of the API string type (issue #146).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@146 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2010-11-22 17:58:27 +00:00
parent 7d60642638
commit fdec22ac8f
2 changed files with 808 additions and 0 deletions

183
include/cef_string_types.h Normal file
View File

@ -0,0 +1,183 @@
// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_STRING_TYPES_T
#define _CEF_STRING_TYPES_T
// CEF provides functions for converting between UTF-8, -16 and -32 strings.
// CEF string types are safe for reading from multiple threads but not for
// modification. It is the user's responsibility to provide synchronization if
// modifying CEF strings from multiple threads.
#ifdef __cplusplus
extern "C" {
#endif
#include "cef_export.h"
// CEF character type definitions. wchat_t is 2 bytes on Windows and 4 bytes on
// most other platforms.
#ifdef _WIN32
typedef wchar_t char16_t;
#else // _WIN32
typedef uint16 char16_t;
#ifndef WCHAR_T_IS_UTF32
#define WCHAR_T_IS_UTF32
#endif // WCHAR_T_IS_UTF32
#endif // _WIN32
// CEF string type definitions. Whomever allocates |str| is responsible for
// providing an appropriate |dtor| implementation that will free the string in
// the same memory space. When reusing an existing string structure make sure
// to call |dtor| for the old value before assigning new |str| and |dtor|
// values. Static strings will have a NULL |dtor| value. Using the below
// functions if you want this managed for you.
typedef struct _cef_string_wide_t {
wchar_t* str;
size_t length;
void (*dtor)(wchar_t* str);
} cef_string_wide_t;
typedef struct _cef_string_utf8_t {
char* str;
size_t length;
void (*dtor)(char* str);
} cef_string_utf8_t;
typedef struct _cef_string_utf16_t {
char16_t* str;
size_t length;
void (*dtor)(char16_t* str);
} cef_string_utf16_t;
// These functions set string values. If |copy| is true (1) the value will be
// copied instead of referenced. It is up to the user to properly manage
// the lifespan of references.
CEF_EXPORT int cef_string_wide_set(const wchar_t* src, size_t src_len,
cef_string_wide_t* output, int copy);
CEF_EXPORT int cef_string_utf8_set(const char* src, size_t src_len,
cef_string_utf8_t* output, int copy);
CEF_EXPORT int cef_string_utf16_set(const char16_t* src, size_t src_len,
cef_string_utf16_t* output, int copy);
// Convenience macros for copying values.
#define cef_string_wide_copy(src, src_len, output) \
cef_string_wide_set(src, src_len, output, true)
#define cef_string_utf8_copy(src, src_len, output) \
cef_string_utf8_set(src, src_len, output, true)
#define cef_string_utf16_copy(src, src_len, output) \
cef_string_utf16_set(src, src_len, output, true)
// These functions clear string values. The structure itself is not freed.
CEF_EXPORT void cef_string_wide_clear(cef_string_wide_t* str);
CEF_EXPORT void cef_string_utf8_clear(cef_string_utf8_t* str);
CEF_EXPORT void cef_string_utf16_clear(cef_string_utf16_t* str);
// These functions compare two string values with the same results as strcmp().
CEF_EXPORT int cef_string_wide_cmp(const cef_string_wide_t* str1,
const cef_string_wide_t* str2);
CEF_EXPORT int cef_string_utf8_cmp(const cef_string_utf8_t* str1,
const cef_string_utf8_t* str2);
CEF_EXPORT int cef_string_utf16_cmp(const cef_string_utf16_t* str1,
const cef_string_utf16_t* str2);
// These functions convert between UTF-8, -16, and -32 strings. They are
// potentially slow so unnecessary conversions should be avoided. The best
// possible result will always be written to |output| with the boolean return
// value indicating whether the conversion is 100% valid.
CEF_EXPORT int cef_string_wide_to_utf8(const wchar_t* src, size_t src_len,
cef_string_utf8_t* output);
CEF_EXPORT int cef_string_utf8_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output);
CEF_EXPORT int cef_string_wide_to_utf16(const wchar_t* src, size_t src_len,
cef_string_utf16_t* output);
CEF_EXPORT int cef_string_utf16_to_wide(const char16_t* src, size_t src_len,
cef_string_wide_t* output);
CEF_EXPORT int cef_string_utf8_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output);
CEF_EXPORT int cef_string_utf16_to_utf8(const char16_t* src, size_t src_len,
cef_string_utf8_t* output);
// These functions convert an ASCII string, typically a hardcoded constant, to a
// Wide/UTF16 string. Use instead of the UTF8 conversion routines if you know
// the string is ASCII.
CEF_EXPORT int cef_string_ascii_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output);
CEF_EXPORT int cef_string_ascii_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output);
// It is sometimes necessary for the system to allocate string structures with
// the expectation that the user will free them. The userfree types act as a
// hint that the user is responsible for freeing the structure.
typedef cef_string_wide_t* cef_string_userfree_wide_t;
typedef cef_string_utf8_t* cef_string_userfree_utf8_t;
typedef cef_string_utf16_t* cef_string_userfree_utf16_t;
// These functions allocate a new string structure. They must be freed by
// calling the associated free function.
CEF_EXPORT cef_string_userfree_wide_t cef_string_userfree_wide_alloc();
CEF_EXPORT cef_string_userfree_utf8_t cef_string_userfree_utf8_alloc();
CEF_EXPORT cef_string_userfree_utf16_t cef_string_userfree_utf16_alloc();
// These functions free the string structure allocated by the associated
// alloc function. Any string contents will first be cleared.
CEF_EXPORT void cef_string_userfree_wide_free(cef_string_userfree_wide_t str);
CEF_EXPORT void cef_string_userfree_utf8_free(cef_string_userfree_utf8_t str);
CEF_EXPORT void cef_string_userfree_utf16_free(cef_string_userfree_utf16_t str);
#ifdef __cplusplus
}
#endif
#endif // _CEF_STRING_TYPES_T

View File

@ -0,0 +1,625 @@
// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_STRING_WRAPPERS_H
#define _CEF_STRING_WRAPPERS_H
#include "cef_string_types.h"
#ifdef BUILDING_CEF_SHARED
#include "base/string16.h"
#endif
#include <string>
// Traits implementation for wide character strings.
struct CefStringTraitsWide {
typedef wchar_t char_type;
typedef cef_string_wide_t struct_type;
typedef cef_string_userfree_wide_t userfree_struct_type;
static inline void clear(struct_type *s) { cef_string_wide_clear(s); }
static inline int set(const char_type* src, size_t src_size,
struct_type *output, int copy)
{ return cef_string_wide_set(src, src_size, output, copy); }
static inline int compare(const struct_type* s1, const struct_type* s2)
{ return cef_string_wide_cmp(s1, s2); }
static inline userfree_struct_type userfree_alloc()
{ return cef_string_userfree_wide_alloc(); }
static inline void userfree_free(userfree_struct_type ufs)
{ return cef_string_userfree_wide_free(ufs); }
// Conversion methods.
static inline bool from_ascii(const char* str, size_t len, struct_type *s)
{
return cef_string_ascii_to_wide(str, len, s) ? true : false;
}
static inline std::string to_string(const struct_type *s)
{
cef_string_utf8_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_wide_to_utf8(s->str, s->length, &cstr);
std::string str;
if (cstr.length > 0)
str = std::string(cstr.str, cstr.length);
cef_string_utf8_clear(&cstr);
return str;
}
static inline bool from_string(const std::string& str, struct_type *s)
{
return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false;
}
static inline std::wstring to_wstring(const struct_type *s)
{
return std::wstring(s->str, s->length);
}
static inline bool from_wstring(const std::wstring& str, struct_type *s)
{
return cef_string_wide_set(str.c_str(), str.length(), s, true) ?
true : false;
}
#if defined(BUILDING_CEF_SHARED)
#if defined(WCHAR_T_IS_UTF32)
static inline string16 to_string16(const struct_type *s)
{
cef_string_utf16_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_wide_to_utf16(s->str, s->length, &cstr);
string16 str;
if (cstr.length > 0)
str = string16(cstr.str, cstr.length);
cef_string_utf16_clear(&cstr);
return str;
}
static inline bool from_string16(const string16& str, struct_type *s)
{
return cef_string_utf16_to_wide(str.c_str(), str.length(), s) ?
true : false;
}
#else // WCHAR_T_IS_UTF32
static inline string16 to_string16(const struct_type *s)
{
return string16(s->str, s->length);
}
static inline bool from_string16(const string16& str, struct_type *s)
{
return cef_string_wide_set(str.c_str(), str.length(), s, true) ?
true : false;
}
#endif // WCHAR_T_IS_UTF32
#endif // BUILDING_CEF_SHARED
};
// Traits implementation for utf8 character strings.
struct CefStringTraitsUTF8 {
typedef char char_type;
typedef cef_string_utf8_t struct_type;
typedef cef_string_userfree_utf8_t userfree_struct_type;
static inline void clear(struct_type *s) { cef_string_utf8_clear(s); }
static inline int set(const char_type* src, size_t src_size,
struct_type *output, int copy)
{ return cef_string_utf8_set(src, src_size, output, copy); }
static inline int compare(const struct_type* s1, const struct_type* s2)
{ return cef_string_utf8_cmp(s1, s2); }
static inline userfree_struct_type userfree_alloc()
{ return cef_string_userfree_utf8_alloc(); }
static inline void userfree_free(userfree_struct_type ufs)
{ return cef_string_userfree_utf8_free(ufs); }
// Conversion methods.
static inline bool from_ascii(const char* str, size_t len, struct_type* s)
{
return cef_string_utf8_copy(str, len, s) ? true : false;
}
static inline std::string to_string(const struct_type* s)
{
return std::string(s->str, s->length);
}
static inline bool from_string(const std::string& str, struct_type* s)
{
return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false;
}
static inline std::wstring to_wstring(const struct_type* s)
{
cef_string_wide_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_utf8_to_wide(s->str, s->length, &cstr);
std::wstring str;
if (cstr.length > 0)
str = std::wstring(cstr.str, cstr.length);
cef_string_wide_clear(&cstr);
return str;
}
static inline bool from_wstring(const std::wstring& str, struct_type* s)
{
return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false;
}
#if defined(BUILDING_CEF_SHARED)
static inline string16 to_string16(const struct_type* s)
{
cef_string_utf16_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_utf8_to_utf16(s->str, s->length, &cstr);
string16 str;
if (cstr.length > 0)
str = string16(cstr.str, cstr.length);
cef_string_utf16_clear(&cstr);
return str;
}
static inline bool from_string16(const string16& str, struct_type* s)
{
return cef_string_utf16_to_utf8(str.c_str(), str.length(), s) ?
true : false;
}
#endif // BUILDING_CEF_SHARED
};
// Traits implementation for utf16 character strings.
struct CefStringTraitsUTF16 {
typedef char16_t char_type;
typedef cef_string_utf16_t struct_type;
typedef cef_string_userfree_utf16_t userfree_struct_type;
static inline void clear(struct_type *s) { cef_string_utf16_clear(s); }
static inline int set(const char_type* src, size_t src_size,
struct_type *output, int copy)
{ return cef_string_utf16_set(src, src_size, output, copy); }
static inline int compare(const struct_type* s1, const struct_type* s2)
{ return cef_string_utf16_cmp(s1, s2); }
static inline userfree_struct_type userfree_alloc()
{ return cef_string_userfree_utf16_alloc(); }
static inline void userfree_free(userfree_struct_type ufs)
{ return cef_string_userfree_utf16_free(ufs); }
// Conversion methods.
static inline bool from_ascii(const char* str, size_t len, struct_type* s)
{
return cef_string_ascii_to_utf16(str, len, s) ? true : false;
}
static inline std::string to_string(const struct_type* s)
{
cef_string_utf8_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_utf16_to_utf8(s->str, s->length, &cstr);
std::string str;
if (cstr.length > 0)
str = std::string(cstr.str, cstr.length);
cef_string_utf8_clear(&cstr);
return str;
}
static inline bool from_string(const std::string& str, struct_type* s)
{
return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ?
true : false;
}
#if defined(WCHAR_T_IS_UTF32)
static inline std::wstring to_wstring(const struct_type* s)
{
cef_string_wide_t cstr;
memset(&cstr, 0, sizeof(cstr));
cef_string_utf16_to_wide(s->str, s->length, &cstr);
std::wstring str;
if (cstr.length > 0)
str = std::wstring(cstr.str, cstr.length);
cef_string_wide_clear(&cstr);
return str;
}
static inline bool from_wstring(const std::wstring& str, struct_type* s)
{
return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ?
true : false;
}
#else // WCHAR_T_IS_UTF32
static inline std::wstring to_wstring(const struct_type* s)
{
return std::wstring(s->str, s->length);
}
static inline bool from_wstring(const std::wstring& str, struct_type* s)
{
return cef_string_utf16_set(str.c_str(), str.length(), s, true) ?
true : false;
}
#endif // WCHAR_T_IS_UTF32
#if defined(BUILDING_CEF_SHARED)
static inline string16 to_string16(const struct_type* s)
{
return string16(s->str, s->length);
}
static inline bool FromString16(const string16& str, struct_type* s)
{
return cef_string_utf16_set(str.c_str(), str.length(), s, true) ?
true : false;
}
#endif // BUILDING_CEF_SHARED
};
// String template.
template <class traits>
class CefStringBase {
public:
typedef typename traits::char_type char_type;
typedef typename traits::struct_type struct_type;
typedef typename traits::userfree_struct_type userfree_struct_type;
// Default constructor.
CefStringBase() : string_(NULL), owner_(false) {}
// Create a new string from an existing string. Data will always be copied.
CefStringBase(const CefStringBase& str) : string_(NULL), owner_(false)
{ FromString(str.c_str(), str.length(), true); }
// Create a new string from an existing std::string. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
CefStringBase(const std::string& src) : string_(NULL), owner_(false)
{ FromString(src); }
CefStringBase(const char* src) : string_(NULL), owner_(false)
{ FromString(std::string(src)); }
// Create a new string from an existing std::wstring. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
CefStringBase(const std::wstring& src) : string_(NULL), owner_(false)
{ FromWString(src); }
CefStringBase(const wchar_t* src) : string_(NULL), owner_(false)
{ FromWString(std::wstring(src)); }
#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32))
// Create a new string from an existing string16. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
CefStringBase(const string16& src) : string_(NULL), owner_(false)
{ FromString16(src); }
CefStringBase(const char16_t* src) : string_(NULL), owner_(false)
{ FromString16(string16(src)); }
#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32
// Create a new string from an existing character array. If |copy| is true
// this class will copy the data. Otherwise, this class will reference the
// existing data. Referenced data must exist for the lifetime of this class
// and will not be freed by this class.
CefStringBase(const char_type* src, size_t src_len, bool copy)
: string_(NULL), owner_(false)
{ FromString(src, src_len, copy); }
// Create a new string referencing an existing string structure without taking
// ownership. Referenced structures must exist for the lifetime of this class
// and will not be freed by this class.
CefStringBase(const struct_type* src) : string_(NULL), owner_(false)
{
if (!src)
return;
// Reference the existing structure without taking ownership.
Attach(const_cast<struct_type*>(src), false);
}
virtual ~CefStringBase() { ClearAndFree(); }
// The following methods are named for compatibility with the standard library
// string template types.
// Return a read-only pointer to the string data.
const char_type* c_str() const { return (string_ ? string_->str : NULL); }
// Return the length of the string data.
size_t length() const { return (string_ ? string_->length : 0); }
// Return the length of the string data.
inline size_t size() const { return length(); }
// Returns true if the string is empty.
bool empty() const { return (string_ == NULL || string_->length == 0); }
// Compare this string to the specified string.
int compare(const CefStringBase& str) const
{
if (empty() && str.empty())
return 0;
if (empty())
return -1;
if (str.empty())
return 1;
return traits::compare(string_, str.GetStruct());
}
// Clear the string data.
void clear()
{
if (!empty())
traits::clear(string_);
}
// The following methods are unique to CEF string template types.
// Returns true if this class owns the underlying string structure.
bool IsOwner() const { return owner_; }
// Returns a read-only pointer to the underlying string structure. May return
// NULL if no structure is currently allocated.
const struct_type* GetStruct() const { return string_; }
// Returns a writable pointer to the underlying string structure. Will never
// return NULL.
struct_type* GetWritableStruct()
{
AllocIfNeeded();
return string_;
}
// Clear the state of this class. The underlying string structure and data
// will be freed if this class owns the structure.
void ClearAndFree()
{
if (!string_)
return;
if (owner_) {
clear();
delete string_;
}
string_ = NULL;
owner_ = false;
}
// Attach to the specified string structure. If |owner| is true this class
// will take ownership of the structure.
void Attach(struct_type* str, bool owner)
{
// Free the previous structure and data, if any.
ClearAndFree();
string_ = str;
owner_ = owner;
}
// Take ownership of the specified userfree structure's string data. The
// userfree structure itself will be freed. Only use this method with userfree
// structures.
void AttachToUserFree(userfree_struct_type str)
{
// Free the previous structure and data, if any.
ClearAndFree();
if (!str)
return;
AllocIfNeeded();
owner_ = true;
memcpy(string_, str, sizeof(struct_type));
// Free the |str| structure but not the data.
memset(str, 0, sizeof(struct_type));
traits::userfree_free(str);
}
// Detach from the underlying string structure. To avoid memory leaks only use
// this method if you already hold a pointer to the underlying string
// structure.
void Detach()
{
string_ = NULL;
owner_ = false;
}
// Create a userfree structure and give it ownership of this class' string
// data. This class will be disassociated from the data. May return NULL if
// this string class currently contains no data.
userfree_struct_type DetachToUserFree()
{
if (empty())
return NULL;
userfree_struct_type str = traits::userfree_alloc();
memcpy(str, string_, sizeof(struct_type));
// Free this class' structure but not the data.
memset(string_, 0, sizeof(struct_type));
ClearAndFree();
return str;
}
// Set this string's data to the specified character array. If |copy| is true
// this class will copy the data. Otherwise, this class will reference the
// existing data. Referenced data must exist for the lifetime of this class
// and will not be freed by this class.
bool FromString(const char_type* src, size_t src_len, bool copy)
{
if (src == NULL || src_len == 0) {
clear();
return true;
}
AllocIfNeeded();
return traits::set(src, src_len, string_, copy) ? true : false;
}
// Set this string's data from an existing ASCII string. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
bool FromASCII(const char* str)
{
size_t len = str ? strlen(str) : 0;
if (len == 0) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_ascii(str, len, string_);
}
// Return this string's data as a std::string. Translation will occur if
// necessary based on the underlying string type.
std::string ToString() const
{
if (empty())
return std::string();
return traits::to_string(string_);
}
// Set this string's data from an existing std::string. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
bool FromString(const std::string& str)
{
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string(str, string_);
}
// Return this string's data as a std::wstring. Translation will occur if
// necessary based on the underlying string type.
std::wstring ToWString() const
{
if (empty())
return std::wstring();
return traits::to_wstring(string_);
}
// Set this string's data from an existing std::wstring. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
bool FromWString(const std::wstring& str)
{
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_wstring(str, string_);
}
#if defined(BUILDING_CEF_SHARED)
// Return this string's data as a string16. Translation will occur if
// necessary based on the underlying string type.
string16 ToString16() const
{
if (empty())
return string16();
return traits::to_string16(string_);
}
// Set this string's data from an existing string16. Data will be always
// copied. Translation will occur if necessary based on the underlying string
// type.
bool FromString16(const string16& str)
{
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string16(str, string_);
}
#endif // BUILDING_CEF_SHARED
// Comparison operator overloads.
bool operator<(const CefStringBase& str) const
{ return (compare(str) < 0); }
bool operator<=(const CefStringBase& str) const
{ return (compare(str) <= 0); }
bool operator>(const CefStringBase& str) const
{ return (compare(str) > 0); }
bool operator>=(const CefStringBase& str) const
{ return (compare(str) >= 0); }
bool operator==(const CefStringBase& str) const
{ return (compare(str) == 0); }
bool operator!=(const CefStringBase& str) const
{ return (compare(str) != 0); }
// Assignment operator overloads.
CefStringBase& operator=(const CefStringBase& str)
{ FromString(str.c_str(), str.length(), true); return *this; }
operator std::string() const { return ToString(); }
CefStringBase& operator=(const std::string& str)
{ FromString(str); return *this; }
CefStringBase& operator=(const char* str)
{ FromString(std::string(str)); return *this; }
operator std::wstring() const { return ToWString(); }
CefStringBase& operator=(const std::wstring& str)
{ FromWString(str); return *this; }
CefStringBase& operator=(const wchar_t* str)
{ FromWString(std::wstring(str)); return *this; }
#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32))
operator string16() const { return ToString16(); }
CefStringBase& operator=(const string16& str)
{ FromString16(str); return *this; }
CefStringBase& operator=(const char16_t* str)
{ FromString16(string16(str)); return *this; }
#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32
private:
// Allocate the string structure if it doesn't already exist.
void AllocIfNeeded()
{
if (string_ == NULL) {
string_ = new struct_type;
memset(string_, 0, sizeof(struct_type));
owner_ = true;
}
}
struct_type* string_;
bool owner_;
};
// CEF string classes can convert between all supported string types. For
// example, the CefStringWide class uses wchar_t as the underlying character
// type and provides two approaches for translating data to/from a UTF8 string
// (std::string).
//
// 1. Implicit conversion using the assignment operator overload.
//
// CefStringWide aCefString;
// std::string aUTF8String;
// aCefString = aUTF8String; // Assign std::string to CefStringWide
// aUTF8String = aCefString; // Assign CefStringWide to std::string
//
// 2. Explicit conversion using the FromString/ToString methods.
//
// CefStringWide aCefString;
// std::string aUTF8String;
// aCefString.FromString(aUTF8String); // Assign std::string to CefStringWide
// aUTF8String = aCefString.ToString(); // Assign CefStringWide to std::string
//
// Translation will only occur if the assigned value is a different string type.
// Assigning a std::string to a CefStringUTF8, for example, will copy the data
// without performing a translation.
//
// CEF string classes are safe for reading from multiple threads but not for
// modification. It is the user's responsibility to provide synchronization if
// modifying CEF strings from multiple threads.
typedef CefStringBase<CefStringTraitsWide> CefStringWide;
typedef CefStringBase<CefStringTraitsUTF8> CefStringUTF8;
typedef CefStringBase<CefStringTraitsUTF16> CefStringUTF16;
#endif // _CEF_STRING_WRAPPERS_H