pEp_utility.cpp
author Markus Schaber <markus@pep-security.net>
Wed, 14 Jun 2017 23:46:37 +0200
branchCOM-54-ENGINE-9
changeset 251 ded328cde93f
parent 224 b0290a75f7a5
permissions -rw-r--r--
COM-54: Attachment Blob CID Support
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@212
    11
			if (!_ident)
vb@212
    12
				return;
vb@212
    13
vb@10
    14
            if (_ident->address)
vb@10
    15
                address = _ident->address;
vb@10
    16
            if (_ident->fpr)
vb@10
    17
                fpr = _ident->fpr;
vb@10
    18
            if (_ident->user_id)
vb@10
    19
                user_id = _ident->user_id;
vb@10
    20
            if (_ident->username)
vb@10
    21
                username = _ident->username;
markus@172
    22
            comm_type = (pEpComType) _ident->comm_type;
vb@10
    23
            lang = _ident->lang;
vb@217
    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
            : me(false)
vb@10
    29
        {
vb@212
    30
			if (!_ident)
vb@212
    31
				return;
vb@212
    32
vb@212
    33
			if (_ident->Address)
markus@180
    34
                address = utf8_string(_ident->Address);
markus@180
    35
            if (_ident->Fpr)
markus@180
    36
                fpr = utf8_string(_ident->Fpr);
markus@180
    37
            if (_ident->UserId)
markus@180
    38
                user_id = utf8_string(_ident->UserId);
markus@180
    39
            if (_ident->UserName)
markus@180
    40
                username = utf8_string(_ident->UserName);
markus@180
    41
            comm_type = _ident->CommType;
markus@180
    42
            if (_ident->Lang)
markus@180
    43
                lang = utf8_string(_ident->Lang);
vb@217
    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
            _ident->me = this->me;
vb@10
    56
vb@10
    57
            assert(this->lang.size() == 0 || this->lang.size() == 2);
vb@10
    58
vb@10
    59
            if (this->lang.size()) {
vb@10
    60
                _ident->lang[0] = this->lang[0];
vb@10
    61
                _ident->lang[1] = this->lang[1];
vb@10
    62
            }
vb@10
    63
vb@217
    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@172
    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);
vb@219
    82
			_ident->Flags = (pEpIdentityFlags) this->flags;
vb@10
    83
vb@10
    84
            return _ident;
vb@10
    85
        }
vb@10
    86
markus@172
    87
        void copy_identity(pEpIdentity * ident_s, const pEp_identity * ident)
vb@10
    88
        {
vb@10
    89
            assert(ident_s);
vb@212
    90
			if (!ident_s)
vb@212
    91
				throw invalid_argument("ident_s");
vb@10
    92
markus@172
    93
            ::memset(ident_s, 0, sizeof(pEpIdentity));
vb@10
    94
            if (ident) {
vb@10
    95
                if (ident->address)
markus@180
    96
                    ident_s->Address = utf16_bstr(ident->address);
vb@10
    97
                if (ident->fpr)
markus@180
    98
                    ident_s->Fpr = utf16_bstr(ident->fpr);
vb@10
    99
                if (ident->user_id)
markus@180
   100
                    ident_s->UserId = utf16_bstr(ident->user_id);
vb@10
   101
                if (ident->username)
markus@180
   102
                    ident_s->UserName = utf16_bstr(ident->username);
markus@180
   103
                ident_s->CommType = (pEpComType) ident->comm_type;
vb@10
   104
                if (ident->lang)
markus@180
   105
                    ident_s->Lang = utf16_bstr(ident->lang);
vb@219
   106
				ident_s->Flags = (pEpIdentityFlags) ident->flags;
vb@10
   107
            }
vb@10
   108
        }
vb@10
   109
markus@172
   110
        ::pEp_identity *new_identity(const pEpIdentity * ident)
