Back to index

lightning-sunbird  0.9+nobinonly
TestLineBreak.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or 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 #include <stdio.h>
00038 #include "nsXPCOM.h"
00039 #include "nsIComponentManager.h"
00040 #include "nsISupports.h"
00041 #include "nsServiceManagerUtils.h"
00042 #include "nsILineBreakerFactory.h"
00043 #include "nsILineBreaker.h"
00044 #include "nsIWordBreakerFactory.h"
00045 #include "nsIWordBreaker.h"
00046 #include "nsIBreakState.h"
00047 #include "nsLWBrkCIID.h"
00048 #include "nsReadableUtils.h"
00049 
00050 #define WORK_AROUND_SERVICE_MANAGER_ASSERT
00051 
00052 IMPL_NS_IBREAKSTATE( nsBreakState )
00053 
00054 NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
00055 
00056 
00057 static char teng1[] = 
00058 //          1         2         3         4         5         6         7
00059 //01234567890123456789012345678901234567890123456789012345678901234567890123456789
00060  "This is a test to test(reasonable) line    break. This 0.01123 = 45 x 48.";
00061 
00062 static PRUint32 exp1[] = {
00063   4,5,7,8,9,10,14,15,17,18,22,34,35,39,40,41,42,43,49,50,54,55,62,63,64,65,
00064   67,68,69,70
00065 };
00066 
00067 static PRUint32 wexp1[] = {
00068 
00069   4,5,7,8,9,10,14,15,17,18,22,23,33,34,35,39,43,48,49,50,54,55,56,57,62,63,
00070   64,65,67,68,69,70,72
00071 };
00072 //          1         2         3         4         5         6         7
00073 //01234567890123456789012345678901234567890123456789012345678901234567890123456789
00074 static char teng2[] = 
00075  "()((reasonab(l)e) line  break. .01123=45x48.";
00076 
00077 static PRUint32 lexp2[] = {
00078   2,12,15,17,18,22,23,24,30,31,37,38,
00079 };
00080 static PRUint32 wexp2[] = {
00081   4,12,13,14,15,16,17,18,22,24,29,30,31,32,37,38,43
00082 };
00083 
00084 //          1         2         3         4         5         6         7
00085 //01234567890123456789012345678901234567890123456789012345678901234567890123456789
00086 static char teng3[] = 
00087  "It's a test to test(ronae ) line break....";
00088 static PRUint32 exp3[] = {
00089   4, 5, 6,7,11,12,14,15,19,25,27,28,32,33
00090 };
00091 static PRUint32 wexp3[] = {
00092   4,5,6,7,11,12,14,15,19,20,25,26,27,28,32,33,38
00093 };
00094 
00095 static char ruler1[] =
00096 "          1         2         3         4         5         6         7  ";
00097 static char ruler2[] =
00098 "0123456789012345678901234567890123456789012345678901234567890123456789012";
00099 
00100 
00101 PRBool TestASCIILB(nsILineBreaker *lb,
00102                  const char* in, const PRUint32 len, 
00103                  const PRUint32* out, PRUint32 outlen)
00104 {
00105          nsAutoString eng1; eng1.AssignWithConversion(in);
00106          PRUint32 i,j;
00107          PRUint32 res[256];
00108          PRBool ok = PR_TRUE;
00109          PRUint32 curr;
00110          PRBool finishThisFrag = PR_FALSE;
00111          for(i = 0, curr = 0; ((! finishThisFrag) && (i < 256)); i++)
00112          {
00113             lb->Next(eng1.get(), eng1.Length(), curr, 
00114                     &curr,
00115                     &finishThisFrag);
00116             res [i] = curr;
00117     
00118          }
00119          if (i != outlen)
00120          {
00121             ok = PR_FALSE;
00122             printf("WARNING!!! return size wrong, expect %d bet got %d \n",
00123                    outlen, i);
00124          }
00125          printf("string  = \n%s\n", in);
00126          printf("%s\n", ruler1);
00127          printf("%s\n", ruler2);
00128          printf("Expect = \n");
00129          for(j=0;j<outlen;j++)
00130          {
00131             printf("%d,", out[j]);
00132          }
00133          printf("\nResult = \n");
00134          for(j=0;j<i;j++)
00135          {
00136             printf("%d,", res[j]);
00137          }
00138          printf("\n");
00139          for(j=0;j<i;j++)
00140          {
00141             if(j < outlen)
00142             {
00143                 if (res[j] != out[j])
00144                 {
00145                    ok = PR_FALSE;
00146                    printf("[%d] expect %d but got %d\n", j, out[j], res[j]);
00147                 }
00148             } else {
00149                    ok = PR_FALSE;
00150                    printf("[%d] additional %d\n", j, res[j]);
00151             }
00152          }
00153          return ok;
00154 }
00155 
00156 PRBool TestASCIIWB(nsIWordBreaker *lb,
00157                  const char* in, const PRUint32 len, 
00158                  const PRUint32* out, PRUint32 outlen)
00159 {
00160          nsAutoString eng1; eng1.AssignWithConversion(in);
00161          // nsBreakState bk(eng1.get(), eng1.Length());
00162 
00163          PRUint32 i,j;
00164          PRUint32 res[256];
00165          PRBool ok = PR_TRUE;
00166          PRBool done;
00167          PRUint32 curr =0;
00168 
00169          for(i = 0, lb->NextWord(eng1.get(), eng1.Length(), curr, &curr, &done);
00170                     (! done ) && (i < 256);
00171                     lb->NextWord(eng1.get(), eng1.Length(), curr, &curr, &done), i++)
00172          {
00173             res [i] = curr;
00174          }
00175          if (i != outlen)
00176          {
00177             ok = PR_FALSE;
00178             printf("WARNING!!! return size wrong, expect %d bet got %d\n",
00179                    outlen, i);
00180          }
00181          printf("string  = \n%s\n", in);
00182          printf("%s\n", ruler1);
00183          printf("%s\n", ruler2);
00184          printf("Expect = \n");
00185          for(j=0;j<outlen;j++)
00186          {
00187             printf("%d,", out[j]);
00188          }
00189          printf("\nResult = \n");
00190          for(j=0;j<i;j++)
00191          {
00192             printf("%d,", res[j]);
00193          }
00194          printf("\n");
00195          for(j=0;j<i;j++)
00196          {
00197             if(j < outlen)
00198             {
00199                 if (res[j] != out[j])
00200                 {
00201                    ok = PR_FALSE;
00202                    printf("[%d] expect %d but got %d\n", j, out[j], res[j]);
00203                 }
00204             } else {
00205                    ok = PR_FALSE;
00206                    printf("[%d] additional %d\n", j, res[j]);
00207             }
00208          }
00209          return ok;
00210 }
00211      
00212      
00213 PRBool TestLineBreaker()
00214 {
00215    printf("==================================\n");
00216    printf("Finish nsILineBreakerFactory Test \n");
00217    printf("==================================\n");
00218    nsILineBreakerFactory *t = NULL;
00219    nsresult res;
00220    PRBool ok = PR_TRUE;
00221    res = CallGetService(kLWBrkCID, &t);
00222            
00223    printf("Test 1 - GetService():\n");
00224    if(NS_FAILED(res) || ( t == NULL ) ) {
00225      printf("\t1st GetService failed\n");
00226      ok = PR_FALSE;
00227    } else {
00228 #ifdef WORD_AROUND_SERVICE_MANAGER_ASSERT
00229      NS_RELEASE(t);
00230 #endif
00231    }
00232 
00233    res = CallGetService(kLWBrkCID, &t);
00234            
00235    if(NS_FAILED(res) || ( t == NULL ) ) {
00236      printf("\t2nd GetService failed\n");
00237      ok = PR_FALSE;
00238    } else {
00239 
00240      printf("Test 3 - GetLineBreaker():\n");
00241      nsILineBreaker *lb;
00242 
00243      nsAutoString lb_arg;
00244      res = t->GetBreaker(lb_arg, &lb);
00245      if(NS_FAILED(res) || (lb == NULL)) {
00246          printf("GetBreaker(nsILineBreaker*) failed\n");
00247          ok = PR_FALSE;
00248      } else {
00249          
00250          printf("Test 4 - {First,Next}ForwardBreak():\n");
00251          if( TestASCIILB(lb, teng1, sizeof(teng1)/sizeof(char), 
00252                    exp1, sizeof(exp1)/sizeof(PRUint32)) )
00253          {
00254            printf("Test 4 Passed\n\n");
00255          } else {
00256            ok = PR_FALSE;
00257            printf("Test 4 Failed\n\n");
00258          }
00259 
00260          printf("Test 5 - {First,Next}ForwardBreak():\n");
00261          if(TestASCIILB(lb, teng2, sizeof(teng2)/sizeof(char), 
00262                    lexp2, sizeof(lexp2)/sizeof(PRUint32)) )
00263          {
00264            printf("Test 5 Passed\n\n");
00265          } else {
00266            ok = PR_FALSE;
00267            printf("Test 5 Failed\n\n");
00268          }
00269 
00270          printf("Test 6 - {First,Next}ForwardBreak():\n");
00271          if(TestASCIILB(lb, teng3, sizeof(teng3)/sizeof(char), 
00272                    exp3, sizeof(exp3)/sizeof(PRUint32)) )
00273          {
00274            printf("Test 6 Passed\n\n");
00275          } else {
00276            ok = PR_FALSE;
00277            printf("Test 6 Failed\n\n");
00278          }
00279 
00280 
00281          NS_IF_RELEASE(lb);
00282      }
00283 
00284 #ifdef WORD_AROUND_SERVICE_MANAGER_ASSERT
00285      NS_RELEASE(t);
00286 #endif
00287    }
00288    printf("==================================\n");
00289    printf("Finish nsILineBreakerFactory Test \n");
00290    printf("==================================\n");
00291 
00292    return ok;
00293 }
00294 
00295 PRBool TestWordBreaker()
00296 {
00297    printf("==================================\n");
00298    printf("Finish nsIWordBreakerFactory Test \n");
00299    printf("==================================\n");
00300    nsIWordBreakerFactory *t = NULL;
00301    nsresult res;
00302    PRBool ok = PR_TRUE;
00303    res = CallGetService(kLWBrkCID, &t);
00304            
00305    printf("Test 1 - GetService():\n");
00306    if(NS_FAILED(res) || ( t == NULL ) ) {
00307      printf("\t1st GetService failed\n");
00308      ok = PR_FALSE;
00309    } else {
00310      NS_RELEASE(t);
00311    }
00312 
00313    res = CallGetService(kLWBrkCID, &t);
00314            
00315    if(NS_FAILED(res) || ( t == NULL ) ) {
00316      printf("\t2nd GetService failed\n");
00317      ok = PR_FALSE;
00318    } else {
00319 
00320      printf("Test 3 - GetWordBreaker():\n");
00321      nsIWordBreaker *lb;
00322 
00323      nsAutoString lb_arg;
00324      res = t->GetBreaker(lb_arg, &lb);
00325      if(NS_FAILED(res) || (lb == NULL)) {
00326          printf("GetBreaker(nsIWordBreaker*) failed\n");
00327          ok = PR_FALSE;
00328      } else {
00329          
00330          printf("Test 4 - {First,Next}ForwardBreak():\n");
00331          if( TestASCIIWB(lb, teng1, sizeof(teng1)/sizeof(char), 
00332                    wexp1, sizeof(wexp1)/sizeof(PRUint32)) )
00333          {
00334            printf("Test 4 Passed\n\n");
00335          } else {
00336            ok = PR_FALSE;
00337            printf("Test 4 Failed\n\n");
00338          }
00339 
00340          printf("Test 5 - {First,Next}ForwardBreak():\n");
00341          if(TestASCIIWB(lb, teng2, sizeof(teng2)/sizeof(char), 
00342                    wexp2, sizeof(wexp2)/sizeof(PRUint32)) )
00343          {
00344            printf("Test 5 Passed\n\n");
00345          } else {
00346            ok = PR_FALSE;
00347            printf("Test 5 Failed\n\n");
00348          }
00349 
00350          printf("Test 6 - {First,Next}ForwardBreak():\n");
00351          if(TestASCIIWB(lb, teng3, sizeof(teng3)/sizeof(char), 
00352                    wexp3, sizeof(wexp3)/sizeof(PRUint32)) )
00353          {
00354            printf("Test 6 Passed\n\n");
00355          } else {
00356            ok = PR_FALSE;
00357            printf("Test 6 Failed\n\n");
00358          }
00359 
00360 
00361          NS_IF_RELEASE(lb);
00362      }
00363 
00364      NS_RELEASE(t);
00365    }
00366    printf("==================================\n");
00367    printf("Finish nsIWordBreakerFactory Test \n");
00368    printf("==================================\n");
00369 
00370    return ok;
00371 }
00372 
00373 void   SamplePrintWordWithBreak();
00374 void   SampleFindWordBreakFromPosition(PRUint32 fragN, PRUint32 offset);
00375 // Sample Code
00376 
00377 //                          012345678901234
00378 static const char wb0[] =  "T";
00379 static const char wb1[] =  "h";
00380 static const char wb2[] =  "is   is a int";
00381 static const char wb3[] =  "ernationali";
00382 static const char wb4[] =  "zation work.";
00383 
00384 static const char* wb[] = {wb0,wb1,wb2,wb3,wb4};
00385 void SampleWordBreakUsage()
00386 {
00387    SamplePrintWordWithBreak();
00388    SampleFindWordBreakFromPosition(0,0); // This
00389    SampleFindWordBreakFromPosition(1,0); // This
00390    SampleFindWordBreakFromPosition(2,0); // This
00391    SampleFindWordBreakFromPosition(2,1); // This
00392    SampleFindWordBreakFromPosition(2,9); // [space]
00393    SampleFindWordBreakFromPosition(2,10); // internationalization
00394    SampleFindWordBreakFromPosition(3,4);  // internationalization
00395    SampleFindWordBreakFromPosition(3,8);  // internationalization
00396    SampleFindWordBreakFromPosition(4,6);  // [space]
00397    SampleFindWordBreakFromPosition(4,7);  // work
00398 }
00399  
00400 
00401 void SamplePrintWordWithBreak()
00402 {
00403    PRUint32 numOfFragment = sizeof(wb) / sizeof(char*);
00404    nsIWordBreakerFactory *t = NULL;
00405 
00406    nsresult res = CallGetService(kLWBrkCID, &t);
00407    nsIWordBreaker *wbk;
00408 
00409    nsAutoString wb_arg;
00410    res = t->GetBreaker(wb_arg, &wbk);
00411 
00412    nsAutoString result;
00413    nsAutoString tmp;
00414 
00415    for(PRUint32 i = 0; i < numOfFragment; i++)
00416    {
00417       nsAutoString fragText; fragText.AssignWithConversion(wb[i]); 
00418       // nsBreakState bk(fragText.get(), fragText.Length());
00419 
00420       PRUint32 cur = 0;
00421       PRBool done;
00422       res = wbk->NextWord(fragText.get(), fragText.Length(), cur, &cur, &done);
00423       PRUint32 start = 0;
00424       for(PRUint32 j = 0; ! done ; j++)
00425       {
00426             tmp.Truncate();
00427             fragText.Mid(tmp, start, cur - start);
00428             result.Append(tmp);
00429             result.AppendLiteral("^");
00430             start = cur;
00431             wbk->NextWord(fragText.get(), fragText.Length(), cur, &cur, &done);
00432       }
00433 
00434       tmp.Truncate();
00435       fragText.Mid(tmp, start, fragText.Length() - start);
00436       result.Append(tmp);
00437 
00438 
00439       if( i != (numOfFragment -1 ))
00440       {
00441         nsAutoString nextFragText; nextFragText.AssignWithConversion(wb[i+1]);
00442  
00443         PRBool canBreak = PR_TRUE;
00444         res = wbk->BreakInBetween( fragText.get(), 
00445                                   fragText.Length(),
00446                                   nextFragText.get(), 
00447                                   nextFragText.Length(),
00448                                   &canBreak
00449                                 );
00450         if(canBreak)
00451             result.AppendLiteral("^");
00452 
00453         fragText = nextFragText;
00454       }
00455    }
00456    printf("Output From  SamplePrintWordWithBreak() \n\n");
00457    printf("[%s]\n", NS_LossyConvertUCS2toASCII(result).get());
00458 }
00459 
00460 void SampleFindWordBreakFromPosition(PRUint32 fragN, PRUint32 offset)
00461 {
00462    PRUint32 numOfFragment = sizeof(wb) / sizeof(char*);
00463    nsIWordBreakerFactory *t = NULL;
00464 
00465    nsresult res = CallGetService(kLWBrkCID, &t);
00466    nsIWordBreaker *wbk;
00467 
00468    nsAutoString wb_arg;
00469    res = t->GetBreaker(wb_arg, &wbk);
00470 
00471 
00472    nsAutoString fragText; fragText.AssignWithConversion(wb[fragN]); 
00473    
00474    PRUint32 begin, end;
00475 
00476 
00477    nsAutoString result;
00478    res = wbk->FindWord(fragText.get(), fragText.Length(), 
00479                           offset, &begin, &end);
00480 
00481    PRBool canbreak;
00482    fragText.Mid(result, begin, end-begin);
00483 
00484    if((PRUint32)fragText.Length() == end) // if we hit the end of the fragment
00485    {
00486      nsAutoString curFragText = fragText;
00487      for(PRUint32  p = fragN +1; p < numOfFragment ;p++)
00488      {
00489         nsAutoString nextFragText; nextFragText.AssignWithConversion(wb[p]); 
00490         res = wbk->BreakInBetween(curFragText.get(), 
00491                                   curFragText.Length(),
00492                                   nextFragText.get(), 
00493                                   nextFragText.Length(),
00494                                   &canbreak);
00495         if(canbreak)
00496            break;
00497  
00498         PRUint32 b, e;
00499         res = wbk->FindWord(nextFragText.get(), nextFragText.Length(), 
00500                           0, &b, &e);
00501 
00502         nsAutoString tmp;
00503         nextFragText.Mid(tmp,b,e-b);
00504         result.Append(tmp);
00505 
00506         if((PRUint32)nextFragText.Length() != e)
00507           break;
00508 
00509         nextFragText = curFragText;
00510      }
00511    }
00512    
00513    if(0 == begin) // if we hit the beginning of the fragment
00514    {
00515      nsAutoString curFragText = fragText;
00516      for(PRUint32  p = fragN ; p > 0 ;p--)
00517      {
00518         nsAutoString prevFragText; prevFragText.AssignWithConversion(wb[p-1]); 
00519         res = wbk->BreakInBetween(prevFragText.get(), 
00520                                   prevFragText.Length(),
00521                                   curFragText.get(), 
00522                                   curFragText.Length(),
00523                                   &canbreak);
00524         if(canbreak)
00525            break;
00526  
00527         PRUint32 b, e;
00528         res = wbk->FindWord(prevFragText.get(), prevFragText.Length(), 
00529                           prevFragText.Length(), &b, &e);
00530 
00531         nsAutoString tmp;
00532         prevFragText.Mid(tmp,b,e-b);
00533         result.Insert(tmp,0);
00534 
00535         if(0 != b)
00536           break;
00537 
00538         prevFragText = curFragText;
00539      }
00540    }
00541    
00542    printf("Output From  SamplePrintWordWithBreak() \n\n");
00543    printf("[%s]\n", NS_LossyConvertUCS2toASCII(result).get());
00544 }
00545 
00546 // Main
00547 
00548 int main(int argc, char** argv) {
00549 
00550    NS_InitXPCOM2(nsnull, nsnull, nsnull);
00551    
00552    // --------------------------------------------
00553    printf("Test Line Break\n");
00554 
00555    PRBool lbok ; 
00556    PRBool wbok ; 
00557    lbok =TestWordBreaker();
00558    if(lbok)
00559       printf("Line Break Test\nOK\n");
00560    else
00561       printf("Line Break Test\nFailed\n");
00562 
00563    wbok = TestLineBreaker();
00564    if(wbok)
00565       printf("Word Break Test\nOK\n");
00566    else
00567       printf("Word Break Test\nFailed\n");
00568 
00569    SampleWordBreakUsage();
00570    
00571 
00572    // --------------------------------------------
00573    printf("Finish All The Test Cases\n");
00574 
00575    if(lbok && wbok)
00576       printf("Line/Word Break Test\nOK\n");
00577    else
00578       printf("Line/Word Break Test\nFailed\n");
00579    return 0;
00580 }