RakWString.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "RakWString.h"
  11. #include "BitStream.h"
  12. #include <string.h>
  13. #include <wchar.h>
  14. #include <stdlib.h>
  15. using namespace RakNet;
  16. // From http://www.joelonsoftware.com/articles/Unicode.html
  17. // Only code points 128 and above are stored using 2, 3, in fact, up to 6 bytes.
  18. #define MAX_BYTES_PER_UNICODE_CHAR sizeof(wchar_t)
  19. RakWString::RakWString()
  20. {
  21. c_str=0;
  22. c_strCharLength=0;
  23. }
  24. RakWString::RakWString( const RakString &right )
  25. {
  26. c_str=0;
  27. c_strCharLength=0;
  28. *this=right;
  29. }
  30. RakWString::RakWString( const char *input )
  31. {
  32. c_str=0;
  33. c_strCharLength=0;
  34. *this = input;
  35. }
  36. RakWString::RakWString( const wchar_t *input )
  37. {
  38. c_str=0;
  39. c_strCharLength=0;
  40. *this = input;
  41. }
  42. RakWString::RakWString( const RakWString & right)
  43. {
  44. c_str=0;
  45. c_strCharLength=0;
  46. *this = right;
  47. }
  48. RakWString::~RakWString()
  49. {
  50. rakFree_Ex(c_str,_FILE_AND_LINE_);
  51. }
  52. RakWString& RakWString::operator = ( const RakWString& right )
  53. {
  54. Clear();
  55. if (right.IsEmpty())
  56. return *this;
  57. c_str = (wchar_t *) rakMalloc_Ex( (right.GetLength() + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  58. if (!c_str)
  59. {
  60. c_strCharLength=0;
  61. notifyOutOfMemory(_FILE_AND_LINE_);
  62. return *this;
  63. }
  64. c_strCharLength = right.GetLength();
  65. memcpy(c_str,right.C_String(),(right.GetLength() + 1) * MAX_BYTES_PER_UNICODE_CHAR);
  66. return *this;
  67. }
  68. RakWString& RakWString::operator = ( const RakString& right )
  69. {
  70. return *this = right.C_String();
  71. }
  72. RakWString& RakWString::operator = ( const wchar_t * const str )
  73. {
  74. Clear();
  75. if (str==0)
  76. return *this;
  77. c_strCharLength = wcslen(str);
  78. if (c_strCharLength==0)
  79. return *this;
  80. c_str = (wchar_t *) rakMalloc_Ex( (c_strCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  81. if (!c_str)
  82. {
  83. c_strCharLength=0;
  84. notifyOutOfMemory(_FILE_AND_LINE_);
  85. return *this;
  86. }
  87. wcscpy(c_str,str);
  88. return *this;
  89. }
  90. RakWString& RakWString::operator = ( wchar_t *str )
  91. {
  92. *this = ( const wchar_t * const) str;
  93. return *this;
  94. }
  95. RakWString& RakWString::operator = ( const char * const str )
  96. {
  97. Clear();
  98. // Not supported on android
  99. #if !defined(ANDROID)
  100. if (str==0)
  101. return *this;
  102. if (str[0]==0)
  103. return *this;
  104. c_strCharLength = mbstowcs(NULL, str, 0);
  105. c_str = (wchar_t *) rakMalloc_Ex( (c_strCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  106. if (!c_str)
  107. {
  108. c_strCharLength=0;
  109. notifyOutOfMemory(_FILE_AND_LINE_);
  110. return *this;
  111. }
  112. c_strCharLength = mbstowcs(c_str, str, c_strCharLength+1);
  113. if (c_strCharLength == (size_t) (-1))
  114. {
  115. RAKNET_DEBUG_PRINTF("Couldn't convert string--invalid multibyte character.\n");
  116. Clear();
  117. return *this;
  118. }
  119. #else
  120. // mbstowcs not supported on android
  121. RakAssert("mbstowcs not supported on Android" && 0);
  122. #endif // defined(ANDROID)
  123. return *this;
  124. }
  125. RakWString& RakWString::operator = ( char *str )
  126. {
  127. *this = ( const char * const) str;
  128. return *this;
  129. }
  130. RakWString& RakWString::operator +=( const RakWString& right)
  131. {
  132. if (right.IsEmpty())
  133. return *this;
  134. size_t newCharLength = c_strCharLength + right.GetLength();
  135. wchar_t *newCStr;
  136. bool isEmpty = IsEmpty();
  137. if (isEmpty)
  138. newCStr = (wchar_t *) rakMalloc_Ex( (newCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  139. else
  140. newCStr = (wchar_t *) rakRealloc_Ex( c_str, (newCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  141. if (!newCStr)
  142. {
  143. notifyOutOfMemory(_FILE_AND_LINE_);
  144. return *this;
  145. }
  146. c_str = newCStr;
  147. c_strCharLength = newCharLength;
  148. if (isEmpty)
  149. {
  150. memcpy(newCStr,right.C_String(),(right.GetLength() + 1) * MAX_BYTES_PER_UNICODE_CHAR);
  151. }
  152. else
  153. {
  154. wcscat(c_str, right.C_String());
  155. }
  156. return *this;
  157. }
  158. RakWString& RakWString::operator += ( const wchar_t * const right )
  159. {
  160. if (right==0)
  161. return *this;
  162. size_t rightLength = wcslen(right);
  163. size_t newCharLength = c_strCharLength + rightLength;
  164. wchar_t *newCStr;
  165. bool isEmpty = IsEmpty();
  166. if (isEmpty)
  167. newCStr = (wchar_t *) rakMalloc_Ex( (newCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  168. else
  169. newCStr = (wchar_t *) rakRealloc_Ex( c_str, (newCharLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  170. if (!newCStr)
  171. {
  172. notifyOutOfMemory(_FILE_AND_LINE_);
  173. return *this;
  174. }
  175. c_str = newCStr;
  176. c_strCharLength = newCharLength;
  177. if (isEmpty)
  178. {
  179. memcpy(newCStr,right,(rightLength + 1) * MAX_BYTES_PER_UNICODE_CHAR);
  180. }
  181. else
  182. {
  183. wcscat(c_str, right);
  184. }
  185. return *this;
  186. }
  187. RakWString& RakWString::operator += ( wchar_t *right )
  188. {
  189. return *this += (const wchar_t * const) right;
  190. }
  191. bool RakWString::operator==(const RakWString &right) const
  192. {
  193. if (GetLength()!=right.GetLength())
  194. return false;
  195. return wcscmp(C_String(),right.C_String())==0;
  196. }
  197. bool RakWString::operator < ( const RakWString& right ) const
  198. {
  199. return wcscmp(C_String(),right.C_String())<0;
  200. }
  201. bool RakWString::operator <= ( const RakWString& right ) const
  202. {
  203. return wcscmp(C_String(),right.C_String())<=0;
  204. }
  205. bool RakWString::operator > ( const RakWString& right ) const
  206. {
  207. return wcscmp(C_String(),right.C_String())>0;
  208. }
  209. bool RakWString::operator >= ( const RakWString& right ) const
  210. {
  211. return wcscmp(C_String(),right.C_String())>=0;
  212. }
  213. bool RakWString::operator!=(const RakWString &right) const
  214. {
  215. if (GetLength()!=right.GetLength())
  216. return true;
  217. return wcscmp(C_String(),right.C_String())!=0;
  218. }
  219. void RakWString::Set( wchar_t *str )
  220. {
  221. *this = str;
  222. }
  223. bool RakWString::IsEmpty(void) const
  224. {
  225. return GetLength()==0;
  226. }
  227. size_t RakWString::GetLength(void) const
  228. {
  229. return c_strCharLength;
  230. }
  231. unsigned long RakWString::ToInteger(const RakWString &rs)
  232. {
  233. unsigned long hash = 0;
  234. int c;
  235. const char *str = (const char *)rs.C_String();
  236. size_t i;
  237. for (i=0; i < rs.GetLength()*MAX_BYTES_PER_UNICODE_CHAR*sizeof(wchar_t); i++)
  238. {
  239. c = *str++;
  240. hash = c + (hash << 6) + (hash << 16) - hash;
  241. }
  242. return hash;
  243. }
  244. int RakWString::StrCmp(const RakWString &right) const
  245. {
  246. return wcscmp(C_String(), right.C_String());
  247. }
  248. int RakWString::StrICmp(const RakWString &right) const
  249. {
  250. #ifdef _WIN32
  251. return _wcsicmp(C_String(), right.C_String());
  252. #else
  253. // Not supported
  254. return wcscmp(C_String(), right.C_String());
  255. #endif
  256. }
  257. void RakWString::Clear(void)
  258. {
  259. rakFree_Ex(c_str,_FILE_AND_LINE_);
  260. c_str=0;
  261. c_strCharLength=0;
  262. }
  263. void RakWString::Printf(void)
  264. {
  265. printf("%ls", C_String());
  266. }
  267. void RakWString::FPrintf(FILE *fp)
  268. {
  269. fprintf(fp,"%ls", C_String());
  270. }
  271. void RakWString::Serialize(BitStream *bs) const
  272. {
  273. Serialize(C_String(), bs);
  274. }
  275. void RakWString::Serialize(const wchar_t * const str, BitStream *bs)
  276. {
  277. #if 0
  278. char *multiByteBuffer;
  279. size_t allocated = wcslen(str)*MAX_BYTES_PER_UNICODE_CHAR;
  280. multiByteBuffer = (char*) rakMalloc_Ex(allocated, _FILE_AND_LINE_);
  281. size_t used = wcstombs(multiByteBuffer, str, allocated);
  282. bs->WriteCasted<unsigned short>(used);
  283. bs->WriteAlignedBytes((const unsigned char*) multiByteBuffer,(const unsigned int) used);
  284. rakFree_Ex(multiByteBuffer, _FILE_AND_LINE_);
  285. #else
  286. size_t mbByteLength = wcslen(str);
  287. bs->WriteCasted<unsigned short>(mbByteLength);
  288. for (unsigned int i=0; i < mbByteLength; i++)
  289. {
  290. uint16_t t;
  291. t = (uint16_t) str[i];
  292. // Force endian swapping, and write to 16 bits
  293. bs->Write(t);
  294. }
  295. #endif
  296. }
  297. bool RakWString::Deserialize(BitStream *bs)
  298. {
  299. Clear();
  300. size_t mbByteLength;
  301. bs->ReadCasted<unsigned short>(mbByteLength);
  302. if (mbByteLength>0)
  303. {
  304. #if 0
  305. char *multiByteBuffer;
  306. multiByteBuffer = (char*) rakMalloc_Ex(mbByteLength+1, _FILE_AND_LINE_);
  307. bool result = bs->ReadAlignedBytes((unsigned char*) multiByteBuffer,(const unsigned int) mbByteLength);
  308. if (result==false)
  309. {
  310. rakFree_Ex(multiByteBuffer, _FILE_AND_LINE_);
  311. return false;
  312. }
  313. multiByteBuffer[mbByteLength]=0;
  314. c_str = (wchar_t *) rakMalloc_Ex( (mbByteLength + 1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  315. c_strCharLength = mbstowcs(c_str, multiByteBuffer, mbByteLength);
  316. rakFree_Ex(multiByteBuffer, _FILE_AND_LINE_);
  317. c_str[c_strCharLength]=0;
  318. #else
  319. c_str = (wchar_t*) rakMalloc_Ex((mbByteLength+1) * MAX_BYTES_PER_UNICODE_CHAR, _FILE_AND_LINE_);
  320. c_strCharLength = mbByteLength;
  321. for (unsigned int i=0; i < mbByteLength; i++)
  322. {
  323. uint16_t t;
  324. // Force endian swapping, and read 16 bits
  325. bs->Read(t);
  326. c_str[i]=t;
  327. }
  328. c_str[mbByteLength]=0;
  329. #endif
  330. return true;
  331. }
  332. else
  333. {
  334. return true;
  335. }
  336. }
  337. bool RakWString::Deserialize(wchar_t *str, BitStream *bs)
  338. {
  339. size_t mbByteLength;
  340. bs->ReadCasted<unsigned short>(mbByteLength);
  341. if (mbByteLength>0)
  342. {
  343. #if 0
  344. char *multiByteBuffer;
  345. multiByteBuffer = (char*) rakMalloc_Ex(mbByteLength+1, _FILE_AND_LINE_);
  346. bool result = bs->ReadAlignedBytes((unsigned char*) multiByteBuffer,(const unsigned int) mbByteLength);
  347. if (result==false)
  348. {
  349. rakFree_Ex(multiByteBuffer, _FILE_AND_LINE_);
  350. return false;
  351. }
  352. multiByteBuffer[mbByteLength]=0;
  353. size_t c_strCharLength = mbstowcs(str, multiByteBuffer, mbByteLength);
  354. rakFree_Ex(multiByteBuffer, _FILE_AND_LINE_);
  355. str[c_strCharLength]=0;
  356. #else
  357. for (unsigned int i=0; i < mbByteLength; i++)
  358. {
  359. uint16_t t;
  360. // Force endian swapping, and read 16 bits
  361. bs->Read(t);
  362. str[i]=t;
  363. }
  364. str[mbByteLength]=0;
  365. #endif
  366. return true;
  367. }
  368. else
  369. {
  370. wcscpy(str,L"");
  371. }
  372. return true;
  373. }
  374. /*
  375. RakNet::BitStream bsTest;
  376. RakNet::RakWString testString("cat"), testString2;
  377. testString = "Hllo";
  378. testString = L"Hello";
  379. testString += L" world";
  380. testString2 += testString2;
  381. RakNet::RakWString ts3(L" from here");
  382. testString2+=ts3;
  383. RakNet::RakWString ts4(L" 222");
  384. testString2=ts4;
  385. RakNet::RakString rs("rakstring");
  386. testString2+=rs;
  387. testString2=rs;
  388. bsTest.Write(L"one");
  389. bsTest.Write(testString2);
  390. bsTest.SetReadOffset(0);
  391. RakNet::RakWString ts5, ts6;
  392. wchar_t buff[99];
  393. wchar_t *wptr = (wchar_t*)buff;
  394. bsTest.Read(wptr);
  395. bsTest.Read(ts5);
  396. */
粤ICP备19079148号