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
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@38
    83
            int len = ::stringlist_length(stringlist);
vb@38
    84
vb@38
    85
            if (len = 0)
vb@37
    86
                return CComSafeArray<BSTR>((ULONG)0);
vb@37
    87
vb@38
    88
            CComSafeArray<BSTR> sa_string_list((LONG) len);
vb@38
    89
            LONG n = 0;
vb@38
    90
            for (const ::stringlist_t *k = stringlist; k && k->value; k = k->next) {
vb@10
    91
                if (k->value) {
vb@38
    92
                    HRESULT _result = sa_string_list.SetAt(n, utf16_bstr(k->value).Detach(), false);
vb@10
    93
                    assert(_result == S_OK);
vb@10
    94
                    if (_result == E_OUTOFMEMORY)
vb@10
    95
                        throw std::bad_alloc();
vb@10
    96
                    ++n;
vb@10
    97
                }
vb@10
    98
            }
vb@10
    99
vb@10
   100
            return sa_string_list;
vb@10
   101
        }
vb@10
   102
vb@10
   103
        ::stringlist_t * new_stringlist(const SAFEARRAY * safearray)
vb@10
   104
        {
vb@37
   105
            if (safearray == NULL)
vb@37
   106
                return NULL;
vb@37
   107
vb@10
   108
            CComSafeArray<BSTR> sa(safearray);
vb@10
   109
            int n_strings = 0;
vb@10
   110
            ::stringlist_t *_stringlist = ::new_stringlist((const char *) NULL);
vb@10
   111
            assert(_stringlist);
vb@10
   112
            if (_stringlist == NULL)
vb@10
   113
                throw std::bad_alloc();
vb@10
   114
vb@10
   115
            n_strings = sa.GetUpperBound() - sa.GetLowerBound() + 1;
vb@10
   116
            ::stringlist_t *k = _stringlist;
vb@10
   117
            for (int i = 0, j = sa.GetLowerBound(); i < n_strings; ++i, ++j) {
vb@10
   118
                k = ::stringlist_add(k, utf8_string(sa.GetAt(j)).c_str());
vb@10
   119
                assert(k);
vb@10
   120
                if (k == NULL) {
vb@10
   121
                    ::free_stringlist(_stringlist);
vb@10
   122
                    throw std::bad_alloc();
vb@10
   123
                }
vb@10
   124
            }
vb@10
   125
vb@10
   126
            return _stringlist;
vb@10
   127
        }
vb@10
   128
vb@10
   129
    }
vb@10
   130
}