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