Back to index

lightning-sunbird  0.9+nobinonly
nsStringAPI.cpp
Go to the documentation of this file.
00001 /* vim:set ts=2 sw=2 et cindent: */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla.
00016  *
00017  * The Initial Developer of the Original Code is IBM Corporation.
00018  * Portions created by IBM Corporation are Copyright (C) 2003
00019  * IBM Corporation.  All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Darin Fisher <darin@meer.net>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsString.h"
00039 #include "nsCharTraits.h"
00040 
00041 #include "nsStringAPI.h"
00042 #include "nsNativeCharsetUtils.h"
00043 
00044 /* ------------------------------------------------------------------------- */
00045 
00046 NS_STRINGAPI(nsresult)
00047 NS_StringContainerInit(nsStringContainer &aContainer)
00048 {
00049   NS_ASSERTION(sizeof(nsStringContainer) >= sizeof(nsString),
00050       "nsStringContainer is not large enough");
00051 
00052   // use placement new to avoid heap allocating nsString object
00053   new (&aContainer) nsString();
00054 
00055   return NS_OK;
00056 }
00057 
00058 NS_STRINGAPI(nsresult)
00059 NS_StringContainerInit2(nsStringContainer &aContainer,
00060                         const PRUnichar   *aData,
00061                         PRUint32           aDataLength,
00062                         PRUint32           aFlags)
00063 {
00064   NS_ASSERTION(sizeof(nsStringContainer) >= sizeof(nsString),
00065       "nsStringContainer is not large enough");
00066 
00067   if (!aData)
00068   {
00069     new (&aContainer) nsString();
00070   }
00071   else
00072   {
00073     if (aDataLength == PR_UINT32_MAX)
00074     {
00075       NS_ENSURE_ARG(!(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING));
00076       aDataLength = nsCharTraits<PRUnichar>::length(aData);
00077     }
00078 
00079     if (aFlags & (NS_STRING_CONTAINER_INIT_DEPEND |
00080                   NS_STRING_CONTAINER_INIT_ADOPT))
00081     {
00082       PRUint32 flags;
00083       if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)
00084         flags = nsSubstring::F_NONE;
00085       else
00086         flags = nsSubstring::F_TERMINATED;
00087 
00088       if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT)
00089         flags |= nsSubstring::F_OWNED;
00090 
00091       new (&aContainer) nsSubstring(NS_CONST_CAST(PRUnichar *, aData),
00092                                     aDataLength, flags);
00093     }
00094     else
00095     {
00096       new (&aContainer) nsString(aData, aDataLength);
00097     }
00098   }
00099 
00100   return NS_OK;
00101 }
00102 
00103 NS_STRINGAPI(void)
00104 NS_StringContainerFinish(nsStringContainer &aContainer)
00105 {
00106   // call the nsString dtor
00107   NS_REINTERPRET_CAST(nsString *, &aContainer)->~nsString();
00108 }
00109 
00110 /* ------------------------------------------------------------------------- */
00111 
00112 NS_STRINGAPI(PRUint32)
00113 NS_StringGetData(const nsAString &aStr, const PRUnichar **aData,
00114                  PRBool *aTerminated)
00115 {
00116   if (aTerminated)
00117     *aTerminated = aStr.IsTerminated();
00118 
00119   nsAString::const_iterator begin;
00120   aStr.BeginReading(begin);
00121   *aData = begin.get();
00122   return begin.size_forward();
00123 }
00124 
00125 NS_STRINGAPI(PRUint32)
00126 NS_StringGetMutableData(nsAString &aStr, PRUint32 aDataLength,
00127                         PRUnichar **aData)
00128 {
00129   if (aDataLength != PR_UINT32_MAX) {
00130     aStr.SetLength(aDataLength);
00131     if (aStr.Length() != aDataLength) {
00132       *aData = nsnull;
00133       return 0;
00134     }
00135   }
00136 
00137   nsAString::iterator begin;
00138   aStr.BeginWriting(begin);
00139   *aData = begin.get();
00140   return begin.size_forward();
00141 }
00142 
00143 NS_STRINGAPI(PRUnichar *)
00144 NS_StringCloneData(const nsAString &aStr)
00145 {
00146   return ToNewUnicode(aStr);
00147 }
00148 
00149 NS_STRINGAPI(nsresult)
00150 NS_StringSetData(nsAString &aStr, const PRUnichar *aData, PRUint32 aDataLength)
00151 {
00152   aStr.Assign(aData, aDataLength);
00153   return NS_OK; // XXX report errors
00154 }
00155 
00156 NS_STRINGAPI(nsresult)
00157 NS_StringSetDataRange(nsAString &aStr,
00158                       PRUint32 aCutOffset, PRUint32 aCutLength,
00159                       const PRUnichar *aData, PRUint32 aDataLength)
00160 {
00161   if (aCutOffset == PR_UINT32_MAX)
00162   {
00163     // append case
00164     if (aData)
00165       aStr.Append(aData, aDataLength);
00166     return NS_OK; // XXX report errors
00167   }
00168 
00169   if (aCutLength == PR_UINT32_MAX)
00170     aCutLength = aStr.Length() - aCutOffset;
00171 
00172   if (aData)
00173   {
00174     if (aDataLength == PR_UINT32_MAX)
00175       aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData));
00176     else
00177       aStr.Replace(aCutOffset, aCutLength, Substring(aData, aData + aDataLength));
00178   }
00179   else
00180     aStr.Cut(aCutOffset, aCutLength);
00181 
00182   return NS_OK; // XXX report errors
00183 }
00184 
00185 NS_STRINGAPI(nsresult)
00186 NS_StringCopy(nsAString &aDest, const nsAString &aSrc)
00187 {
00188   aDest.Assign(aSrc);
00189   return NS_OK; // XXX report errors
00190 }
00191 
00192 /* ------------------------------------------------------------------------- */
00193 
00194 NS_STRINGAPI(nsresult)
00195 NS_CStringContainerInit(nsCStringContainer &aContainer)
00196 {
00197   NS_ASSERTION(sizeof(nsCStringContainer) >= sizeof(nsCString),
00198       "nsCStringContainer is not large enough");
00199 
00200   // use placement new to avoid heap allocating nsCString object
00201   new (&aContainer) nsCString();
00202 
00203   return NS_OK;
00204 }
00205 
00206 NS_STRINGAPI(nsresult)
00207 NS_CStringContainerInit2(nsCStringContainer &aContainer,
00208                          const char         *aData,
00209                          PRUint32            aDataLength,
00210                          PRUint32            aFlags)
00211 {
00212   NS_ASSERTION(sizeof(nsCStringContainer) >= sizeof(nsCString),
00213       "nsStringContainer is not large enough");
00214 
00215   if (!aData)
00216   {
00217     new (&aContainer) nsCString();
00218   }
00219   else
00220   {
00221     if (aDataLength == PR_UINT32_MAX)
00222     {
00223       NS_ENSURE_ARG(!(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING));
00224       aDataLength = nsCharTraits<char>::length(aData);
00225     }
00226 
00227     if (aFlags & (NS_CSTRING_CONTAINER_INIT_DEPEND |
00228                   NS_CSTRING_CONTAINER_INIT_ADOPT))
00229     {
00230       PRUint32 flags;
00231       if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)
00232         flags = nsCSubstring::F_NONE;
00233       else
00234         flags = nsCSubstring::F_TERMINATED;
00235 
00236       if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT)
00237         flags |= nsCSubstring::F_OWNED;
00238 
00239       new (&aContainer) nsCSubstring(NS_CONST_CAST(char *, aData),
00240                                      aDataLength, flags);
00241     }
00242     else
00243     {
00244       new (&aContainer) nsCString(aData, aDataLength);
00245     }
00246   }
00247 
00248   return NS_OK;
00249 }
00250 
00251 NS_STRINGAPI(void)
00252 NS_CStringContainerFinish(nsCStringContainer &aContainer)
00253 {
00254   // call the nsCString dtor
00255   NS_REINTERPRET_CAST(nsCString *, &aContainer)->~nsCString();
00256 }
00257 
00258 /* ------------------------------------------------------------------------- */
00259 
00260 NS_STRINGAPI(PRUint32)
00261 NS_CStringGetData(const nsACString &aStr, const char **aData,
00262                   PRBool *aTerminated)
00263 {
00264   if (aTerminated)
00265     *aTerminated = aStr.IsTerminated();
00266 
00267   nsACString::const_iterator begin;
00268   aStr.BeginReading(begin);
00269   *aData = begin.get();
00270   return begin.size_forward();
00271 }
00272 
00273 NS_STRINGAPI(PRUint32)
00274 NS_CStringGetMutableData(nsACString &aStr, PRUint32 aDataLength, char **aData)
00275 {
00276   if (aDataLength != PR_UINT32_MAX) {
00277     aStr.SetLength(aDataLength);
00278     if (aStr.Length() != aDataLength) {
00279       *aData = nsnull;
00280       return 0;
00281     }
00282   }
00283 
00284   nsACString::iterator begin;
00285   aStr.BeginWriting(begin);
00286   *aData = begin.get();
00287   return begin.size_forward();
00288 }
00289 
00290 NS_STRINGAPI(char *)
00291 NS_CStringCloneData(const nsACString &aStr)
00292 {
00293   return ToNewCString(aStr);
00294 }
00295 
00296 NS_STRINGAPI(nsresult)
00297 NS_CStringSetData(nsACString &aStr, const char *aData, PRUint32 aDataLength)
00298 {
00299   aStr.Assign(aData, aDataLength);
00300   return NS_OK; // XXX report errors
00301 }
00302 
00303 NS_STRINGAPI(nsresult)
00304 NS_CStringSetDataRange(nsACString &aStr,
00305                        PRUint32 aCutOffset, PRUint32 aCutLength,
00306                        const char *aData, PRUint32 aDataLength)
00307 {
00308   if (aCutOffset == PR_UINT32_MAX)
00309   {
00310     // append case
00311     if (aData)
00312       aStr.Append(aData, aDataLength);
00313     return NS_OK; // XXX report errors
00314   }
00315 
00316   if (aCutLength == PR_UINT32_MAX)
00317     aCutLength = aStr.Length() - aCutOffset;
00318 
00319   if (aData)
00320   {
00321     if (aDataLength == PR_UINT32_MAX)
00322       aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData));
00323     else
00324       aStr.Replace(aCutOffset, aCutLength, Substring(aData, aData + aDataLength));
00325   }
00326   else
00327     aStr.Cut(aCutOffset, aCutLength);
00328 
00329   return NS_OK; // XXX report errors
00330 }
00331 
00332 NS_STRINGAPI(nsresult)
00333 NS_CStringCopy(nsACString &aDest, const nsACString &aSrc)
00334 {
00335   aDest.Assign(aSrc);
00336   return NS_OK; // XXX report errors
00337 }
00338 
00339 /* ------------------------------------------------------------------------- */
00340 
00341 NS_STRINGAPI(nsresult)
00342 NS_CStringToUTF16(const nsACString &aSrc,
00343                   nsCStringEncoding aSrcEncoding,
00344                   nsAString &aDest)
00345 {
00346   switch (aSrcEncoding)
00347   {
00348     case NS_CSTRING_ENCODING_ASCII:
00349       CopyASCIItoUTF16(aSrc, aDest);
00350       break;
00351     case NS_CSTRING_ENCODING_UTF8:
00352       CopyUTF8toUTF16(aSrc, aDest);
00353       break;
00354     case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM:
00355       NS_CopyNativeToUnicode(aSrc, aDest);
00356       break;
00357     default:
00358       return NS_ERROR_NOT_IMPLEMENTED;
00359   }
00360 
00361   return NS_OK; // XXX report errors
00362 }
00363 
00364 NS_STRINGAPI(nsresult)
00365 NS_UTF16ToCString(const nsAString &aSrc,
00366                   nsCStringEncoding aDestEncoding,
00367                   nsACString &aDest)
00368 {
00369   switch (aDestEncoding)
00370   {
00371     case NS_CSTRING_ENCODING_ASCII:
00372       LossyCopyUTF16toASCII(aSrc, aDest);
00373       break;
00374     case NS_CSTRING_ENCODING_UTF8:
00375       CopyUTF16toUTF8(aSrc, aDest);
00376       break;
00377     case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM:
00378       NS_CopyUnicodeToNative(aSrc, aDest);
00379       break;
00380     default:
00381       return NS_ERROR_NOT_IMPLEMENTED;
00382   }
00383 
00384   return NS_OK; // XXX report errors
00385 }