nsXPCOMStrings.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nsString.h"
  6. #include "nsCharTraits.h"
  7. #include "nsXPCOMStrings.h"
  8. #include "nsNativeCharsetUtils.h"
  9. /* ------------------------------------------------------------------------- */
  10. XPCOM_API(nsresult)
  11. NS_StringContainerInit(nsStringContainer& aContainer)
  12. {
  13. NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString),
  14. "nsStringContainer is not large enough");
  15. // use placement new to avoid heap allocating nsString object
  16. new (&aContainer) nsString();
  17. return NS_OK;
  18. }
  19. XPCOM_API(nsresult)
  20. NS_StringContainerInit2(nsStringContainer& aContainer,
  21. const char16_t* aData,
  22. uint32_t aDataLength,
  23. uint32_t aFlags)
  24. {
  25. NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString),
  26. "nsStringContainer is not large enough");
  27. if (!aData) {
  28. new (&aContainer) nsString();
  29. } else {
  30. if (aDataLength == UINT32_MAX) {
  31. if (NS_WARN_IF(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)) {
  32. return NS_ERROR_INVALID_ARG;
  33. }
  34. aDataLength = nsCharTraits<char16_t>::length(aData);
  35. }
  36. if (aFlags & (NS_STRING_CONTAINER_INIT_DEPEND |
  37. NS_STRING_CONTAINER_INIT_ADOPT)) {
  38. uint32_t flags;
  39. if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING) {
  40. flags = nsSubstring::F_NONE;
  41. } else {
  42. flags = nsSubstring::F_TERMINATED;
  43. }
  44. if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT) {
  45. flags |= nsSubstring::F_OWNED;
  46. }
  47. new (&aContainer) nsSubstring(const_cast<char16_t*>(aData),
  48. aDataLength, flags);
  49. } else {
  50. new (&aContainer) nsString(aData, aDataLength);
  51. }
  52. }
  53. return NS_OK;
  54. }
  55. XPCOM_API(void)
  56. NS_StringContainerFinish(nsStringContainer& aContainer)
  57. {
  58. // call the nsString dtor
  59. reinterpret_cast<nsString*>(&aContainer)->~nsString();
  60. }
  61. /* ------------------------------------------------------------------------- */
  62. XPCOM_API(uint32_t)
  63. NS_StringGetData(const nsAString& aStr, const char16_t** aData,
  64. bool* aTerminated)
  65. {
  66. if (aTerminated) {
  67. *aTerminated = aStr.IsTerminated();
  68. }
  69. *aData = aStr.BeginReading();
  70. return aStr.Length();
  71. }
  72. XPCOM_API(uint32_t)
  73. NS_StringGetMutableData(nsAString& aStr, uint32_t aDataLength,
  74. char16_t** aData)
  75. {
  76. if (aDataLength != UINT32_MAX) {
  77. aStr.SetLength(aDataLength);
  78. if (aStr.Length() != aDataLength) {
  79. *aData = nullptr;
  80. return 0;
  81. }
  82. }
  83. *aData = aStr.BeginWriting();
  84. return aStr.Length();
  85. }
  86. XPCOM_API(char16_t*)
  87. NS_StringCloneData(const nsAString& aStr)
  88. {
  89. return ToNewUnicode(aStr);
  90. }
  91. XPCOM_API(nsresult)
  92. NS_StringSetData(nsAString& aStr, const char16_t* aData, uint32_t aDataLength)
  93. {
  94. aStr.Assign(aData, aDataLength);
  95. return NS_OK; // XXX report errors
  96. }
  97. XPCOM_API(nsresult)
  98. NS_StringSetDataRange(nsAString& aStr,
  99. uint32_t aCutOffset, uint32_t aCutLength,
  100. const char16_t* aData, uint32_t aDataLength)
  101. {
  102. if (aCutOffset == UINT32_MAX) {
  103. // append case
  104. if (aData) {
  105. aStr.Append(aData, aDataLength);
  106. }
  107. return NS_OK; // XXX report errors
  108. }
  109. if (aCutLength == UINT32_MAX) {
  110. aCutLength = aStr.Length() - aCutOffset;
  111. }
  112. if (aData) {
  113. if (aDataLength == UINT32_MAX) {
  114. aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData));
  115. } else {
  116. aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
  117. }
  118. } else {
  119. aStr.Cut(aCutOffset, aCutLength);
  120. }
  121. return NS_OK; // XXX report errors
  122. }
  123. XPCOM_API(nsresult)
  124. NS_StringCopy(nsAString& aDest, const nsAString& aSrc)
  125. {
  126. aDest.Assign(aSrc);
  127. return NS_OK; // XXX report errors
  128. }
  129. XPCOM_API(void)
  130. NS_StringSetIsVoid(nsAString& aStr, const bool aIsVoid)
  131. {
  132. aStr.SetIsVoid(aIsVoid);
  133. }
  134. XPCOM_API(bool)
  135. NS_StringGetIsVoid(const nsAString& aStr)
  136. {
  137. return aStr.IsVoid();
  138. }
  139. /* ------------------------------------------------------------------------- */
  140. XPCOM_API(nsresult)
  141. NS_CStringContainerInit(nsCStringContainer& aContainer)
  142. {
  143. NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString),
  144. "nsCStringContainer is not large enough");
  145. // use placement new to avoid heap allocating nsCString object
  146. new (&aContainer) nsCString();
  147. return NS_OK;
  148. }
  149. XPCOM_API(nsresult)
  150. NS_CStringContainerInit2(nsCStringContainer& aContainer,
  151. const char* aData,
  152. uint32_t aDataLength,
  153. uint32_t aFlags)
  154. {
  155. NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString),
  156. "nsStringContainer is not large enough");
  157. if (!aData) {
  158. new (&aContainer) nsCString();
  159. } else {
  160. if (aDataLength == UINT32_MAX) {
  161. if (NS_WARN_IF(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)) {
  162. return NS_ERROR_INVALID_ARG;
  163. }
  164. aDataLength = nsCharTraits<char>::length(aData);
  165. }
  166. if (aFlags & (NS_CSTRING_CONTAINER_INIT_DEPEND |
  167. NS_CSTRING_CONTAINER_INIT_ADOPT)) {
  168. uint32_t flags;
  169. if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING) {
  170. flags = nsCSubstring::F_NONE;
  171. } else {
  172. flags = nsCSubstring::F_TERMINATED;
  173. }
  174. if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT) {
  175. flags |= nsCSubstring::F_OWNED;
  176. }
  177. new (&aContainer) nsCSubstring(const_cast<char*>(aData),
  178. aDataLength, flags);
  179. } else {
  180. new (&aContainer) nsCString(aData, aDataLength);
  181. }
  182. }
  183. return NS_OK;
  184. }
  185. XPCOM_API(void)
  186. NS_CStringContainerFinish(nsCStringContainer& aContainer)
  187. {
  188. // call the nsCString dtor
  189. reinterpret_cast<nsCString*>(&aContainer)->~nsCString();
  190. }
  191. /* ------------------------------------------------------------------------- */
  192. XPCOM_API(uint32_t)
  193. NS_CStringGetData(const nsACString& aStr, const char** aData,
  194. bool* aTerminated)
  195. {
  196. if (aTerminated) {
  197. *aTerminated = aStr.IsTerminated();
  198. }
  199. *aData = aStr.BeginReading();
  200. return aStr.Length();
  201. }
  202. XPCOM_API(uint32_t)
  203. NS_CStringGetMutableData(nsACString& aStr, uint32_t aDataLength, char** aData)
  204. {
  205. if (aDataLength != UINT32_MAX) {
  206. aStr.SetLength(aDataLength);
  207. if (aStr.Length() != aDataLength) {
  208. *aData = nullptr;
  209. return 0;
  210. }
  211. }
  212. *aData = aStr.BeginWriting();
  213. return aStr.Length();
  214. }
  215. XPCOM_API(char*)
  216. NS_CStringCloneData(const nsACString& aStr)
  217. {
  218. return ToNewCString(aStr);
  219. }
  220. XPCOM_API(nsresult)
  221. NS_CStringSetData(nsACString& aStr, const char* aData, uint32_t aDataLength)
  222. {
  223. aStr.Assign(aData, aDataLength);
  224. return NS_OK; // XXX report errors
  225. }
  226. XPCOM_API(nsresult)
  227. NS_CStringSetDataRange(nsACString& aStr,
  228. uint32_t aCutOffset, uint32_t aCutLength,
  229. const char* aData, uint32_t aDataLength)
  230. {
  231. if (aCutOffset == UINT32_MAX) {
  232. // append case
  233. if (aData) {
  234. aStr.Append(aData, aDataLength);
  235. }
  236. return NS_OK; // XXX report errors
  237. }
  238. if (aCutLength == UINT32_MAX) {
  239. aCutLength = aStr.Length() - aCutOffset;
  240. }
  241. if (aData) {
  242. if (aDataLength == UINT32_MAX) {
  243. aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData));
  244. } else {
  245. aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
  246. }
  247. } else {
  248. aStr.Cut(aCutOffset, aCutLength);
  249. }
  250. return NS_OK; // XXX report errors
  251. }
  252. XPCOM_API(nsresult)
  253. NS_CStringCopy(nsACString& aDest, const nsACString& aSrc)
  254. {
  255. aDest.Assign(aSrc);
  256. return NS_OK; // XXX report errors
  257. }
  258. XPCOM_API(void)
  259. NS_CStringSetIsVoid(nsACString& aStr, const bool aIsVoid)
  260. {
  261. aStr.SetIsVoid(aIsVoid);
  262. }
  263. XPCOM_API(bool)
  264. NS_CStringGetIsVoid(const nsACString& aStr)
  265. {
  266. return aStr.IsVoid();
  267. }
  268. /* ------------------------------------------------------------------------- */
  269. XPCOM_API(nsresult)
  270. NS_CStringToUTF16(const nsACString& aSrc,
  271. nsCStringEncoding aSrcEncoding,
  272. nsAString& aDest)
  273. {
  274. switch (aSrcEncoding) {
  275. case NS_CSTRING_ENCODING_ASCII:
  276. CopyASCIItoUTF16(aSrc, aDest);
  277. break;
  278. case NS_CSTRING_ENCODING_UTF8:
  279. CopyUTF8toUTF16(aSrc, aDest);
  280. break;
  281. case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM:
  282. NS_CopyNativeToUnicode(aSrc, aDest);
  283. break;
  284. default:
  285. return NS_ERROR_NOT_IMPLEMENTED;
  286. }
  287. return NS_OK; // XXX report errors
  288. }
  289. XPCOM_API(nsresult)
  290. NS_UTF16ToCString(const nsAString& aSrc,
  291. nsCStringEncoding aDestEncoding,
  292. nsACString& aDest)
  293. {
  294. switch (aDestEncoding) {
  295. case NS_CSTRING_ENCODING_ASCII:
  296. LossyCopyUTF16toASCII(aSrc, aDest);
  297. break;
  298. case NS_CSTRING_ENCODING_UTF8:
  299. CopyUTF16toUTF8(aSrc, aDest);
  300. break;
  301. case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM:
  302. NS_CopyUnicodeToNative(aSrc, aDest);
  303. break;
  304. default:
  305. return NS_ERROR_NOT_IMPLEMENTED;
  306. }
  307. return NS_OK; // XXX report errors
  308. }