vb@10
   111
        {
vb@37
   112
            if (ident == NULL)
vb@37
   113
                return NULL;
vb@37
   114
vb@10
   115
            ::pEp_identity *_ident;
vb@10
   116
vb@10
   117
            string _address;
vb@10
   118
            string _fpr;
vb@10
   119
            string _user_id;
vb@10
   120
            string _username;
vb@10
   121
markus@180
   122
            if (ident->Address)
markus@180
   123
                _address = utf8_string(ident->Address);
markus@180
   124
            if (ident->Fpr) {
markus@180
   125
                _fpr = utf8_string(ident->Fpr);
vb@10
   126
                for (auto p = _fpr.begin(); p != _fpr.end(); ++p) {
vb@10
   127
                    if (*p >= 'A' && *p <= 'Z')
vb@10
   128
                        continue;
vb@10
   129
                    if (*p >= '0' && *p <= '9')
vb@10
   130
                        continue;
vb@10
   131
                    throw invalid_argument("invalid hex digits in fingerprint");
vb@10
   132
                }
vb@10
   133
            }
markus@180
   134
            if (ident->UserId)
markus@180
   135
                _user_id = utf8_string(ident->UserId);
markus@180
   136
            if (ident->UserName)
markus@180
   137
                _username = utf8_string(ident->UserName);
vb@10
   138
vb@10
   139
            _ident = ::new_identity(_address.c_str(), _fpr.c_str(), _user_id.c_str(), _username.c_str());
vb@10
   140
            assert(_ident);
vb@10
   141
            if (_ident == NULL)
vb@10
   142
                throw bad_alloc();
vb@10
   143
markus@180
   144
            _ident->comm_type = (PEP_comm_type) ident->CommType;
vb@10
   145
markus@180
   146
            if (ident->Lang) {
markus@180
   147
                string _lang = utf8_string(ident->Lang);
vb@10
   148
                if (_lang.length() != 0) {
vb@10
   149
                    if (_lang.length() != 2) {
vb@10
   150
                        ::free_identity(_ident);
vb@10
   151
                        throw invalid_argument("invalid language code");
vb@10
   152
                    }
vb@10
   153
                    if (_lang[0] < 'a' || _lang[0] > 'z') {
vb@10
   154
                        ::free_identity(_ident);
vb@10
   155
                        throw invalid_argument("invalid language code");
vb@10
   156
                    }
vb@10
   157
                    if (_lang[1] < 'a' || _lang[1] > 'z') {
vb@10
   158
                        ::free_identity(_ident);
vb@10
   159
                        throw invalid_argument("invalid language code");
vb@10
   160
                    }
vb@10
   161
                    _ident->lang[0] = _lang[0];
vb@10
   162
                    _ident->lang[1] = _lang[1];
vb@10
   163
                }
vb@10
   164
            }
vb@10
   165
vb@217
   166
			_ident->flags = (identity_flags_t)ident->Flags;
vb@217
   167
vb@10
   168
            return _ident;
vb@10
   169
        }
vb@33
   170
vb@33
   171
        template< class T2, class T > T2 from_C(T *tl);
vb@33
   172
vb@41
   173
        BSTR bstr(char *s)
vb@33
   174
        {
vb@42
   175
            if (s == NULL)
vb@33
   176
                return _bstr_t(L"").Detach();
vb@42
   177
vb@42
   178
            return utf16_bstr(s);
vb@33
   179
        }
vb@33
   180
markus@172
   181
        template<> Blob *from_C< Blob *, bloblist_t >(bloblist_t *tl)
vb@33
   182
        {
vb@212
   183
			assert(tl);
vb@212
   184
vb@33
   185
            CComSafeArray<BYTE> sa;
vb@212
   186
			if (tl) {
vb@212
   187
				sa.Create(tl->size);
vb@212
   188
				if (tl->size) {
vb@212
   189
					char *data;
vb@212
   190
					SafeArrayAccessData(sa, (void **)&data);
vb@212
   191
					memcpy(data, tl->value, tl->size);
vb@212
   192
					SafeArrayUnaccessData(sa);
vb@212
   193
				}
vb@212
   194
			}
vb@212
   195
			else {
vb@212
   196
				sa.Create((ULONG)0);
vb@212
   197
			}
vb@33
   198
markus@172
   199
            Blob *_blob = new Blob();
vb@33
   200
vb@33
   201
            _blob->value = sa.Detach();
markus@180
   202
            _blob->MimeType = bstr(tl->mime_type);
markus@180
   203
            _blob->Filename = bstr(tl->filename);
vb@33
   204
vb@33
   205
            return _blob;
vb@33
   206
        }
vb@33
   207
markus@251
   208
        template<> BlobEx *from_C< BlobEx *, bloblist_t >(bloblist_t *tl)
markus@251
   209
        {
markus@251
   210
            assert(tl);
markus@251
   211
markus@251
   212
            CComSafeArray<BYTE> sa;
markus@251
   213
            if (tl) {
markus@251
   214
                sa.Create(tl->size);
markus@251
   215
                if (tl->size) {
markus@251
   216
                    char *data;
markus@251
   217
                    SafeArrayAccessData(sa, (void **)&data);
markus@251
   218
                    memcpy(data, tl->value, tl->size);
markus@251
   219
                    SafeArrayUnaccessData(sa);
markus@251
   220
                }
markus@251
   221
            }
markus@251
   222
            else {
markus@251
   223
                sa.Create((ULONG)0);
markus@251
   224
            }
markus@251
   225
markus@251
   226
            BlobEx *_blob = new BlobEx();
markus@251
   227
markus@251
   228
            _blob->value = sa.Detach();
markus@251
   229
            _blob->MimeType = bstr(tl->mime_type);
markus@251
   230
            _blob->Filename = bstr(tl->filename);
markus@251
   231
            _blob->ContentId = bstr(tl->content_id);
markus@251
   232
markus@251
   233
            return _blob;
markus@251
   234
        }
