#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
#define CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_
#pragma once
#include <memory.h>
#include <string>
#include "include/internal/cef_string_types.h"
#if defined(USING_CHROMIUM_INCLUDES)
#include "base/files/file_path.h"
#endif
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);
}
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf8_to_wide(data, length, s) ? true : false;
}
static inline bool from_string(const std::string& str, struct_type* s) {
return from_string(str.data(), str.length(), s);
}
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_wide_set(data, length, s, true) ? true : false;
}
static inline bool from_wstring(const std::wstring& str, struct_type* s) {
return from_wstring(str.data(), str.length(), s);
}
#if defined(WCHAR_T_IS_UTF32)
static inline std::u16string 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);
std::u16string str;
if (cstr.length > 0) {
str = std::u16string(
reinterpret_cast<std::u16string::value_type*>(cstr.str), cstr.length);
}
cef_string_utf16_clear(&cstr);
return str;
}
static inline bool from_string16(const std::u16string::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf16_to_wide(reinterpret_cast<const char16*>(data),
length, s)
? true
: false;
}
#else
static inline std::u16string to_string16(const struct_type* s) {
return std::u16string(
reinterpret_cast<const std::u16string::value_type*>(s->str), s->length);
}
static inline bool from_string16(const std::u16string::value_type* data,
size_t length,
struct_type* s) {
return cef_string_wide_set(reinterpret_cast<const wchar_t*>(data), length,
s, true)
? true
: false;
}
#endif
static inline bool from_string16(const std::u16string& str, struct_type* s) {
return from_string16(str.data(), str.length(), s);
}
};
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);
}
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf8_copy(data, length, s) ? true : false;
}
static inline bool from_string(const std::string& str, struct_type* s) {
return from_string(str.c_str(), str.length(), s);
}
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_wide_to_utf8(data, length, s) ? true : false;
}
static inline bool from_wstring(const std::wstring& str, struct_type* s) {
return from_wstring(str.data(), str.length(), s);
}
static inline std::u16string 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);
std::u16string str;
if (cstr.length > 0) {
str = std::u16string(
reinterpret_cast<std::u16string::value_type*>(cstr.str), cstr.length);
}
cef_string_utf16_clear(&cstr);
return str;
}
static inline bool from_string16(const std::u16string::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf16_to_utf8(reinterpret_cast<const char16*>(data),
length, s)
? true
: false;
}
static inline bool from_string16(const std::u16string& str, struct_type* s) {
return from_string16(str.data(), str.length(), s);
}
};
struct CefStringTraitsUTF16 {
typedef char16 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);
}
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf8_to_utf16(data, length, s) ? true : false;
}
static inline bool from_string(const std::string& str, struct_type* s) {
return from_string(str.data(), str.length(), s);
}
#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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_wide_to_utf16(data, length, s) ? true : false;
}
#else
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::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf16_set(data, length, s, true) ? true : false;
}
#endif
static inline bool from_wstring(const std::wstring& str, struct_type* s) {
return from_wstring(str.data(), str.length(), s);
}
static inline std::u16string to_string16(const struct_type* s) {
return std::u16string(
reinterpret_cast<const std::u16string::value_type*>(s->str), s->length);
}
static inline bool from_string16(const std::u16string::value_type* data,
size_t length,
struct_type* s) {
return cef_string_utf16_set(reinterpret_cast<const char16*>(data), length,
s, true)
? true
: false;
}
static inline bool from_string16(const std::u16string& str, struct_type* s) {
return from_string16(str.data(), str.length(), s);
}
};
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;
CefStringBase() : string_(NULL), owner_(false) {}
CefStringBase(const CefStringBase& str) : string_(NULL), owner_(false) {
FromString(str.c_str(), str.length(), true);
}
CefStringBase(const std::string& src) : string_(NULL), owner_(false) {
FromString(src);
}
CefStringBase(const char* src, size_t length = 0)
: string_(NULL), owner_(false) {
if (src)
FromString(src, length);
}
CefStringBase(const std::wstring& src) : string_(NULL), owner_(false) {
FromWString(src);
}
CefStringBase(const wchar_t* src, size_t length = 0)
: string_(NULL), owner_(false) {
if (src)
FromWString(src, length);
}
CefStringBase(const std::u16string& src) : string_(NULL), owner_(false) {
FromString16(src);
}
CefStringBase(const std::u16string::value_type* src, size_t length = 0)
: string_(NULL), owner_(false) {
if (src)
FromString16(src, length);
}
#if defined(WCHAR_T_IS_UTF32)
CefStringBase(const char16* src, size_t length = 0)
: string_(NULL), owner_(false) {
if (src) {
FromString16(reinterpret_cast<const std::u16string::value_type*>(src),
length);
}
}
#endif
CefStringBase(const char_type* src, size_t src_len, bool copy)
: string_(NULL), owner_(false) {
if (src && src_len > 0)
FromString(src, src_len, copy);
}
CefStringBase(const struct_type* src) : string_(NULL), owner_(false) {
if (!src)
return;
Attach(const_cast<struct_type*>(src), false);
}
virtual ~CefStringBase() { ClearAndFree(); }
const char_type* c_str() const { return (string_ ? string_->str : NULL); }
size_t length() const { return (string_ ? string_->length : 0); }
inline size_t size() const { return length(); }
bool empty() const { return (string_ == NULL || string_->length == 0); }
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());
}
void clear() {
if (string_)
traits::clear(string_);
}
void swap(CefStringBase& str) {
struct_type* tmp_string = string_;
bool tmp_owner = owner_;
string_ = str.string_;
owner_ = str.owner_;
str.string_ = tmp_string;
str.owner_ = tmp_owner;
}
bool IsOwner() const { return owner_; }
const struct_type* GetStruct() const { return string_; }
struct_type* GetWritableStruct() {
AllocIfNeeded();
return string_;
}
void ClearAndFree() {
if (!string_)
return;
if (owner_) {
clear();
delete string_;
}
string_ = NULL;
owner_ = false;
}
void Attach(struct_type* str, bool owner) {
ClearAndFree();
string_ = str;
owner_ = owner;
}
void AttachToUserFree(userfree_struct_type str) {
ClearAndFree();
if (!str)
return;
AllocIfNeeded();
owner_ = true;
memcpy(string_, str, sizeof(struct_type));
memset(str, 0, sizeof(struct_type));
traits::userfree_free(str);
}
void Detach() {
string_ = NULL;
owner_ = false;
}
userfree_struct_type DetachToUserFree() {
if (empty())
return NULL;
userfree_struct_type str = traits::userfree_alloc();
memcpy(str, string_, sizeof(struct_type));
memset(string_, 0, sizeof(struct_type));
ClearAndFree();
return str;
}
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;
}
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_);
}
std::string ToString() const {
if (empty())
return std::string();
return traits::to_string(string_);
}
bool FromString(const std::string& str) {
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string(str, string_);
}
bool FromString(const std::string::value_type* data, size_t length = 0) {
if (data && length == 0) {
length = std::char_traits<std::string::value_type>::length(data);
}
if (!data || length == 0) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string(data, length, string_);
}
std::wstring ToWString() const {
if (empty())
return std::wstring();
return traits::to_wstring(string_);
}
bool FromWString(const std::wstring& str) {
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_wstring(str, string_);
}
bool FromWString(const std::wstring::value_type* data, size_t length = 0) {
if (data && length == 0) {
length = std::char_traits<std::wstring::value_type>::length(data);
}
if (!data || length == 0) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_wstring(data, length, string_);
}
std::u16string ToString16() const {
if (empty())
return std::u16string();
return traits::to_string16(string_);
}
bool FromString16(const std::u16string& str) {
if (str.empty()) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string16(str, string_);
}
bool FromString16(const std::u16string::value_type* data, size_t length = 0) {
if (data && length == 0) {
length = std::char_traits<std::u16string::value_type>::length(data);
}
if (!data || length == 0) {
clear();
return true;
}
AllocIfNeeded();
return traits::from_string16(data, length, string_);
}
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);
}
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 std::string::value_type* str) {
FromString(str);
return *this;
}
operator std::wstring() const { return ToWString(); }
CefStringBase& operator=(const std::wstring& str) {
FromWString(str);
return *this;
}
CefStringBase& operator=(const std::wstring::value_type* str) {
FromWString(str);
return *this;
}
operator std::u16string() const { return ToString16(); }
CefStringBase& operator=(const std::u16string& str) {
FromString16(str);
return *this;
}
CefStringBase& operator=(const std::u16string::value_type* str) {
FromString16(str);
return *this;
}
#if defined(WCHAR_T_IS_UTF32)
CefStringBase& operator=(const char16* str) {
FromString16(reinterpret_cast<const std::u16string::value_type*>(str));
return *this;
}
#endif
#if defined(USING_CHROMIUM_INCLUDES)
operator base::FilePath() const {
#if defined(OS_WIN)
return base::FilePath(ToWString());
#else
return base::FilePath(ToString());
#endif
}
#endif
private:
void AllocIfNeeded() {
if (string_ == NULL) {
string_ = new struct_type;
memset(string_, 0, sizeof(struct_type));
owner_ = true;
}
}
struct_type* string_;
bool owner_;
};
typedef CefStringBase<CefStringTraitsWide> CefStringWide;
typedef CefStringBase<CefStringTraitsUTF8> CefStringUTF8;
typedef CefStringBase<CefStringTraitsUTF16> CefStringUTF16;
#endif