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