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