p≡p COM server adapter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

137 lines
4.2 KiB

#include "stdafx.h"
#include "utf8_helper.h"
using namespace ATL;
using namespace std;
namespace pEp {
namespace utility {
string utf8_string(wstring wstr, NORM_FORM norm)
{
if (wstr.size() == 0)
return string();
wstring _wstr_normalized;
if (norm == NormalizationOther)
_wstr_normalized = wstr;
else {
int size = NormalizeString(norm, wstr.c_str(), -1, NULL, 0);
assert(size > 0);
if (size > 0) {
wchar_t *buf = new wchar_t[size];
NormalizeString(norm, wstr.c_str(), -1, buf, size);
_wstr_normalized = buf;
delete[] buf;
}
else
throw out_of_range("input wstring is not valid while normalizing.");
}
string result;
int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, _wstr_normalized.c_str(), -1, NULL, 0, NULL, NULL);
assert(size);
if (size) {
char *buf = new char[size];
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, _wstr_normalized.c_str(), -1, buf, size, NULL, NULL);
result = buf;
delete[] buf;
}
else {
DWORD error = GetLastError();
throw out_of_range("input wstring is not valid while converting UTF-16 to UTF-8. Error" + error);
}
return result;
}
string utf8_string(BSTR bstr, NORM_FORM norm)
{
if (bstr == NULL)
return "";
_bstr_t _bstr(bstr);
wstring wstr = (wchar_t *)_bstr;
_bstr.Detach();
return utf8_string(wstr, norm);
}
wstring utf16_string(string str)
{
if (str.size() == 0)
return wstring();
wstring result;
int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, NULL, 0);
assert(size);
if (size) {
wchar_t * buf = new wchar_t[size];
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, buf, size);
result = buf;
delete[] buf;
}
else
throw out_of_range("input string is not valid while converting UTF-8 to UTF-16.");
return result;
}
BSTR utf16_bstr(string str)
{
wstring wstr = utf16_string(str);
return _bstr_t(wstr.c_str()).Detach();
}
LPSAFEARRAY string_array(const ::stringlist_t *stringlist)
{
int len = ::stringlist_length(stringlist);
if (len == 0)
return NULL;
CComSafeArray<BSTR> sa_string_list((LONG)len);
LONG n = 0;
for (const ::stringlist_t *k = stringlist; k && k->value; k = k->next) {
if (k->value) {
HRESULT _result = sa_string_list.SetAt(n, utf16_bstr(k->value), false);
assert(_result == S_OK);
if (_result == E_OUTOFMEMORY)
throw std::bad_alloc();
++n;
}
}
return sa_string_list.Detach();
}
::stringlist_t * new_stringlist(const SAFEARRAY * safearray)
{
if (safearray == NULL)
return NULL;
CComSafeArray<BSTR> sa(safearray);
int n_strings = 0;
::stringlist_t *_stringlist = ::new_stringlist((const char *)NULL);
assert(_stringlist);
if (_stringlist == NULL)
throw std::bad_alloc();
n_strings = sa.GetUpperBound() - sa.GetLowerBound() + 1;
::stringlist_t *k = _stringlist;
for (int i = 0, j = sa.GetLowerBound(); i < n_strings; ++i, ++j) {
k = ::stringlist_add(k, utf8_string(sa.GetAt(j)).c_str());
assert(k);
if (k == NULL) {
::free_stringlist(_stringlist);
throw std::bad_alloc();
}
}
return _stringlist;
}
}
}