utf8_helper.cpp
author Thomas
Thu, 29 Oct 2020 08:09:08 +0100
changeset 461 c3d9c7751b05
parent 369 2d02d1fc2218
permissions -rw-r--r--
Move test key file to relevant project
     1 #include "stdafx.h"
     2 #include "utf8_helper.h"
     3 
     4 using namespace ATL;
     5 using namespace std;
     6 
     7 namespace pEp {
     8     namespace utility {
     9 
    10         string utf8_string(wstring wstr, NORM_FORM norm)
    11         {
    12             if (wstr.size() == 0)
    13                 return string();
    14 
    15             wstring _wstr_normalized;
    16 
    17             if (norm == NormalizationOther)
    18                 _wstr_normalized = wstr;
    19             else {
    20                 int size = NormalizeString(norm, wstr.c_str(), -1, NULL, 0);
    21                 assert(size > 0);
    22                 if (size > 0) {
    23                     wchar_t *buf = new wchar_t[size];
    24                     NormalizeString(norm, wstr.c_str(), -1, buf, size);
    25                     _wstr_normalized = buf;
    26                     delete[] buf;
    27                 }
    28                 else
    29                     throw out_of_range("input wstring is not valid while normalizing.");
    30             }
    31             string result;
    32 
    33             int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, _wstr_normalized.c_str(), -1, NULL, 0, NULL, NULL);
    34             assert(size);
    35             if (size) {
    36                 char *buf = new char[size];
    37                 WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, _wstr_normalized.c_str(), -1, buf, size, NULL, NULL);
    38                 result = buf;
    39                 delete[] buf;
    40             }
    41             else {
    42                 DWORD error = GetLastError();
    43                 throw out_of_range("input wstring is not valid while converting UTF-16 to UTF-8. Error" + error);
    44             }
    45 
    46             return result;
    47         }
    48 
    49         string utf8_string(BSTR bstr, NORM_FORM norm)
    50         {
    51             if (bstr == NULL)
    52                 return "";
    53 
    54             _bstr_t _bstr(bstr);
    55             wstring wstr = (wchar_t *)_bstr;
    56             _bstr.Detach();
    57 
    58             return utf8_string(wstr, norm);
    59         }
    60 
    61         wstring utf16_string(string str)
    62         {
    63             if (str.size() == 0)
    64                 return wstring();
    65 
    66             wstring result;
    67 
    68             int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, NULL, 0);
    69             assert(size);
    70             if (size) {
    71                 wchar_t * buf = new wchar_t[size];
    72                 MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, buf, size);
    73                 result = buf;
    74                 delete[] buf;
    75             }
    76             else
    77                 throw out_of_range("input string is not valid while converting UTF-8 to UTF-16.");
    78 
    79             return result;
    80         }
    81 
    82         BSTR utf16_bstr(string str)
    83         {
    84             wstring wstr = utf16_string(str);
    85             return _bstr_t(wstr.c_str()).Detach();
    86         }
    87 
    88         LPSAFEARRAY string_array(const ::stringlist_t *stringlist)
    89         {
    90             int len = ::stringlist_length(stringlist);
    91 
    92             if (len == 0)
    93                 return NULL;
    94 
    95             CComSafeArray<BSTR> sa_string_list((LONG)len);
    96             LONG n = 0;
    97             for (const ::stringlist_t *k = stringlist; k && k->value; k = k->next) {
    98                 if (k->value) {
    99                     HRESULT _result = sa_string_list.SetAt(n, utf16_bstr(k->value), false);
   100                     assert(_result == S_OK);
   101                     if (_result == E_OUTOFMEMORY)
   102                         throw std::bad_alloc();
   103                     ++n;
   104                 }
   105             }
   106 
   107             return sa_string_list.Detach();
   108         }
   109 
   110         ::stringlist_t * new_stringlist(const SAFEARRAY * safearray)
   111         {
   112             if (safearray == NULL)
   113                 return NULL;
   114 
   115             CComSafeArray<BSTR> sa(safearray);
   116             int n_strings = 0;
   117             ::stringlist_t *_stringlist = ::new_stringlist((const char *)NULL);
   118             assert(_stringlist);
   119             if (_stringlist == NULL)
   120                 throw std::bad_alloc();
   121 
   122             n_strings = sa.GetUpperBound() - sa.GetLowerBound() + 1;
   123             ::stringlist_t *k = _stringlist;
   124             for (int i = 0, j = sa.GetLowerBound(); i < n_strings; ++i, ++j) {
   125                 k = ::stringlist_add(k, utf8_string(sa.GetAt(j)).c_str());
   126                 assert(k);
   127                 if (k == NULL) {
   128                     ::free_stringlist(_stringlist);
   129                     throw std::bad_alloc();
   130                 }
   131             }
   132 
   133             return _stringlist;
   134         }
   135 
   136     }
   137 }