ECStringCompat.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include "ECStringCompat.h"
  19. #include "soapH.h"
  20. #include <kopano/charset/convert.h>
  21. #include <kopano/charset/utf8string.h>
  22. #include "utf8/unchecked.h"
  23. using namespace std;
  24. namespace KC {
  25. char *ECStringCompat::WTF1252_to_WINDOWS1252(soap *lpsoap, const char *szWTF1252, convert_context *lpConverter)
  26. {
  27. if (!szWTF1252)
  28. return NULL;
  29. string str1252;
  30. str1252.reserve(strlen(szWTF1252));
  31. while (*szWTF1252) {
  32. utf8::uint32_t cp = utf8::unchecked::next(szWTF1252);
  33. // Since the string was originally windows-1252, all code points
  34. // should be in the range 0 <= cp < 256.
  35. str1252.append(1, cp < 256 ? cp : '?');
  36. }
  37. return s_strcpy(lpsoap, str1252.c_str());
  38. }
  39. char *ECStringCompat::WTF1252_to_UTF8(soap *lpsoap, const char *szWTF1252, convert_context *lpConverter)
  40. {
  41. if (!szWTF1252)
  42. return NULL;
  43. string str1252;
  44. str1252.reserve(strlen(szWTF1252));
  45. while (*szWTF1252) {
  46. utf8::uint32_t cp = utf8::unchecked::next(szWTF1252);
  47. // Since the string was originally windows-1252, all code points
  48. // should be in the range 0 <= cp < 256.
  49. str1252.append(1, cp < 256 ? cp : '?');
  50. }
  51. // Now convert the windows-1252 string to proper UTF8.
  52. utf8string strUTF8;
  53. if (lpConverter)
  54. strUTF8 = lpConverter->convert_to<utf8string>(str1252, rawsize(str1252), "WINDOWS-1252");
  55. else
  56. strUTF8 = convert_to<utf8string>(str1252, rawsize(str1252), "WINDOWS-1252");
  57. return s_strcpy(lpsoap, strUTF8.c_str());
  58. }
  59. char *ECStringCompat::UTF8_to_WTF1252(soap *lpsoap, const char *szUTF8, convert_context *lpConverter)
  60. {
  61. if (!szUTF8)
  62. return NULL;
  63. string str1252;
  64. if (lpConverter)
  65. str1252 = lpConverter->convert_to<string>("WINDOWS-1252//TRANSLIT", szUTF8, rawsize(szUTF8), "UTF-8");
  66. else
  67. str1252 = convert_to<string>("WINDOWS-1252//TRANSLIT", szUTF8, rawsize(szUTF8), "UTF-8");
  68. string strWTF1252;
  69. auto iWTF1252 = back_inserter(strWTF1252);
  70. strWTF1252.reserve(string::size_type(str1252.size() * 1.3)); // It will probably grow a bit, 1.3 is just a guess.
  71. for (const auto c : str1252)
  72. utf8::unchecked::append(static_cast<unsigned char>(c), iWTF1252);
  73. return s_strcpy(lpsoap, strWTF1252.c_str());
  74. }
  75. ECStringCompat::ECStringCompat(bool fUnicode) :
  76. m_lpConverter(fUnicode ? NULL : new convert_context)
  77. , m_fUnicode(fUnicode)
  78. { }
  79. ECStringCompat::~ECStringCompat()
  80. {
  81. // deleting a NULL ptr is allowed.
  82. delete m_lpConverter;
  83. }
  84. ECRESULT FixPropEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct propVal *lpProp, bool bNoTagUpdate)
  85. {
  86. if (PROP_TYPE(lpProp->ulPropTag) == PT_STRING8 || PROP_TYPE(lpProp->ulPropTag) == PT_UNICODE) {
  87. if (type == In) {
  88. lpProp->Value.lpszA = stringCompat.to_UTF8(soap, lpProp->Value.lpszA);
  89. if (!bNoTagUpdate)
  90. lpProp->ulPropTag = CHANGE_PROP_TYPE(lpProp->ulPropTag, PT_UNICODE);
  91. } else {
  92. lpProp->Value.lpszA = stringCompat.from_UTF8(soap, lpProp->Value.lpszA);
  93. if (!bNoTagUpdate)
  94. lpProp->ulPropTag = CHANGE_PROP_TYPE(lpProp->ulPropTag, stringCompat.string_prop_type());
  95. }
  96. } else if (PROP_TYPE(lpProp->ulPropTag) == PT_MV_STRING8 || PROP_TYPE(lpProp->ulPropTag) == PT_MV_UNICODE) {
  97. if (type == In) {
  98. for (gsoap_size_t i = 0; i < lpProp->Value.mvszA.__size; ++i)
  99. lpProp->Value.mvszA.__ptr[i] = stringCompat.to_UTF8(soap, lpProp->Value.mvszA.__ptr[i]);
  100. if (!bNoTagUpdate)
  101. lpProp->ulPropTag = CHANGE_PROP_TYPE(lpProp->ulPropTag, PT_MV_UNICODE);
  102. } else {
  103. for (gsoap_size_t i = 0; i < lpProp->Value.mvszA.__size; ++i)
  104. lpProp->Value.mvszA.__ptr[i] = stringCompat.from_UTF8(soap, lpProp->Value.mvszA.__ptr[i]);
  105. if (!bNoTagUpdate)
  106. lpProp->ulPropTag = CHANGE_PROP_TYPE(lpProp->ulPropTag, stringCompat.string_prop_type() | MV_FLAG);
  107. }
  108. }
  109. return erSuccess;
  110. }
  111. ECRESULT FixRestrictionEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct restrictTable *lpRestrict)
  112. {
  113. ECRESULT er = erSuccess;
  114. assert(soap != NULL);
  115. assert(lpRestrict != NULL);
  116. switch (lpRestrict->ulType) {
  117. case RES_AND:
  118. for (gsoap_size_t i = 0; er == erSuccess && i < lpRestrict->lpAnd->__size; ++i)
  119. er = FixRestrictionEncoding(soap, stringCompat, type, lpRestrict->lpAnd->__ptr[i]);
  120. break;
  121. case RES_BITMASK:
  122. break;
  123. case RES_COMMENT:
  124. for (gsoap_size_t i = 0; er == erSuccess && i < lpRestrict->lpComment->sProps.__size; ++i)
  125. er = FixPropEncoding(soap, stringCompat, type, &lpRestrict->lpComment->sProps.__ptr[i]);
  126. if (er == erSuccess)
  127. er = FixRestrictionEncoding(soap, stringCompat, type, lpRestrict->lpComment->lpResTable);
  128. break;
  129. case RES_COMPAREPROPS:
  130. break;
  131. case RES_CONTENT:
  132. er = FixPropEncoding(soap, stringCompat, type, lpRestrict->lpContent->lpProp);
  133. break;
  134. case RES_EXIST:
  135. break;
  136. case RES_NOT:
  137. er = FixRestrictionEncoding(soap, stringCompat, type, lpRestrict->lpNot->lpNot);
  138. break;
  139. case RES_OR:
  140. for (gsoap_size_t i = 0; er == erSuccess && i < lpRestrict->lpOr->__size; ++i)
  141. er = FixRestrictionEncoding(soap, stringCompat, type, lpRestrict->lpOr->__ptr[i]);
  142. break;
  143. case RES_PROPERTY:
  144. er = FixPropEncoding(soap, stringCompat, type, lpRestrict->lpProp->lpProp);
  145. break;
  146. case RES_SIZE:
  147. break;
  148. case RES_SUBRESTRICTION:
  149. er = FixRestrictionEncoding(soap, stringCompat, type, lpRestrict->lpSub->lpSubObject);
  150. break;
  151. default:
  152. return KCERR_INVALID_TYPE;
  153. }
  154. return er;
  155. }
  156. ECRESULT FixRowSetEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct rowSet *lpRowSet)
  157. {
  158. ECRESULT er = erSuccess;
  159. for (gsoap_size_t i = 0; er == erSuccess && i < lpRowSet->__size; ++i)
  160. for (gsoap_size_t j = 0; er == erSuccess && j < lpRowSet->__ptr[i].__size; ++j)
  161. er = FixPropEncoding(soap, stringCompat, type, &lpRowSet->__ptr[i].__ptr[j], true);
  162. return er;
  163. }
  164. ECRESULT FixUserEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct user *lpUser)
  165. {
  166. ECRESULT er = erSuccess;
  167. if (type == In) {
  168. lpUser->lpszFullName = stringCompat.to_UTF8(soap, lpUser->lpszFullName);
  169. lpUser->lpszMailAddress = stringCompat.to_UTF8(soap, lpUser->lpszMailAddress);
  170. lpUser->lpszPassword = stringCompat.to_UTF8(soap, lpUser->lpszPassword);
  171. lpUser->lpszServername = stringCompat.to_UTF8(soap, lpUser->lpszServername);
  172. lpUser->lpszUsername = stringCompat.to_UTF8(soap, lpUser->lpszUsername);
  173. if (lpUser->lpsPropmap)
  174. for (gsoap_size_t i = 0; er == erSuccess && i < lpUser->lpsPropmap->__size; ++i)
  175. lpUser->lpsPropmap->__ptr[i].lpszValue = stringCompat.to_UTF8(soap, lpUser->lpsPropmap->__ptr[i].lpszValue);
  176. if (lpUser->lpsMVPropmap)
  177. for (gsoap_size_t i = 0; er == erSuccess && i < lpUser->lpsMVPropmap->__size; ++i)
  178. for (gsoap_size_t j = 0; er == erSuccess && j < lpUser->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  179. lpUser->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.to_UTF8(soap, lpUser->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  180. } else {
  181. lpUser->lpszFullName = stringCompat.from_UTF8_cpy(soap, lpUser->lpszFullName);
  182. lpUser->lpszMailAddress = stringCompat.from_UTF8_cpy(soap, lpUser->lpszMailAddress);
  183. lpUser->lpszPassword = stringCompat.from_UTF8_cpy(soap, lpUser->lpszPassword);
  184. lpUser->lpszServername = stringCompat.from_UTF8_cpy(soap, lpUser->lpszServername);
  185. lpUser->lpszUsername = stringCompat.from_UTF8_cpy(soap, lpUser->lpszUsername);
  186. if (lpUser->lpsPropmap)
  187. for (gsoap_size_t i = 0; er == erSuccess && i < lpUser->lpsPropmap->__size; ++i)
  188. lpUser->lpsPropmap->__ptr[i].lpszValue = stringCompat.from_UTF8_cpy(soap, lpUser->lpsPropmap->__ptr[i].lpszValue);
  189. if (lpUser->lpsMVPropmap)
  190. for (gsoap_size_t i = 0; er == erSuccess && i < lpUser->lpsMVPropmap->__size; ++i)
  191. for (gsoap_size_t j = 0; er == erSuccess && j < lpUser->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  192. lpUser->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.from_UTF8_cpy(soap, lpUser->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  193. }
  194. return er;
  195. }
  196. ECRESULT FixGroupEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct group *lpGroup)
  197. {
  198. ECRESULT er = erSuccess;
  199. if (type == In) {
  200. lpGroup->lpszFullname = stringCompat.to_UTF8(soap, lpGroup->lpszFullname);
  201. lpGroup->lpszFullEmail = stringCompat.to_UTF8(soap, lpGroup->lpszFullEmail);
  202. lpGroup->lpszGroupname = stringCompat.to_UTF8(soap, lpGroup->lpszGroupname);
  203. if (lpGroup->lpsPropmap)
  204. for (gsoap_size_t i = 0; er == erSuccess && i < lpGroup->lpsPropmap->__size; ++i)
  205. lpGroup->lpsPropmap->__ptr[i].lpszValue = stringCompat.to_UTF8(soap, lpGroup->lpsPropmap->__ptr[i].lpszValue);
  206. if (lpGroup->lpsMVPropmap)
  207. for (gsoap_size_t i = 0; er == erSuccess && i < lpGroup->lpsMVPropmap->__size; ++i)
  208. for (gsoap_size_t j = 0; er == erSuccess && j < lpGroup->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  209. lpGroup->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.to_UTF8(soap, lpGroup->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  210. } else {
  211. lpGroup->lpszFullname = stringCompat.from_UTF8_cpy(soap, lpGroup->lpszFullname);
  212. lpGroup->lpszFullEmail = stringCompat.from_UTF8_cpy(soap, lpGroup->lpszFullEmail);
  213. lpGroup->lpszGroupname = stringCompat.from_UTF8_cpy(soap, lpGroup->lpszGroupname);
  214. if (lpGroup->lpsPropmap)
  215. for (gsoap_size_t i = 0; er == erSuccess && i < lpGroup->lpsPropmap->__size; ++i)
  216. lpGroup->lpsPropmap->__ptr[i].lpszValue = stringCompat.from_UTF8_cpy(soap, lpGroup->lpsPropmap->__ptr[i].lpszValue);
  217. if (lpGroup->lpsMVPropmap)
  218. for (gsoap_size_t i = 0; er == erSuccess && i < lpGroup->lpsMVPropmap->__size; ++i)
  219. for (gsoap_size_t j = 0; er == erSuccess && j < lpGroup->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  220. lpGroup->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.from_UTF8_cpy(soap, lpGroup->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  221. }
  222. return er;
  223. }
  224. ECRESULT FixCompanyEncoding(struct soap *soap, const ECStringCompat &stringCompat, enum EncodingFixDirection type, struct company *lpCompany)
  225. {
  226. ECRESULT er = erSuccess;
  227. if (type == In) {
  228. lpCompany->lpszCompanyname = stringCompat.to_UTF8(soap, lpCompany->lpszCompanyname);
  229. lpCompany->lpszServername = stringCompat.to_UTF8(soap, lpCompany->lpszServername);
  230. if (lpCompany->lpsPropmap)
  231. for (gsoap_size_t i = 0; er == erSuccess && i < lpCompany->lpsPropmap->__size; ++i)
  232. lpCompany->lpsPropmap->__ptr[i].lpszValue = stringCompat.to_UTF8(soap, lpCompany->lpsPropmap->__ptr[i].lpszValue);
  233. if (lpCompany->lpsMVPropmap)
  234. for (gsoap_size_t i = 0; er == erSuccess && i < lpCompany->lpsMVPropmap->__size; ++i)
  235. for (gsoap_size_t j = 0; er == erSuccess && j < lpCompany->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  236. lpCompany->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.to_UTF8(soap, lpCompany->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  237. } else {
  238. lpCompany->lpszCompanyname = stringCompat.from_UTF8_cpy(soap, lpCompany->lpszCompanyname);
  239. lpCompany->lpszServername = stringCompat.from_UTF8_cpy(soap, lpCompany->lpszServername);
  240. if (lpCompany->lpsPropmap)
  241. for (gsoap_size_t i = 0; er == erSuccess && i < lpCompany->lpsPropmap->__size; ++i)
  242. lpCompany->lpsPropmap->__ptr[i].lpszValue = stringCompat.from_UTF8_cpy(soap, lpCompany->lpsPropmap->__ptr[i].lpszValue);
  243. if (lpCompany->lpsMVPropmap)
  244. for (gsoap_size_t i = 0; er == erSuccess && i < lpCompany->lpsMVPropmap->__size; ++i)
  245. for (gsoap_size_t j = 0; er == erSuccess && j < lpCompany->lpsMVPropmap->__ptr[i].sValues.__size; ++j)
  246. lpCompany->lpsMVPropmap->__ptr[i].sValues.__ptr[j] = stringCompat.from_UTF8_cpy(soap, lpCompany->lpsMVPropmap->__ptr[i].sValues.__ptr[j]);
  247. }
  248. return er;
  249. }
  250. ECRESULT FixNotificationsEncoding(struct soap *soap, const ECStringCompat &stringCompat, struct notificationArray *notifications)
  251. {
  252. ECRESULT er = erSuccess;
  253. for (gsoap_size_t i = 0; i < notifications->__size; ++i) {
  254. switch (notifications->__ptr[i].ulEventType) {
  255. case fnevNewMail:
  256. notifications->__ptr[i].newmail->lpszMessageClass = stringCompat.from_UTF8(soap, notifications->__ptr[i].newmail->lpszMessageClass);
  257. break;
  258. case fnevTableModified:
  259. if (notifications->__ptr[i].tab->pRow)
  260. for (gsoap_size_t j = 0; er == erSuccess && j < notifications->__ptr[i].tab->pRow->__size; ++j)
  261. er = FixPropEncoding(soap, stringCompat, Out, notifications->__ptr[i].tab->pRow->__ptr + j, true);
  262. break;
  263. default:
  264. break;
  265. }
  266. }
  267. return er;
  268. }
  269. } /* namespace */