markus@251
   235
vb@33
   236
        template< class T > int length(T *);
vb@33
   237
vb@33
   238
        template< class T2, class T > SAFEARRAY * array_from_C(T *tl)
vb@33
   239
        {
vb@39
   240
            if (tl == NULL)
vb@39
   241
                return newSafeArray<T2>(0);
vb@39
   242
vb@33
   243
            int len = length<T>(tl);
vb@33
   244
vb@33
   245
            LPSAFEARRAY sa = newSafeArray<T2>(len);
vb@33
   246
            LONG lbound, ubound;
vb@33
   247
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   248
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   249
vb@33
   250
            T *_tl = tl;
vb@38
   251
            for (LONG i = lbound; i <= ubound; _tl = _tl->next, i++)
vb@33
   252
                SafeArrayPutElement(sa, &i, from_C<T2 *, T>(_tl));
vb@33
   253
vb@33
   254
            return sa;
vb@33
   255
        }
vb@33
   256
markus@172
   257
        void clear_identity_s(pEpIdentity& ident)
vb@41
   258
        {
markus@180
   259
            SysFreeString(ident.Address);
markus@180
   260
            SysFreeString(ident.Fpr);
markus@180
   261
            SysFreeString(ident.Lang);
markus@180
   262
            SysFreeString(ident.UserName);
markus@180
   263
            SysFreeString(ident.UserId);
vb@41
   264
markus@172
   265
            memset(&ident, 0, sizeof(pEpIdentity));
vb@41
   266
        }
vb@41
   267
markus@172
   268
        template<> pEpIdentity from_C< pEpIdentity, pEp_identity >(pEp_identity *tl)
vb@33
   269
        {
markus@172
   270
            pEpIdentity _ident;
vb@41
   271
            memset(&_ident, 0, sizeof(_ident));
vb@41
   272
vb@39
   273
            if (tl)
vb@39
   274
                copy_identity(&_ident, tl);
vb@33
   275
            return _ident;
vb@33
   276
        }
vb@33
   277
markus@172
   278
        pEpIdentity identity_s(pEp_identity *ident)
vb@33
   279
        {
markus@172
   280
            return from_C< pEpIdentity, pEp_identity >(ident);
vb@33
   281
        }
vb@33
   282
markus@172
   283
        template<> pEpIdentity *from_C< pEpIdentity *, identity_list >(identity_list *il)
vb@33
   284
        {
markus@172
   285
            pEpIdentity *ident = new pEpIdentity();
markus@172
   286
            memset(ident, 0, sizeof(pEpIdentity));
vb@41
   287
vb@39
   288
            if (il)
vb@39
   289
                copy_identity(ident, il->ident);
vb@33
   290
            return ident;
vb@33
   291
        }
vb@33
   292
markus@171
   293
        template<> StringPair *from_C< StringPair *, stringpair_list_t >(stringpair_list_t * sp)
vb@33
   294
        {
markus@171
   295
            StringPair *fld = new StringPair();
vb@39
   296
            if (sp) {
markus@180
   297
                fld->Name = bstr(sp->value->key);
markus@180
   298
                fld->Value = bstr(sp->value->value);
vb@39
   299
            }
vb@33
   300
            return fld;
vb@33
   301
        }
vb@33
   302
vb@33
   303
        template<> int length<identity_list>(identity_list *tl)
vb@33
   304
        {
vb@33
   305
            return identity_list_length(tl);
vb@33
   306
        }
vb@33
   307
vb@33
   308
        template<> int length<bloblist_t>(bloblist_t *tl)
vb@33
   309
        {
vb@33
   310
            return bloblist_length(tl);
vb@33
   311
        }
vb@33
   312
vb@33
   313
        template<> int length<stringpair_list_t>(stringpair_list_t *tl)
vb@33
   314
        {
vb@33
   315
            return stringpair_list_length(tl);
vb@33
   316
        }
vb@33
   317
markus@172
   318
        void clear_text_message(TextMessage *msg)
