p≡p COM server adapter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

598 lines
19 KiB

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