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