vb@41
   319
        {
vb@210
   320
			assert(msg);
vb@210
   321
			if (!msg)
vb@210
   322
				return;
vb@210
   323
markus@180
   324
            SysFreeString(msg->Id);
markus@182
   325
            SysFreeString(msg->ShortMsg);
markus@182
   326
            SysFreeString(msg->LongMsg);
markus@182
   327
            SysFreeString(msg->LongMsgFormatted);
markus@180
   328
            SafeArrayDestroy(msg->Attachments);
markus@180
   329
            clear_identity_s(msg->From);
markus@180
   330
            SafeArrayDestroy(msg->To);
markus@180
   331
            clear_identity_s(msg->RecvBy);
markus@180
   332
            SafeArrayDestroy(msg->Cc);
markus@180
   333
            SafeArrayDestroy(msg->Bcc);
markus@180
   334
            SafeArrayDestroy(msg->ReplyTo);
markus@180
   335
            SafeArrayDestroy(msg->References);
markus@180
   336
            SafeArrayDestroy(msg->Keywords);
markus@180
   337
            SysFreeString(msg->Comments);
markus@180
   338
            SafeArrayDestroy(msg->OptFields);
vb@41
   339
markus@172
   340
            memset(msg, 0, sizeof(TextMessage));
vb@41
   341
        }
vb@41
   342
markus@251
   343
        void clear_text_message(TextMessageEx *msg)
markus@251
   344
        {
markus@251
   345
            assert(msg);
markus@251
   346
            if (!msg)
markus@251
   347
                return;
markus@251
   348
markus@251
   349
            SysFreeString(msg->Id);
markus@251
   350
            SysFreeString(msg->ShortMsg);
markus@251
   351
            SysFreeString(msg->LongMsg);
markus@251
   352
            SysFreeString(msg->LongMsgFormatted);
markus@251
   353
            SafeArrayDestroy(msg->Attachments);
markus@251
   354
            clear_identity_s(msg->From);
markus@251
   355
            SafeArrayDestroy(msg->To);
markus@251
   356
            clear_identity_s(msg->RecvBy);
markus@251
   357
            SafeArrayDestroy(msg->Cc);
markus@251
   358
            SafeArrayDestroy(msg->Bcc);
markus@251
   359
            SafeArrayDestroy(msg->ReplyTo);
markus@251
   360
            SafeArrayDestroy(msg->References);
markus@251
   361
            SafeArrayDestroy(msg->Keywords);
markus@251
   362
            SysFreeString(msg->Comments);
markus@251
   363
            SafeArrayDestroy(msg->OptFields);
markus@251
   364
markus@251
   365
            memset(msg, 0, sizeof(TextMessage));
markus@251
   366
        }
markus@251
   367
markus@172
   368
        void text_message_from_C(TextMessage *msg2, const ::message *msg)
vb@33
   369
        {
vb@37
   370
            assert(msg2);
vb@33
   371
            assert(msg);
vb@33
   372
vb@211
   373
			if (!msg2) {
vb@211
   374
				msg2 = (TextMessage *)calloc(1, sizeof(TextMessage));
vb@211
   375
				assert(msg2);
vb@211
   376
				if (!msg2)
vb@211
   377
					throw bad_alloc();
vb@211
   378
			}
vb@211
   379
			else {
vb@211
   380
				clear_text_message(msg2);
vb@211
   381
			}
vb@211
   382
vb@211
   383
			if (!msg)
vb@211
   384
				return;
vb@41
   385
markus@180
   386
            msg2->Dir = (pEpMsgDirection) msg->dir;
markus@180
   387
            msg2->Id = bstr(msg->id);
markus@182
   388
            msg2->ShortMsg = bstr(msg->shortmsg);
markus@182
   389
            msg2->LongMsg = bstr(msg->longmsg);
markus@182
   390
            msg2->LongMsgFormatted = bstr(msg->longmsg_formatted);
markus@180
   391
            msg2->Attachments = array_from_C<Blob, bloblist_t>(msg->attachments);
vb@39
   392
            if (msg->sent)
markus@180
   393
                msg2->Sent = mktime(msg->sent);
vb@39
   394
            if (msg->recv)
markus@180
   395
                msg2->Recv = mktime(msg->recv);
markus@180
   396
            msg2->From = identity_s(msg->from);
markus@180
   397
            msg2->To = array_from_C<pEpIdentity, identity_list>(msg->to);
markus@180
   398
            msg2->RecvBy = identity_s(msg->recv_by);
markus@180
   399
            msg2->Cc = array_from_C<pEpIdentity, identity_list>(msg->cc);
markus@180
   400
            msg2->Bcc = array_from_C<pEpIdentity, identity_list>(msg->bcc);
markus@180
   401
            msg2->ReplyTo = array_from_C<pEpIdentity, identity_list>(msg->reply_to);
markus@180
   402
            msg2->References = string_array(msg->references);
markus@180
   403
            msg2->Keywords = string_array(msg->keywords);
markus@180
   404
            msg2->Comments = bstr(msg->comments);
markus@180
   405
            msg2->OptFields = array_from_C<StringPair, stringpair_list_t>(msg->opt_fields);
vb@33
   406
        }
