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