pEp_utility.cpp
author Thomas
Fri, 22 Nov 2019 09:35:43 +0100
branchsync
changeset 378 4e1795946472
parent 377 f3db78b86204
child 394 4076d056086c
permissions -rw-r--r--
Update hgignore
vb@10
     1
#include "stdafx.h"
vb@33
     2
#include "pEp_utility.h"
vb@33
     3
vb@33
     4
using namespace ATL;
vb@10
     5
vb@10
     6
namespace pEp {
vb@10
     7
    namespace utility {
vb@10
     8
        pEp_identity_cpp::pEp_identity_cpp(const ::pEp_identity *_ident)
vb@10
     9
        {
markus@269
    10
            if (!_ident)
markus@269
    11
                return;
vb@212
    12
vb@10
    13
            if (_ident->address)
vb@10
    14
                address = _ident->address;
vb@10
    15
            if (_ident->fpr)
vb@10
    16
                fpr = _ident->fpr;
vb@10
    17
            if (_ident->user_id)
vb@10
    18
                user_id = _ident->user_id;
vb@10
    19
            if (_ident->username)
vb@10
    20
                username = _ident->username;
markus@269
    21
            comm_type = (pEpComType)_ident->comm_type;
vb@10
    22
            lang = _ident->lang;
Thomas@377
    23
            me = _ident->me;
markus@269
    24
            flags = (int)_ident->flags;
vb@10
    25
        }
vb@10
    26
markus@172
    27
        pEp_identity_cpp::pEp_identity_cpp(const pEpIdentity *_ident)
vb@10
    28
        {
markus@269
    29
            if (!_ident)
markus@269
    30
                return;
vb@212
    31
markus@269
    32
            if (_ident->Address)
markus@180
    33
                address = utf8_string(_ident->Address);
markus@180
    34
            if (_ident->Fpr)
markus@180
    35
                fpr = utf8_string(_ident->Fpr);
markus@180
    36
            if (_ident->UserId)
markus@180
    37
                user_id = utf8_string(_ident->UserId);
markus@180
    38
            if (_ident->UserName)
markus@180
    39
                username = utf8_string(_ident->UserName);
markus@180
    40
            comm_type = _ident->CommType;
markus@180
    41
            if (_ident->Lang)
markus@180
    42
                lang = utf8_string(_ident->Lang);
Thomas@377
    43
            me = _ident->UserName;
markus@269
    44
            flags = (int)_ident->Flags;
vb@10
    45
        }
vb@10
    46
vb@10
    47
        pEp_identity * pEp_identity_cpp::to_pEp_identity()
vb@10
    48
        {
vb@10
    49
            ::pEp_identity *_ident = ::new_identity(this->address.c_str(), this->fpr.c_str(), this->user_id.c_str(), this->username.c_str());
vb@10
    50
            assert(_ident);
vb@10
    51
            if (_ident == NULL)
vb@10
    52
                throw bad_alloc();
vb@10
    53
vb@10
    54
            _ident->comm_type = (::PEP_comm_type) this->comm_type;
vb@10
    55
vb@10
    56
            assert(this->lang.size() == 0 || this->lang.size() == 2);
vb@10
    57
vb@10
    58
            if (this->lang.size()) {
vb@10
    59
                _ident->lang[0] = this->lang[0];
vb@10
    60
                _ident->lang[1] = this->lang[1];
vb@10
    61
            }
vb@10
    62
Thomas@377
    63
            _ident->me = this->me;
markus@269
    64
            _ident->flags = (identity_flags) this->flags;
vb@217
    65
vb@10
    66
            return _ident;
vb@10
    67
        }
vb@10
    68
markus@172
    69
        pEpIdentity * pEp_identity_cpp::to_pEp_identity_s()
vb@10
    70
        {
markus@269
    71
            pEpIdentity *_ident = (pEpIdentity *)calloc(1, sizeof(pEpIdentity));
vb@10
    72
            assert(_ident);
vb@10
    73
            if (_ident == NULL)
vb@10
    74
                throw bad_alloc();
vb@10
    75
markus@180
    76
            _ident->Address = utf16_bstr(this->address);
markus@180
    77
            _ident->CommType = this->comm_type;
markus@180
    78
            _ident->Fpr = utf16_bstr(this->fpr);
markus@180
    79
            _ident->Lang = utf16_bstr(this->lang);
markus@180
    80
            _ident->UserName = utf16_bstr(this->username);
markus@180
    81
            _ident->UserId = utf16_bstr(this->user_id);
Thomas@377
    82
            _ident->Me = this->me;
markus@269
    83
            _ident->Flags = (pEpIdentityFlags) this->flags;
vb@10
    84
vb@10
    85
            return _ident;
vb@10
    86
        }
vb@10
    87
markus@172
    88
        void copy_identity(pEpIdentity * ident_s, const pEp_identity * ident)
vb@10
    89
        {
vb@10
    90
            assert(ident_s);
markus@269
    91
            if (!ident_s)
markus@269
    92
                throw invalid_argument("ident_s");
vb@10
    93
markus@172
    94
            ::memset(ident_s, 0, sizeof(pEpIdentity));
vb@10
    95
            if (ident) {
vb@10
    96
                if (ident->address)
markus@180
    97
                    ident_s->Address = utf16_bstr(ident->address);
vb@10
    98
                if (ident->fpr)
markus@180
    99
                    ident_s->Fpr = utf16_bstr(ident->fpr);
vb@10
   100
                if (ident->user_id)
markus@180
   101
                    ident_s->UserId = utf16_bstr(ident->user_id);
vb@10
   102
                if (ident->username)
markus@180
   103
                    ident_s->UserName = utf16_bstr(ident->username);
markus@269
   104
                ident_s->CommType = (pEpComType)ident->comm_type;
vb@10
   105
                if (ident->lang)
markus@180
   106
                    ident_s->Lang = utf16_bstr(ident->lang);
Thomas@377
   107
                ident_s->Me = ident->me;
markus@269
   108
                ident_s->Flags = (pEpIdentityFlags)ident->flags;
vb@10
   109
            }
vb@10
   110
        }
vb@10
   111
markus@172
   112
        ::pEp_identity *new_identity(const pEpIdentity * ident)
vb@10
   113
        {
vb@37
   114
            if (ident == NULL)
vb@37
   115
                return NULL;
vb@37
   116
vb@10
   117
            ::pEp_identity *_ident;
vb@10
   118
vb@10
   119
            string _address;
vb@10
   120
            string _fpr;
vb@10
   121
            string _user_id;
vb@10
   122
            string _username;
vb@10
   123
markus@180
   124
            if (ident->Address)
markus@180
   125
                _address = utf8_string(ident->Address);
markus@180
   126
            if (ident->Fpr) {
markus@180
   127
                _fpr = utf8_string(ident->Fpr);
vb@10
   128
                for (auto p = _fpr.begin(); p != _fpr.end(); ++p) {
vb@10
   129
                    if (*p >= 'A' && *p <= 'Z')
vb@10
   130
                        continue;
vb@10
   131
                    if (*p >= '0' && *p <= '9')
vb@10
   132
                        continue;
vb@10
   133
                    throw invalid_argument("invalid hex digits in fingerprint");
vb@10
   134
                }
vb@10
   135
            }
markus@180
   136
            if (ident->UserId)
markus@180
   137
                _user_id = utf8_string(ident->UserId);
markus@180
   138
            if (ident->UserName)
markus@180
   139
                _username = utf8_string(ident->UserName);
vb@10
   140
vb@10
   141
            _ident = ::new_identity(_address.c_str(), _fpr.c_str(), _user_id.c_str(), _username.c_str());
vb@10
   142
            assert(_ident);
vb@10
   143
            if (_ident == NULL)
vb@10
   144
                throw bad_alloc();
vb@10
   145
markus@269
   146
            _ident->comm_type = (PEP_comm_type)ident->CommType;
vb@10
   147
markus@180
   148
            if (ident->Lang) {
markus@180
   149
                string _lang = utf8_string(ident->Lang);
vb@10
   150
                if (_lang.length() != 0) {
vb@10
   151
                    if (_lang.length() != 2) {
vb@10
   152
                        ::free_identity(_ident);
vb@10
   153
                        throw invalid_argument("invalid language code");
vb@10
   154
                    }
vb@10
   155
                    if (_lang[0] < 'a' || _lang[0] > 'z') {
vb@10
   156
                        ::free_identity(_ident);
vb@10
   157
                        throw invalid_argument("invalid language code");
vb@10
   158
                    }
vb@10
   159
                    if (_lang[1] < 'a' || _lang[1] > 'z') {
vb@10
   160
                        ::free_identity(_ident);
vb@10
   161
                        throw invalid_argument("invalid language code");
vb@10
   162
                    }
vb@10
   163
                    _ident->lang[0] = _lang[0];
vb@10
   164
                    _ident->lang[1] = _lang[1];
vb@10
   165
                }
vb@10
   166
            }
vb@10
   167
Thomas@377
   168
            _ident->me = ident->Me;
markus@269
   169
            _ident->flags = (identity_flags_t)ident->Flags;
vb@217
   170
vb@10
   171
            return _ident;
vb@10
   172
        }
vb@33
   173
vb@33
   174
        template< class T2, class T > T2 from_C(T *tl);
vb@33
   175
vb@41
   176
        BSTR bstr(char *s)
vb@33
   177
        {
vb@42
   178
            if (s == NULL)
vb@33
   179
                return _bstr_t(L"").Detach();
vb@42
   180
vb@42
   181
            return utf16_bstr(s);
vb@33
   182
        }
vb@33
   183
markus@172
   184
        template<> Blob *from_C< Blob *, bloblist_t >(bloblist_t *tl)
vb@33
   185
        {
markus@269
   186
            assert(tl);
vb@212
   187
vb@33
   188
            CComSafeArray<BYTE> sa;
markus@269
   189
            if (tl) {
markus@269
   190
                sa.Create(tl->size);
markus@269
   191
                if (tl->size) {
markus@269
   192
                    char *data;
markus@269
   193
                    SafeArrayAccessData(sa, (void **)&data);
markus@269
   194
                    memcpy(data, tl->value, tl->size);
markus@269
   195
                    SafeArrayUnaccessData(sa);
markus@269
   196
                }
markus@269
   197
            }
markus@269
   198
            else {
markus@269
   199
                sa.Create((ULONG)0);
markus@269
   200
            }
vb@33
   201
markus@172
   202
            Blob *_blob = new Blob();
vb@33
   203
vb@33
   204
            _blob->value = sa.Detach();
markus@180
   205
            _blob->MimeType = bstr(tl->mime_type);
markus@180
   206
            _blob->Filename = bstr(tl->filename);
vb@33
   207
vb@33
   208
            return _blob;
vb@33
   209
        }
vb@33
   210
vb@33
   211
        template< class T > int length(T *);
vb@33
   212
vb@33
   213
        template< class T2, class T > SAFEARRAY * array_from_C(T *tl)
vb@33
   214
        {
vb@39
   215
            if (tl == NULL)
vb@39
   216
                return newSafeArray<T2>(0);
vb@39
   217
vb@33
   218
            int len = length<T>(tl);
vb@33
   219
vb@33
   220
            LPSAFEARRAY sa = newSafeArray<T2>(len);
vb@33
   221
            LONG lbound, ubound;
vb@33
   222
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   223
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   224
vb@33
   225
            T *_tl = tl;
vb@302
   226
            for (LONG i = lbound; i <= ubound; _tl = _tl->next, i++) {
vb@302
   227
                HRESULT result = SafeArrayPutElement(sa, &i, from_C<T2 *, T>(_tl));
vb@302
   228
                if (!SUCCEEDED(result))
vb@302
   229
                    throw bad_alloc();
vb@302
   230
            }
vb@33
   231
vb@33
   232
            return sa;
vb@33
   233
        }
vb@33
   234
markus@172
   235
        void clear_identity_s(pEpIdentity& ident)
vb@41
   236
        {
markus@180
   237
            SysFreeString(ident.Address);
markus@180
   238
            SysFreeString(ident.Fpr);
markus@180
   239
            SysFreeString(ident.Lang);
markus@180
   240
            SysFreeString(ident.UserName);
markus@180
   241
            SysFreeString(ident.UserId);
vb@41
   242
markus@172
   243
            memset(&ident, 0, sizeof(pEpIdentity));
vb@41
   244
        }
vb@41
   245
markus@172
   246
        template<> pEpIdentity from_C< pEpIdentity, pEp_identity >(pEp_identity *tl)
vb@33
   247
        {
markus@172
   248
            pEpIdentity _ident;
vb@41
   249
            memset(&_ident, 0, sizeof(_ident));
vb@41
   250
vb@39
   251
            if (tl)
vb@39
   252
                copy_identity(&_ident, tl);
vb@33
   253
            return _ident;
vb@33
   254
        }
vb@33
   255
markus@172
   256
        pEpIdentity identity_s(pEp_identity *ident)
vb@33
   257
        {
markus@172
   258
            return from_C< pEpIdentity, pEp_identity >(ident);
vb@33
   259
        }
vb@33
   260
markus@172
   261
        template<> pEpIdentity *from_C< pEpIdentity *, identity_list >(identity_list *il)
vb@33
   262
        {
markus@172
   263
            pEpIdentity *ident = new pEpIdentity();
markus@172
   264
            memset(ident, 0, sizeof(pEpIdentity));
vb@41
   265
vb@39
   266
            if (il)
vb@39
   267
                copy_identity(ident, il->ident);
vb@33
   268
            return ident;
vb@33
   269
        }
vb@33
   270
markus@171
   271
        template<> StringPair *from_C< StringPair *, stringpair_list_t >(stringpair_list_t * sp)
vb@33
   272
        {
markus@171
   273
            StringPair *fld = new StringPair();
vb@39
   274
            if (sp) {
markus@180
   275
                fld->Name = bstr(sp->value->key);
markus@180
   276
                fld->Value = bstr(sp->value->value);
vb@39
   277
            }
vb@33
   278
            return fld;
vb@33
   279
        }
vb@33
   280
vb@33
   281
        template<> int length<identity_list>(identity_list *tl)
vb@33
   282
        {
vb@33
   283
            return identity_list_length(tl);
vb@33
   284
        }
vb@33
   285
vb@33
   286
        template<> int length<bloblist_t>(bloblist_t *tl)
vb@33
   287
        {
vb@33
   288
            return bloblist_length(tl);
vb@33
   289
        }
vb@33
   290
vb@33
   291
        template<> int length<stringpair_list_t>(stringpair_list_t *tl)
vb@33
   292
        {
vb@33
   293
            return stringpair_list_length(tl);
vb@33
   294
        }
vb@33
   295
markus@172
   296
        void clear_text_message(TextMessage *msg)
vb@41
   297
        {
markus@269
   298
            assert(msg);
markus@269
   299
            if (!msg)
markus@269
   300
                return;
vb@210
   301
markus@180
   302
            SysFreeString(msg->Id);
markus@182
   303
            SysFreeString(msg->ShortMsg);
markus@182
   304
            SysFreeString(msg->LongMsg);
markus@182
   305
            SysFreeString(msg->LongMsgFormatted);
markus@180
   306
            SafeArrayDestroy(msg->Attachments);
markus@180
   307
            clear_identity_s(msg->From);
markus@180
   308
            SafeArrayDestroy(msg->To);
markus@180
   309
            clear_identity_s(msg->RecvBy);
markus@180
   310
            SafeArrayDestroy(msg->Cc);
markus@180
   311
            SafeArrayDestroy(msg->Bcc);
markus@180
   312
            SafeArrayDestroy(msg->ReplyTo);
markus@180
   313
            SafeArrayDestroy(msg->References);
markus@180
   314
            SafeArrayDestroy(msg->Keywords);
markus@180
   315
            SysFreeString(msg->Comments);
markus@180
   316
            SafeArrayDestroy(msg->OptFields);
vb@41
   317
markus@172
   318
            memset(msg, 0, sizeof(TextMessage));
vb@41
   319
        }
vb@41
   320
markus@172
   321
        void text_message_from_C(TextMessage *msg2, const ::message *msg)
vb@33
   322
        {
vb@37
   323
            assert(msg2);
vb@33
   324
            assert(msg);
vb@33
   325
markus@269
   326
            if (!msg2) {
markus@269
   327
                msg2 = (TextMessage *)calloc(1, sizeof(TextMessage));
markus@269
   328
                assert(msg2);
markus@269
   329
                if (!msg2)
markus@269
   330
                    throw bad_alloc();
markus@269
   331
            }
markus@269
   332
            else {
markus@269
   333
                clear_text_message(msg2);
markus@269
   334
            }
vb@211
   335
markus@269
   336
            if (!msg)
markus@269
   337
                return;
vb@41
   338
markus@269
   339
            msg2->Dir = (pEpMsgDirection)msg->dir;
markus@180
   340
            msg2->Id = bstr(msg->id);
markus@182
   341
            msg2->ShortMsg = bstr(msg->shortmsg);
markus@182
   342
            msg2->LongMsg = bstr(msg->longmsg);
markus@182
   343
            msg2->LongMsgFormatted = bstr(msg->longmsg_formatted);
markus@180
   344
            msg2->Attachments = array_from_C<Blob, bloblist_t>(msg->attachments);
vb@39
   345
            if (msg->sent)
Thomas@324
   346
                msg2->Sent = _mkgmtime(msg->sent);
vb@39
   347
            if (msg->recv)
Thomas@324
   348
                msg2->Recv = _mkgmtime(msg->recv);
markus@180
   349
            msg2->From = identity_s(msg->from);
markus@180
   350
            msg2->To = array_from_C<pEpIdentity, identity_list>(msg->to);
markus@180
   351
            msg2->RecvBy = identity_s(msg->recv_by);
markus@180
   352
            msg2->Cc = array_from_C<pEpIdentity, identity_list>(msg->cc);
markus@180
   353
            msg2->Bcc = array_from_C<pEpIdentity, identity_list>(msg->bcc);
markus@180
   354
            msg2->ReplyTo = array_from_C<pEpIdentity, identity_list>(msg->reply_to);
markus@180
   355
            msg2->References = string_array(msg->references);
markus@180
   356
            msg2->Keywords = string_array(msg->keywords);
markus@180
   357
            msg2->Comments = bstr(msg->comments);
markus@180
   358
            msg2->OptFields = array_from_C<StringPair, stringpair_list_t>(msg->opt_fields);
Thomas@355
   359
            msg2->SenderFpr = bstr(msg->_sender_fpr);
vb@33
   360
        }
vb@33
   361
vb@37
   362
        char * str(BSTR s)
vb@33
   363
        {
vb@37
   364
            string str = utf8_string(s);
vb@37
   365
            char *_s = _strdup(str.c_str());
vb@33
   366
            if (_s == NULL)
vb@33
   367
                throw bad_alloc();
vb@33
   368
vb@37
   369
            return _s;
vb@33
   370
        }
vb@33
   371
markus@172
   372
        void clear_blob(Blob& b)
vb@41
   373
        {
markus@180
   374
            SysFreeString(b.Filename);
markus@180
   375
            SysFreeString(b.MimeType);
vb@41
   376
            SafeArrayDestroy(b.value);
markus@172
   377
            memset(&b, 0, sizeof(Blob));
vb@41
   378
        }
vb@41
   379
vb@33
   380
        bloblist_t *bloblist(SAFEARRAY *sa)
vb@33
   381
        {
vb@37
   382
            if (sa == NULL)
vb@37
   383
                return NULL;
vb@37
   384
vb@33
   385
            LONG lbound, ubound;
vb@33
   386
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   387
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   388
vb@33
   389
            size_t size = ubound - lbound + 1;
vb@33
   390
            if (size <= 0)
vb@33
   391
                return NULL;
vb@33
   392
vb@33
   393
            bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL);
vb@33
   394
            if (bl == NULL)
vb@33
   395
                throw bad_alloc();
vb@33
   396
vb@33
   397
            bloblist_t *_bl = bl;
vb@33
   398
            for (LONG i = lbound; i <= ubound; i++) {
markus@172
   399
                Blob b;
markus@172
   400
                memset(&b, 0, sizeof(Blob));
vb@33
   401
                SafeArrayGetElement(sa, &i, &b);
vb@33
   402
vb@38
   403
                LONG _lbound, _ubound;
vb@38
   404
                SafeArrayGetLBound(b.value, 1, &_lbound);
vb@38
   405
                SafeArrayGetUBound(b.value, 1, &_ubound);
vb@38
   406
                size_t size = _ubound - _lbound + 1;
vb@38
   407
vb@136
   408
                char *buffer;
vb@136
   409
                if (size) {
markus@269
   410
                    buffer = (char *)malloc(size + 1);
vb@136
   411
                    if (buffer == NULL)
vb@136
   412
                        throw bad_alloc();
vb@33
   413
vb@136
   414
                    char *data;
vb@33
   415
markus@269
   416
                    SafeArrayAccessData(b.value, (void **)&data);
vb@136
   417
                    memcpy(buffer, data, size);
markus@269
   418
                    buffer[size] = 0; // safeguard
vb@136
   419
                    SafeArrayUnaccessData(sa);
vb@136
   420
                }
vb@136
   421
                else {
vb@136
   422
                    buffer = _strdup("");
vb@136
   423
                    if (buffer == NULL)
vb@136
   424
                        throw bad_alloc();
vb@33
   425
vb@136
   426
                }
markus@180
   427
                _bl = bloblist_add(_bl, buffer, size, str(b.MimeType), str(b.Filename));
vb@33
   428
                if (_bl == NULL) {
vb@42
   429
                    free(buffer);
vb@41
   430
                    clear_blob(b);
vb@33
   431
                    free_bloblist(bl);
vb@33
   432
                    throw bad_alloc();
vb@33
   433
                }
vb@33
   434
vb@41
   435
                clear_blob(b);
vb@33
   436
            }
vb@33
   437
vb@33
   438
            return bl;
vb@33
   439
        }
vb@33
   440
vb@33
   441
        identity_list *identities(SAFEARRAY * sa)
vb@33
   442
        {
vb@37
   443
            if (sa == NULL)
vb@37
   444
                return NULL;
vb@37
   445
vb@33
   446
            LONG lbound, ubound;
vb@33
   447
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   448
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   449
vb@33
   450
            size_t size = ubound - lbound + 1;
vb@33
   451
            if (size <= 0)
vb@33
   452
                return NULL;
vb@33
   453
vb@33
   454
            identity_list *il = new_identity_list(NULL);
vb@33
   455
vb@33
   456
            identity_list *_il = il;
vb@33
   457
            for (LONG i = lbound; i <= ubound; i++) {
markus@172
   458
                pEpIdentity s;
markus@172
   459
                memset(&s, 0, sizeof(pEpIdentity));
vb@33
   460
                SafeArrayGetElement(sa, &i, &s);
vb@33
   461
vb@33
   462
                pEp_identity *ident;
vb@33
   463
                try {
vb@33
   464
                    ident = new_identity(&s);
vb@33
   465
                }
vb@33
   466
                catch (bad_alloc&) {
vb@41
   467
                    clear_identity_s(s);
vb@33
   468
                    throw bad_alloc();
vb@33
   469
                }
vb@33
   470
vb@41
   471
                clear_identity_s(s);
vb@33
   472
vb@33
   473
                _il = identity_list_add(_il, ident);
vb@33
   474
                if (_il == NULL) {
vb@33
   475
                    free_identity_list(il);
vb@33
   476
                    throw bad_alloc();
vb@33
   477
                }
vb@33
   478
            }
vb@33
   479
vb@33
   480
            return il;
vb@33
   481
        }
vb@33
   482
markus@171
   483
        stringpair_t *new_stringpair(StringPair *fld)
vb@33
   484
        {
markus@269
   485
            stringpair_t *pair;
vb@212
   486
markus@269
   487
            if (!fld) {
markus@269
   488
                pair = ::new_stringpair(NULL, NULL);
markus@269
   489
            }
markus@269
   490
            else {
markus@269
   491
                pair = ::new_stringpair(str(fld->Name), str(fld->Value));
markus@269
   492
            }
vb@33
   493
            if (pair == NULL)
vb@33
   494
                throw bad_alloc();
vb@33
   495
vb@33
   496
            return pair;
vb@33
   497
        }
vb@33
   498
markus@171
   499
        void clear_opt_field(StringPair& f)
vb@41
   500
        {
markus@180
   501
            SysFreeString(f.Name);
markus@180
   502
            SysFreeString(f.Value);
markus@171
   503
            memset(&f, 0, sizeof(StringPair));
vb@41
   504
        }
vb@41
   505
vb@33
   506
        stringpair_list_t *stringpair_list(SAFEARRAY * sa)
vb@33
   507
        {
vb@37
   508
            if (sa == NULL)
vb@37
   509
                return NULL;
vb@37
   510
vb@33
   511
            LONG lbound, ubound;
vb@33
   512
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   513
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   514
vb@33
   515
            size_t size = ubound - lbound + 1;
vb@33
   516
            if (size <= 0)
vb@33
   517
                return NULL;
vb@33
   518
vb@33
   519
            stringpair_list_t *il = new_stringpair_list(NULL);
vb@33
   520
vb@33
   521
            stringpair_list_t *_il = il;
vb@33
   522
            for (LONG i = lbound; i <= ubound; i++) {
markus@171
   523
                StringPair s;
markus@171
   524
                memset(&s, 0, sizeof(StringPair));
vb@33
   525
                SafeArrayGetElement(sa, &i, &s);
vb@33
   526
vb@33
   527
                stringpair_t *pair;
vb@33
   528
                try {
vb@33
   529
                    pair = new_stringpair(&s);
vb@33
   530
                }
vb@33
   531
                catch (bad_alloc&) {
vb@41
   532
                    clear_opt_field(s);
vb@33
   533
                    throw bad_alloc();
vb@33
   534
                }
vb@33
   535
vb@41
   536
                clear_opt_field(s);
vb@33
   537
vb@33
   538
                _il = stringpair_list_add(_il, pair);
vb@33
   539
                if (_il == NULL) {
vb@33
   540
                    free_stringpair_list(il);
vb@33
   541
                    throw bad_alloc();
vb@33
   542
                }
vb@33
   543
            }
vb@33
   544
vb@33
   545
            return il;
vb@33
   546
        }
markus@269
   547
markus@172
   548
        ::message * text_message_to_C(TextMessage *msg)
vb@33
   549
        {
vb@33
   550
            assert(msg);
markus@269
   551
            if (!msg)
markus@269
   552
                throw invalid_argument("msg");
vb@33
   553
markus@269
   554
            ::message * msg2 = new_message((PEP_msg_direction)msg->Dir);
vb@37
   555
            if (msg2 == NULL)
vb@37
   556
                throw bad_alloc();
vb@33
   557
markus@180
   558
            msg2->id = str(msg->Id);
markus@182
   559
            msg2->shortmsg = str(msg->ShortMsg);
markus@182
   560
            msg2->longmsg = str(msg->LongMsg);
markus@182
   561
            msg2->longmsg_formatted = str(msg->LongMsgFormatted);
markus@180
   562
            msg2->attachments = bloblist(msg->Attachments);
markus@180
   563
            msg2->sent = new_timestamp(msg->Sent);
markus@180
   564
            msg2->recv = new_timestamp(msg->Recv);
markus@180
   565
            msg2->from = new_identity(&msg->From);
markus@180
   566
            msg2->to = identities(msg->To);
markus@180
   567
            msg2->recv_by = new_identity(&msg->RecvBy);
markus@180
   568
            msg2->cc = identities(msg->Cc);
markus@180
   569
            msg2->bcc = identities(msg->Bcc);
markus@180
   570
            msg2->reply_to = identities(msg->ReplyTo);
markus@180
   571
            msg2->references = new_stringlist(msg->References);
markus@180
   572
            msg2->keywords = new_stringlist(msg->Keywords);
markus@180
   573
            msg2->comments = str(msg->Comments);
markus@180
   574
            msg2->opt_fields = stringpair_list(msg->OptFields);
vb@33
   575
vb@33
   576
            return msg2;
vb@33
   577
        }
markus@177
   578
markus@269
   579
        void opt_field_array_from_C(stringpair_list_t* spair_list, LPSAFEARRAY* pair_list_out) {
markus@269
   580
            assert(spair_list);
markus@269
   581
            assert(pair_list_out);
krista@157
   582
markus@269
   583
            if (!spair_list)
markus@269
   584
                return;
markus@177
   585
markus@269
   586
            *pair_list_out = array_from_C<StringPair, stringpair_list_t>(spair_list);
markus@269
   587
        }
markus@269
   588
markus@269
   589
        void clear_opt_field_array(LPSAFEARRAY* opt_field_array) {
markus@269
   590
            if (opt_field_array) {
markus@269
   591
                SafeArrayDestroy(*opt_field_array);
markus@269
   592
                *opt_field_array = NULL;
markus@269
   593
            }
markus@269
   594
        }
vb@10
   595
    }
vb@10
   596
}