vb@33
   407
markus@251
   408
        void text_message_from_C(TextMessageEx *msg2, const ::message *msg)
markus@251
   409
        {
markus@251
   410
            assert(msg2);
markus@251
   411
            assert(msg);
markus@251
   412
markus@251
   413
            if (!msg2) {
markus@251
   414
                msg2 = (TextMessageEx *)calloc(1, sizeof(TextMessageEx));
markus@251
   415
                assert(msg2);
markus@251
   416
                if (!msg2)
markus@251
   417
                    throw bad_alloc();
markus@251
   418
            }
markus@251
   419
            else {
markus@251
   420
                clear_text_message(msg2);
markus@251
   421
            }
markus@251
   422
markus@251
   423
            if (!msg)
markus@251
   424
                return;
markus@251
   425
markus@251
   426
            msg2->Dir = (pEpMsgDirection)msg->dir;
markus@251
   427
            msg2->Id = bstr(msg->id);
markus@251
   428
            msg2->ShortMsg = bstr(msg->shortmsg);
markus@251
   429
            msg2->LongMsg = bstr(msg->longmsg);
markus@251
   430
            msg2->LongMsgFormatted = bstr(msg->longmsg_formatted);
markus@251
   431
            msg2->Attachments = array_from_C<BlobEx, bloblist_t>(msg->attachments);
markus@251
   432
            if (msg->sent)
markus@251
   433
                msg2->Sent = mktime(msg->sent);
markus@251
   434
            if (msg->recv)
markus@251
   435
                msg2->Recv = mktime(msg->recv);
markus@251
   436
            msg2->From = identity_s(msg->from);
markus@251
   437
            msg2->To = array_from_C<pEpIdentity, identity_list>(msg->to);
markus@251
   438
            msg2->RecvBy = identity_s(msg->recv_by);
markus@251
   439
            msg2->Cc = array_from_C<pEpIdentity, identity_list>(msg->cc);
markus@251
   440
            msg2->Bcc = array_from_C<pEpIdentity, identity_list>(msg->bcc);
markus@251
   441
            msg2->ReplyTo = array_from_C<pEpIdentity, identity_list>(msg->reply_to);
markus@251
   442
            msg2->References = string_array(msg->references);
markus@251
   443
            msg2->Keywords = string_array(msg->keywords);
markus@251
   444
            msg2->Comments = bstr(msg->comments);
markus@251
   445
            msg2->OptFields = array_from_C<StringPair, stringpair_list_t>(msg->opt_fields);
markus@251
   446
        }
markus@251
   447
vb@37
   448
        char * str(BSTR s)
vb@33
   449
        {
vb@37
   450
            string str = utf8_string(s);
vb@37
   451
            char *_s = _strdup(str.c_str());
vb@33
   452
            if (_s == NULL)
vb@33
   453
                throw bad_alloc();
vb@33
   454
vb@37
   455
            return _s;
vb@33
   456
        }
vb@33
   457
markus@172
   458
        void clear_blob(Blob& b)
vb@41
   459
        {
markus@180
   460
            SysFreeString(b.Filename);
markus@180
   461
            SysFreeString(b.MimeType);
vb@41
   462
            SafeArrayDestroy(b.value);
markus@172
   463
            memset(&b, 0, sizeof(Blob));
vb@41
   464
        }
vb@41
   465
markus@251
   466
        void clear_blob(BlobEx& b)
markus@251
   467
        {
markus@251
   468
            SysFreeString(b.Filename);
markus@251
   469
            SysFreeString(b.MimeType);
markus@251
   470
            SysFreeString(b.ContentId);
markus@251
   471
            SafeArrayDestroy(b.value);
markus@251
   472
            memset(&b, 0, sizeof(Blob));
markus@251
   473
        }
markus@251
   474
vb@33
   475
        bloblist_t *bloblist(SAFEARRAY *sa)
vb@33
   476
        {
vb@37
   477
            if (sa == NULL)
vb@37
   478
                return NULL;
vb@37
   479
vb@33
   480
            LONG lbound, ubound;
vb@33
   481
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   482
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   483
vb@33
   484
            size_t size = ubound - lbound + 1;
vb@33
   485
            if (size <= 0)
vb@33
   486
                return NULL;
vb@33
   487
markus@251
   488
            bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL, NULL);
vb@33
   489
            if (bl == NULL)
vb@33
   490
                throw bad_alloc();
vb@33
   491
vb@33
   492
            bloblist_t *_bl = bl;
