utf8_helper.cpp
author Volker Birk <vb@pep-project.org>
Sun, 31 May 2015 18:26:37 +0200
changeset 38 d314ed57180c
parent 37 863fc3ccd19d
child 39 6fc5cc7a167c
permissions -rw-r--r--
fixes
     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                 throw out_of_range("input wstring is not valid while converting UTF-16 to UTF-8.");
    43 
    44             return result;
    45         }
    46 
    47         string utf8_string(BSTR bstr, NORM_FORM norm)
    48         {
    49             if (bstr == NULL)
    50                 return "";
    51 
    52             return utf8_string((wstring) (wchar_t *) _bstr_t(bstr, true), norm);
    53         }
    54 
    55         wstring utf16_string(string str)
    56         {
    57             if (str.size() == 0)
    58                 return wstring();
    59 
    60             wstring result;
    61 
    62             int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, NULL, 0);
    63             assert(size);
    64             if (size) {
    65                 wchar_t * buf = new wchar_t[size];
    66                 MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, buf, size);
    67                 result = buf;
    68                 delete[] buf;
    69             }
    70             else
    71                 throw out_of_range("input string is not valid while converting UTF-8 to UTF-16.");
    72 
    73             return result;
    74         }
    75 
    76         _bstr_t utf16_bstr(string str)
    77         {
    78             return _bstr_t(utf16_string(str).c_str());
    79         }
    80 
    81         CComSafeArray<BSTR> string_array(const ::stringlist_t *stringlist)
    82         {
    83             int len = ::stringlist_length(stringlist);
    84 
    85             if (len = 0)
    86                 return CComSafeArray<BSTR>((ULONG)0);
    87 
    88             CComSafeArray<BSTR> sa_string_list((LONG) len);
    89             LONG n = 0;
    90             for (const ::stringlist_t *k = stringlist; k && k->value; k = k->next) {
    91                 if (k->value) {
    92                     HRESULT _result = sa_string_list.SetAt(n, utf16_bstr(k->value).Detach(), false);
    93                     assert(_result == S_OK);
    94                     if (_result == E_OUTOFMEMORY)
    95                         throw std::bad_alloc();
    96                     ++n;
    97                 }
    98             }
    99 
   100             return sa_string_list;
   101         }
   102 
   103         ::stringlist_t * new_stringlist(const SAFEARRAY * safearray)
   104         {
   105             if (safearray == NULL)
   106                 return NULL;
   107 
   108             CComSafeArray<BSTR> sa(safearray);
   109             int n_strings = 0;
   110             ::stringlist_t *_stringlist = ::new_stringlist((const char *) NULL);
   111             assert(_stringlist);
   112             if (_stringlist == NULL)
   113                 throw std::bad_alloc();
   114 
   115             n_strings = sa.GetUpperBound() - sa.GetLowerBound() + 1;
   116             ::stringlist_t *k = _stringlist;
   117             for (int i = 0, j = sa.GetLowerBound(); i < n_strings; ++i, ++j) {
   118                 k = ::stringlist_add(k, utf8_string(sa.GetAt(j)).c_str());
   119                 assert(k);
   120                 if (k == NULL) {
   121                     ::free_stringlist(_stringlist);
   122                     throw std::bad_alloc();
   123                 }
   124             }
   125 
   126             return _stringlist;
   127         }
   128 
   129     }
   130 }