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