vb@33
   493
            for (LONG i = lbound; i <= ubound; i++) {
markus@172
   494
                Blob b;
markus@172
   495
                memset(&b, 0, sizeof(Blob));
vb@33
   496
                SafeArrayGetElement(sa, &i, &b);
vb@33
   497
vb@38
   498
                LONG _lbound, _ubound;
vb@38
   499
                SafeArrayGetLBound(b.value, 1, &_lbound);
vb@38
   500
                SafeArrayGetUBound(b.value, 1, &_ubound);
vb@38
   501
                size_t size = _ubound - _lbound + 1;
vb@38
   502
vb@136
   503
                char *buffer;
vb@136
   504
                if (size) {
vb@224
   505
                    buffer = (char *) malloc(size + 1);
vb@136
   506
                    if (buffer == NULL)
vb@136
   507
                        throw bad_alloc();
vb@33
   508
vb@136
   509
                    char *data;
vb@33
   510
vb@136
   511
                    SafeArrayAccessData(b.value, (void **) &data);
vb@136
   512
                    memcpy(buffer, data, size);
vb@224
   513
					buffer[size] = 0; // safeguard
vb@136
   514
                    SafeArrayUnaccessData(sa);
vb@136
   515
                }
vb@136
   516
                else {
vb@136
   517
                    buffer = _strdup("");
vb@136
   518
                    if (buffer == NULL)
vb@136
   519
                        throw bad_alloc();
vb@33
   520
vb@136
   521
                }
markus@251
   522
                _bl = bloblist_add(_bl, buffer, size, str(b.MimeType), str(b.Filename), "");
markus@251
   523
                if (_bl == NULL) {
markus@251
   524
                    free(buffer);
markus@251
   525
                    clear_blob(b);
markus@251
   526
                    free_bloblist(bl);
markus@251
   527
                    throw bad_alloc();
markus@251
   528
                }
markus@251
   529
markus@251
   530
                clear_blob(b);
markus@251
   531
            }
markus@251
   532
markus@251
   533
            return bl;
markus@251
   534
        }
markus@251
   535
markus@251
   536
        bloblist_t *bloblistEx(SAFEARRAY *sa)
markus@251
   537
        {
markus@251
   538
            if (sa == NULL)
markus@251
   539
                return NULL;
markus@251
   540
markus@251
   541
            LONG lbound, ubound;
markus@251
   542
            SafeArrayGetLBound(sa, 1, &lbound);
markus@251
   543
            SafeArrayGetUBound(sa, 1, &ubound);
markus@251
   544
markus@251
   545
            size_t size = ubound - lbound + 1;
markus@251
   546
            if (size <= 0)
markus@251
   547
                return NULL;
markus@251
   548
markus@251
   549
            bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL, NULL);
markus@251
   550
            if (bl == NULL)
markus@251
   551
                throw bad_alloc();
markus@251
   552
markus@251
   553
            bloblist_t *_bl = bl;
markus@251
   554
            for (LONG i = lbound; i <= ubound; i++) {
markus@251
   555
                BlobEx b;
markus@251
   556
                memset(&b, 0, sizeof(BlobEx));
markus@251
   557
                SafeArrayGetElement(sa, &i, &b);
markus@251
   558
markus@251
   559
                LONG _lbound, _ubound;
markus@251
   560
                SafeArrayGetLBound(b.value, 1, &_lbound);
markus@251
   561
                SafeArrayGetUBound(b.value, 1, &_ubound);
markus@251
   562
                size_t size = _ubound - _lbound + 1;
markus@251
   563
markus@251
   564
                char *buffer;
markus@251
   565
                if (size) {
markus@251
   566
                    buffer = (char *)malloc(size + 1);
markus@251
   567
                    if (buffer == NULL)
markus@251
   568
                        throw bad_alloc();
markus@251
   569
markus@251
   570
                    char *data;
markus@251
   571
markus@251
   572
                    SafeArrayAccessData(b.value, (void **)&data);
markus@251
   573
                    memcpy(buffer, data, size);
markus@251
   574
                    buffer[size] = 0; // safeguard
markus@251
   575
                    SafeArrayUnaccessData(sa);
markus@251
   576
                }
markus@251
   577
                else {
markus@251
   578
                    buffer = _strdup("");
markus@251
   579
                    if (buffer == NULL)
markus@251
   580
                        throw bad_alloc();
markus@251
   581
markus@251
   582
                }
markus@251
   583
                _bl = bloblist_add(_bl, buffer, size, str(b.MimeType), str(b.Filename), str(b.ContentId));
vb@33
   584
                if (_bl == NULL) {
vb@42
   585
                    free(buffer);
vb@41
   586
                    clear_blob(b);
vb@33
   587
                    free_bloblist(bl);
vb@33
   588
                    throw bad_alloc();
vb@33
   589
                }
vb@33
   590
vb@41
   591
                clear_blob(b);
vb@33
   592
            }
