Back to index

lightning-sunbird  0.9+nobinonly
TestMinStringAPI.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 #ifdef MOZILLA_INTERNAL_API
00039 #undef MOZILLA_INTERNAL_API
00040 #endif
00041 
00042 #include <stdio.h>
00043 #include "nsStringAPI.h"
00044 #include "nsCRT.h"
00045 
00046 static const char kAsciiData[] = "hello world";
00047 
00048 static const PRUnichar kUnicodeData[] =
00049   {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
00050 
00051 static PRBool test_basic_1()
00052   {
00053     nsCStringContainer s;
00054     NS_CStringContainerInit(s);
00055 
00056     const char *ptr;
00057     PRUint32 len;
00058     char *clone;
00059 
00060     NS_CStringGetData(s, &ptr);
00061     if (ptr == nsnull || *ptr != '\0')
00062       {
00063         NS_ERROR("unexpected result");
00064         return PR_FALSE;
00065       }
00066 
00067     NS_CStringSetData(s, kAsciiData, PR_UINT32_MAX);
00068     len = NS_CStringGetData(s, &ptr);
00069     if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
00070       {
00071         NS_ERROR("unexpected result");
00072         return PR_FALSE;
00073       }
00074     if (len != sizeof(kAsciiData)-1)
00075       {
00076         NS_ERROR("unexpected result");
00077         return PR_FALSE;
00078       }
00079 
00080     clone = NS_CStringCloneData(s);
00081     if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
00082       {
00083         NS_ERROR("unexpected result");
00084         return PR_FALSE;
00085       }
00086     nsMemory::Free(clone);
00087 
00088     nsCStringContainer temp;
00089     NS_CStringContainerInit(temp);
00090     NS_CStringCopy(temp, s);
00091 
00092     len = NS_CStringGetData(temp, &ptr);
00093     if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
00094       {
00095         NS_ERROR("unexpected result");
00096         return PR_FALSE;
00097       }
00098     if (len != sizeof(kAsciiData)-1)
00099       {
00100         NS_ERROR("unexpected result");
00101         return PR_FALSE;
00102       }
00103 
00104     NS_CStringContainerFinish(temp);
00105 
00106     NS_CStringContainerFinish(s);
00107     return PR_TRUE;
00108   }
00109 
00110 static PRBool test_basic_2()
00111   {
00112     nsStringContainer s;
00113     NS_StringContainerInit(s);
00114 
00115     const PRUnichar *ptr;
00116     PRUint32 len;
00117     PRUnichar *clone;
00118 
00119     NS_StringGetData(s, &ptr);
00120     if (ptr == nsnull || *ptr != '\0')
00121       {
00122         NS_ERROR("unexpected result");
00123         return PR_FALSE;
00124       }
00125 
00126     NS_StringSetData(s, kUnicodeData, PR_UINT32_MAX);
00127     len = NS_StringGetData(s, &ptr);
00128     if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
00129       {
00130         NS_ERROR("unexpected result");
00131         return PR_FALSE;
00132       }
00133     if (len != sizeof(kUnicodeData)/2 - 1)
00134       {
00135         NS_ERROR("unexpected result");
00136         return PR_FALSE;
00137       }
00138 
00139     clone = NS_StringCloneData(s);
00140     if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
00141       {
00142         NS_ERROR("unexpected result");
00143         return PR_FALSE;
00144       }
00145     nsMemory::Free(clone);
00146 
00147     nsStringContainer temp;
00148     NS_StringContainerInit(temp);
00149     NS_StringCopy(temp, s);
00150 
00151     len = NS_StringGetData(temp, &ptr);
00152     if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
00153       {
00154         NS_ERROR("unexpected result");
00155         return PR_FALSE;
00156       }
00157     if (len != sizeof(kUnicodeData)/2 - 1)
00158       {
00159         NS_ERROR("unexpected result");
00160         return PR_FALSE;
00161       }
00162 
00163     NS_StringContainerFinish(temp);
00164 
00165     NS_StringContainerFinish(s);
00166 
00167     return PR_TRUE;
00168   }
00169 
00170 static PRBool test_convert()
00171   {
00172     nsStringContainer s;
00173     NS_StringContainerInit(s);
00174     NS_StringSetData(s, kUnicodeData, sizeof(kUnicodeData)/2 - 1);
00175 
00176     nsCStringContainer temp;
00177     NS_CStringContainerInit(temp);
00178 
00179     const char *data;
00180 
00181     NS_UTF16ToCString(s, NS_CSTRING_ENCODING_ASCII, temp);
00182     NS_CStringGetData(temp, &data);
00183     if (strcmp(data, kAsciiData) != 0)
00184       return PR_FALSE;
00185 
00186     NS_UTF16ToCString(s, NS_CSTRING_ENCODING_UTF8, temp);
00187     NS_CStringGetData(temp, &data);
00188     if (strcmp(data, kAsciiData) != 0)
00189       return PR_FALSE;
00190 
00191     NS_CStringContainerFinish(temp);
00192 
00193     NS_StringContainerFinish(s);
00194     return PR_TRUE;
00195   }
00196 
00197 static PRBool test_append()
00198   {
00199     nsCStringContainer s;
00200     NS_CStringContainerInit(s);
00201 
00202     NS_CStringSetData(s, "foo");
00203     NS_CStringAppendData(s, "bar");
00204 
00205     NS_CStringContainerFinish(s);
00206     return PR_TRUE;
00207   }
00208 
00209 // Replace all occurances of |matchVal| with |newVal|
00210 static void ReplaceSubstring( nsACString& str,
00211                               const nsACString& matchVal,
00212                               const nsACString& newVal )
00213   {
00214     const char* sp, *mp, *np;
00215     PRUint32 sl, ml, nl;
00216 
00217     sl = NS_CStringGetData(str, &sp);
00218     ml = NS_CStringGetData(matchVal, &mp);
00219     nl = NS_CStringGetData(newVal, &np);
00220 
00221     for (const char* iter = sp; iter <= sp + sl - ml; ++iter)
00222       {
00223         if (memcmp(iter, mp, ml) == 0)
00224           {
00225             PRUint32 offset = iter - sp;
00226 
00227             NS_CStringSetDataRange(str, offset, ml, np, nl);
00228 
00229             sl = NS_CStringGetData(str, &sp);
00230 
00231             iter = sp + offset + nl - 1;
00232           }
00233       }
00234   }
00235 
00236 static PRBool test_replace_driver(const char *strVal,
00237                                   const char *matchVal,
00238                                   const char *newVal,
00239                                   const char *finalVal)
00240   {
00241     nsCStringContainer a;
00242     NS_CStringContainerInit(a);
00243     NS_CStringSetData(a, strVal);
00244 
00245     nsCStringContainer b;
00246     NS_CStringContainerInit(b);
00247     NS_CStringSetData(b, matchVal);
00248 
00249     nsCStringContainer c;
00250     NS_CStringContainerInit(c);
00251     NS_CStringSetData(c, newVal);
00252 
00253     ReplaceSubstring(a, b, c);
00254 
00255     const char *data;
00256     NS_CStringGetData(a, &data);
00257     if (strcmp(data, finalVal) != 0)
00258       return PR_FALSE;
00259 
00260     NS_CStringContainerFinish(c);
00261     NS_CStringContainerFinish(b);
00262     NS_CStringContainerFinish(a);
00263     return PR_TRUE;
00264   }
00265 
00266 static PRBool test_replace()
00267   {
00268     PRBool rv;
00269 
00270     rv = test_replace_driver("hello world, hello again!",
00271                              "hello",
00272                              "goodbye",
00273                              "goodbye world, goodbye again!");
00274     if (!rv)
00275       return rv;
00276 
00277     rv = test_replace_driver("foofoofoofoo!",
00278                              "foo",
00279                              "bar",
00280                              "barbarbarbar!");
00281     if (!rv)
00282       return rv;
00283 
00284     rv = test_replace_driver("foo bar systems",
00285                              "xyz",
00286                              "crazy",
00287                              "foo bar systems");
00288     if (!rv)
00289       return rv;
00290 
00291     rv = test_replace_driver("oh",
00292                              "xyz",
00293                              "crazy",
00294                              "oh");
00295     if (!rv)
00296       return rv;
00297 
00298     return PR_TRUE;
00299   }
00300 
00301 static const char* kWhitespace="\b\t\r\n ";
00302 
00303 static void
00304 CompressWhitespace(nsACString &str)
00305   {
00306     const char *p;
00307     PRInt32 i, len = (PRInt32) NS_CStringGetData(str, &p);
00308 
00309     // trim leading whitespace
00310 
00311     for (i=0; i<len; ++i)
00312       {
00313         if (!strchr(kWhitespace, (char) p[i]))
00314           break;
00315       }
00316 
00317     if (i>0)
00318       {
00319         NS_CStringCutData(str, 0, i);
00320         len = (PRInt32) NS_CStringGetData(str, &p);
00321       }
00322 
00323     // trim trailing whitespace
00324 
00325     for (i=len-1; i>=0; --i)
00326       {
00327         if (!strchr(kWhitespace, (char) p[i]))
00328           break;
00329       }
00330 
00331     if (++i < len)
00332       NS_CStringCutData(str, i, len - i);
00333   }
00334 
00335 static PRBool test_compress_ws()
00336   {
00337     nsCStringContainer s;
00338     NS_CStringContainerInit(s);
00339     NS_CStringSetData(s, " \thello world\r  \n");
00340     CompressWhitespace(s);
00341     const char *d;
00342     NS_CStringGetData(s, &d);
00343     PRBool rv = !strcmp(d, "hello world");
00344     if (!rv)
00345       printf("=> \"%s\"\n", d);
00346     NS_CStringContainerFinish(s);
00347     return rv;
00348   }
00349 
00350 static PRBool test_depend()
00351   {
00352     static const char kData[] = "hello world";
00353 
00354     nsCStringContainer s;
00355     NS_ENSURE_SUCCESS(
00356         NS_CStringContainerInit2(s, kData, sizeof(kData)-1,
00357                                  NS_CSTRING_CONTAINER_INIT_DEPEND),
00358         PR_FALSE);
00359 
00360     const char *sd;
00361     NS_CStringGetData(s, &sd);
00362 
00363     PRBool rv = (sd == kData);
00364     NS_CStringContainerFinish(s);
00365     return rv;
00366   }
00367 
00368 static PRBool test_depend_sub()
00369   {
00370     static const char kData[] = "hello world";
00371 
00372     nsCStringContainer s;
00373     NS_ENSURE_SUCCESS(
00374         NS_CStringContainerInit2(s, kData, sizeof(kData)-1,
00375                                  NS_CSTRING_CONTAINER_INIT_DEPEND |
00376                                  NS_CSTRING_CONTAINER_INIT_SUBSTRING),
00377         PR_FALSE);
00378 
00379     PRBool terminated;
00380     const char *sd;
00381     PRUint32 len = NS_CStringGetData(s, &sd, &terminated);
00382 
00383     PRBool rv = (sd == kData && len == sizeof(kData)-1 && !terminated);
00384     NS_CStringContainerFinish(s);
00385     return rv;
00386   }
00387 
00388 static PRBool test_adopt()
00389   {
00390     static const char kData[] = "hello world";
00391 
00392     char *data = (char *) nsMemory::Clone(kData, sizeof(kData));
00393     if (!data)
00394       return PR_FALSE;
00395 
00396     nsCStringContainer s;
00397     NS_ENSURE_SUCCESS(
00398         NS_CStringContainerInit2(s, data, PR_UINT32_MAX,
00399                                  NS_CSTRING_CONTAINER_INIT_ADOPT),
00400         PR_FALSE); // leaks data on failure *shrug*
00401 
00402     const char *sd;
00403     NS_CStringGetData(s, &sd);
00404 
00405     PRBool rv = (sd == data);
00406     NS_CStringContainerFinish(s);
00407     return rv;
00408   }
00409 
00410 static PRBool test_adopt_sub()
00411   {
00412     static const char kData[] = "hello world";
00413 
00414     char *data = (char *) nsMemory::Clone(kData, sizeof(kData)-1);
00415     if (!data)
00416       return PR_FALSE;
00417 
00418     nsCStringContainer s;
00419     NS_ENSURE_SUCCESS(
00420         NS_CStringContainerInit2(s, data, sizeof(kData)-1,
00421                                  NS_CSTRING_CONTAINER_INIT_ADOPT |
00422                                  NS_CSTRING_CONTAINER_INIT_SUBSTRING),
00423         PR_FALSE); // leaks data on failure *shrug*
00424 
00425     PRBool terminated;
00426     const char *sd;
00427     PRUint32 len = NS_CStringGetData(s, &sd, &terminated);
00428 
00429     PRBool rv = (sd == data && len == sizeof(kData)-1 && !terminated);
00430     NS_CStringContainerFinish(s);
00431     return rv;
00432   }
00433 
00434 static PRBool test_mutation()
00435   {
00436     nsCStringContainer s;
00437     NS_CStringContainerInit(s);
00438 
00439     const char kText[] = "Every good boy does fine.";
00440 
00441     char *buf;
00442     PRUint32 len = NS_CStringGetMutableData(s, sizeof(kText) - 1, &buf);
00443     if (!buf || len != sizeof(kText) - 1)
00444       return PR_FALSE;
00445     memcpy(buf, kText, sizeof(kText));
00446 
00447     const char *data;
00448     NS_CStringGetData(s, &data);
00449     if (strcmp(data, kText) != 0)
00450       return PR_FALSE;
00451 
00452     PRUint32 newLen = len + 1;
00453     len = NS_CStringGetMutableData(s, newLen, &buf);
00454     if (!buf || len != newLen)
00455       return PR_FALSE;
00456 
00457     buf[len - 1] = '.';
00458 
00459     NS_CStringGetData(s, &data);
00460     if (strncmp(data, kText, len - 1) != 0 || data[len - 1] != '.')
00461       return PR_FALSE;
00462 
00463     NS_CStringContainerFinish(s);
00464     return PR_TRUE;
00465   }
00466 
00467 //----
00468 
00469 typedef PRBool (*TestFunc)();
00470 
00471 static const struct Test
00472   {
00473     const char* name;
00474     TestFunc    func;
00475   }
00476 tests[] =
00477   {
00478     { "test_basic_1", test_basic_1 },
00479     { "test_basic_2", test_basic_2 },
00480     { "test_convert", test_convert },
00481     { "test_append", test_append },
00482     { "test_replace", test_replace },
00483     { "test_compress_ws", test_compress_ws },
00484     { "test_depend", test_depend },
00485     { "test_depend_sub", test_depend_sub },
00486     { "test_adopt", test_adopt },
00487     { "test_adopt_sub", test_adopt_sub },
00488     { "test_mutation", test_mutation },
00489     { nsnull, nsnull }
00490   };
00491 
00492 //----
00493 
00494 int main(int argc, char **argv)
00495   {
00496     int count = 1;
00497     if (argc > 1)
00498       count = atoi(argv[1]);
00499 
00500     while (count--)
00501       {
00502         for (const Test* t = tests; t->name != nsnull; ++t)
00503           {
00504             printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE");
00505           }
00506       }
00507     
00508     return 0;
00509   }