vb@33
   593
vb@33
   594
            return bl;
vb@33
   595
        }
vb@33
   596
vb@33
   597
        identity_list *identities(SAFEARRAY * sa)
vb@33
   598
        {
vb@37
   599
            if (sa == NULL)
vb@37
   600
                return NULL;
vb@37
   601
vb@33
   602
            LONG lbound, ubound;
vb@33
   603
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   604
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   605
vb@33
   606
            size_t size = ubound - lbound + 1;
vb@33
   607
            if (size <= 0)
vb@33
   608
                return NULL;
vb@33
   609
vb@33
   610
            identity_list *il = new_identity_list(NULL);
vb@33
   611
vb@33
   612
            identity_list *_il = il;
vb@33
   613
            for (LONG i = lbound; i <= ubound; i++) {
markus@172
   614
                pEpIdentity s;
markus@172
   615
                memset(&s, 0, sizeof(pEpIdentity));
vb@33
   616
                SafeArrayGetElement(sa, &i, &s);
vb@33
   617
vb@33
   618
                pEp_identity *ident;
vb@33
   619
                try {
vb@33
   620
                    ident = new_identity(&s);
vb@33
   621
                }
vb@33
   622
                catch (bad_alloc&) {
vb@41
   623
                    clear_identity_s(s);
vb@33
   624
                    throw bad_alloc();
vb@33
   625
                }
vb@33
   626
vb@41
   627
                clear_identity_s(s);
vb@33
   628
vb@33
   629
                _il = identity_list_add(_il, ident);
vb@33
   630
                if (_il == NULL) {
vb@33
   631
                    free_identity_list(il);
vb@33
   632
                    throw bad_alloc();
vb@33
   633
                }
vb@33
   634
            }
vb@33
   635
vb@33
   636
            return il;
vb@33
   637
        }
vb@33
   638
markus@171
   639
        stringpair_t *new_stringpair(StringPair *fld)
vb@33
   640
        {
vb@212
   641
			stringpair_t *pair;
vb@212
   642
vb@212
   643
			if (!fld) {
vb@212
   644
				pair = ::new_stringpair(NULL, NULL);
vb@212
   645
			}
vb@212
   646
			else {
vb@212
   647
				pair = ::new_stringpair(str(fld->Name), str(fld->Value));
vb@212
   648
			}
vb@33
   649
            if (pair == NULL)
vb@33
   650
                throw bad_alloc();
vb@33
   651
vb@33
   652
            return pair;
vb@33
   653
        }
vb@33
   654
markus@171
   655
        void clear_opt_field(StringPair& f)
vb@41
   656
        {
markus@180
   657
            SysFreeString(f.Name);
markus@180
   658
            SysFreeString(f.Value);
markus@171
   659
            memset(&f, 0, sizeof(StringPair));
vb@41
   660
        }
vb@41
   661
vb@33
   662
        stringpair_list_t *stringpair_list(SAFEARRAY * sa)
vb@33
   663
        {
vb@37
   664
            if (sa == NULL)
vb@37
   665
                return NULL;
vb@37
   666
vb@33
   667
            LONG lbound, ubound;
vb@33
   668
            SafeArrayGetLBound(sa, 1, &lbound);
vb@33
   669
            SafeArrayGetUBound(sa, 1, &ubound);
vb@33
   670
vb@33
   671
            size_t size = ubound - lbound + 1;
vb@33
   672
            if (size <= 0)
vb@33
   673
                return NULL;
vb@33
   674
vb@33
   675
            stringpair_list_t *il = new_stringpair_list(NULL);
vb@33
   676
vb@33
   677
            stringpair_list_t *_il = il;
vb@33
   678
            for (LONG i = lbound; i <= ubound; i++) {
markus@171
   679
                StringPair s;
markus@171
   680
                memset(&s, 0, sizeof(StringPair));
vb@33
   681
                SafeArrayGetElement(sa, &i, &s);
vb@33
   682
vb@33
   683
                stringpair_t *pair;
vb@33
   684
                try {
vb@33
   685
                    pair = new_stringpair(&s);
vb@33
   686
                }
vb@33
   687
                catch (bad_alloc&) {
vb@41
   688
                    clear_opt_field(s);
vb@33
   689
                    throw bad_alloc();
vb@33
   690
                }
vb@33
   691
vb@41
   692
                clear_opt_field(s);
vb@33
   693
vb@33
   694
                _il = stringpair_list_add(_il, pair);
vb@33
   695
                if (_il == NULL) {
vb@33
   696
                    free_stringpair_list(il);
vb@33
   697
                    throw bad_alloc();
vb@33
   698
                }
vb@33
   699
            }
vb@33
   700
vb@33
   701
            return il;
vb@33
   702
        }
vb@33
   703
        
markus@172
   704
        ::message * text_message_to_C(TextMessage *msg)
vb@33
   705
        {
vb@33
   706
            assert(msg);
vb@212
   707
			if (!msg)
vb@212
   708
				throw invalid_argument("msg");
vb@33
   709
markus@180
   710
            ::message * msg2 = new_message((PEP_msg_direction) msg->Dir);
vb@37
   711
            if (msg2 == NULL)
vb@37
   712
                throw bad_alloc();
vb@33
   713
markus@180
   714
            msg2->id = str(msg->Id);
markus@182
   715
            msg2->shortmsg = str(msg->ShortMsg);
markus@182
   716
            msg2->longmsg = str(msg->LongMsg);
markus@182
   717
            msg2->longmsg_formatted = str(msg->LongMsgFormatted);
markus@180
   718
            msg2->attachments = bloblist(msg->Attachments);
markus@180
   719
            msg2->sent = new_timestamp(msg->Sent);
markus@180
   720
            msg2->recv = new_timestamp(msg->Recv);
markus@180
   721
            msg2->from = new_identity(&msg->From);
markus@180
   722
            msg2->to = identities(msg->To);
markus@180
   723
            msg2->recv_by = new_identity(&msg->RecvBy);
markus@180
   724
            msg2->cc = identities(msg->Cc);
markus@180
   725
            msg2->bcc = identities(msg->Bcc);
markus@180
   726
            msg2->reply_to = identities(msg->ReplyTo);
markus@180
   727
            msg2->references = new_stringlist(msg->References);
markus@180
   728
            msg2->keywords = new_stringlist(msg->Keywords);
markus@180
   729
            msg2->comments = str(msg->Comments);
markus@180
   730
            msg2->opt_fields = stringpair_list(msg->OptFields);
vb@33
   731
vb@33
   732
            return msg2;
vb@33
   733
        }
markus@177
   734
markus@251
   735
        ::message * text_message_to_C(TextMessageEx *msg)
markus@251
   736
        {
markus@251
   737
            assert(msg);
markus@251
   738
            if (!msg)
markus@251
   739
                throw invalid_argument("msg");
markus@251
   740
markus@251
   741
            ::message * msg2 = new_message((PEP_msg_direction)msg->Dir);
markus@251
   742
            if (msg2 == NULL)
markus@251
   743
                throw bad_alloc();
markus@251
   744
markus@251
   745
            msg2->id = str(msg->Id);
markus@251
   746
            msg2->shortmsg = str(msg->ShortMsg);
markus@251
   747
            msg2->longmsg = str(msg->LongMsg);
markus@251
   748
            msg2->longmsg_formatted = str(msg->LongMsgFormatted);
markus@251
   749
            msg2->attachments = bloblistEx(msg->Attachments);
markus@251
   750
            msg2->sent = new_timestamp(msg->Sent);
markus@251
   751
            msg2->recv = new_timestamp(msg->Recv);
markus@251
   752
            msg2->from = new_identity(&msg->From);
markus@251
   753
            msg2->to = identities(msg->To);
markus@251
   754
            msg2->recv_by = new_identity(&msg->RecvBy);
markus@251
   755
            msg2->cc = identities(msg->Cc);
markus@251
   756
            msg2->bcc = identities(msg->Bcc);
markus@251
   757
            msg2->reply_to = identities(msg->ReplyTo);
markus@251
   758
            msg2->references = new_stringlist(msg->References);
markus@251
   759
            msg2->keywords = new_stringlist(msg->Keywords);
markus@251
   760
            msg2->comments = str(msg->Comments);
markus@251
   761
            msg2->opt_fields = stringpair_list(msg->OptFields);
markus@251
   762
markus@251
   763
            return msg2;
markus@251
   764
        }
markus@251
   765
krista@157
   766
		void opt_field_array_from_C(stringpair_list_t* spair_list, LPSAFEARRAY* pair_list_out) {
krista@157
   767
			assert(spair_list);
krista@157
   768
			assert(pair_list_out);
krista@157
   769
			
krista@157
   770
			if (!spair_list)
krista@157
   771
				return;
krista@157
   772
markus@171
   773
			*pair_list_out = array_from_C<StringPair, stringpair_list_t>(spair_list);
krista@157
   774
		}
markus@177
   775
krista@158
   776
		void clear_opt_field_array(LPSAFEARRAY* opt_field_array) {
vb@212
   777
			if (opt_field_array){
vb@212
   778
				SafeArrayDestroy(*opt_field_array);
vb@212
   779
				*opt_field_array = NULL;
vb@212
   780
			}
krista@158
   781
		}
vb@10
   782
    }
vb@10
   783
}