• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 2000-2012, International Business Machines
5 *   Corporation and others.  All Rights Reserved.
6 *
7 *******************************************************************************
8 *
9 * File wrtjava.c
10 *
11 * Modification History:
12 *
13 *   Date        Name        Description
14 *   01/11/02    Ram         Creation.
15 *   02/12/08    Spieth      Fix errant 'new Object[][]{' insertion
16 *   02/19/08    Spieth      Removed ICUListResourceBundle dependancy
17 *******************************************************************************
18 */
19 
20 #include <assert.h>
21 #include "reslist.h"
22 #include "unewdata.h"
23 #include "unicode/ures.h"
24 #include "errmsg.h"
25 #include "filestrm.h"
26 #include "cstring.h"
27 #include "unicode/ucnv.h"
28 #include "genrb.h"
29 #include "rle.h"
30 #include "uhash.h"
31 #include "uresimp.h"
32 #include "unicode/ustring.h"
33 
34 void res_write_java(struct SResource *res,UErrorCode *status);
35 
36 
37 static const char copyRight[] =
38     "/* \n"
39     " *******************************************************************************\n"
40     " *\n"
41     " *   Copyright (C) International Business Machines\n"
42     " *   Corporation and others.  All Rights Reserved.\n"
43     " *\n"
44     " *******************************************************************************\n"
45     " * $" "Source:  $ \n"
46     " * $" "Date:  $ \n"
47     " * $" "Revision:  $ \n"
48     " *******************************************************************************\n"
49     " */\n\n";
50 static const char warningMsg[] =
51     "/*********************************************************************\n"
52     "######################################################################\n"
53     "\n"
54     "   WARNING: This file is generated by genrb Version " GENRB_VERSION ".\n"
55     "            If you edit this file, please make sure that, the source\n"
56     "            of this file (XXXX.txt in LocaleElements_XXXX.java)\n"
57     "            is also edited.\n"
58     "######################################################################\n"
59     " *********************************************************************\n"
60     " */\n\n";
61 static const char* openBrace="{\n";
62 static const char* closeClass="    };\n"
63                               "}\n";
64 
65 static const char* javaClass =  "import java.util.ListResourceBundle;\n\n"
66                                 "public class ";
67 
68 static const char* javaClass1=  " extends ListResourceBundle {\n\n"
69                                 "    /**\n"
70                                 "     * Overrides ListResourceBundle \n"
71                                 "     */\n"
72                                 "    public final Object[][] getContents() { \n"
73                                 "          return  contents;\n"
74                                 "    }\n\n"
75                                 "    private static Object[][] contents = {\n";
76 /*static const char* javaClassICU= " extends ListResourceBundle {\n\n"
77                                  "    public %s  () {\n"
78                                  "          super.contents = data;\n"
79                                  "    }\n"
80                                  "    static final Object[][] data = new Object[][] { \n";*/
81 static int tabCount = 3;
82 
83 static FileStream* out=NULL;
84 static struct SRBRoot* srBundle ;
85 /*static const char* outDir = NULL;*/
86 
87 static const char* bName=NULL;
88 static const char* pName=NULL;
89 
write_tabs(FileStream * os)90 static void write_tabs(FileStream* os){
91     int i=0;
92     for(;i<=tabCount;i++){
93         T_FileStream_write(os,"    ",4);
94     }
95 }
96 
97 #define ZERO 0x30
98 
99 static const char* enc ="";
100 static UConverter* conv = NULL;
101 
102 static int32_t
uCharsToChars(char * target,int32_t targetLen,UChar * source,int32_t sourceLen,UErrorCode * status)103 uCharsToChars( char* target,int32_t targetLen, UChar* source, int32_t sourceLen,UErrorCode* status){
104     int i=0, j=0;
105     char str[30]={'\0'};
106     while(i<sourceLen){
107         if (source[i] == '\n') {
108             if (j + 2 < targetLen) {
109                 uprv_strcat(target, "\\n");
110             }
111             j += 2;
112         }else if(source[i]==0x0D){
113             if(j+2<targetLen){
114                 uprv_strcat(target,"\\f");
115             }
116             j+=2;
117         }else if(source[i] == '"'){
118             if(source[i-1]=='\''){
119                 if(j+2<targetLen){
120                     uprv_strcat(target,"\\");
121                     target[j+1]= (char)source[i];
122                 }
123                 j+=2;
124             }else if(source[i-1]!='\\'){
125 
126                 if(j+2<targetLen){
127                     uprv_strcat(target,"\\");
128                     target[j+1]= (char)source[i];
129                 }
130                 j+=2;
131             }else if(source[i-1]=='\\'){
132                 target[j++]= (char)source[i];
133             }
134         }else if(source[i]=='\\'){
135             if(i+1<sourceLen){
136                 switch(source[i+1]){
137                 case ',':
138                 case '!':
139                 case '?':
140                 case '#':
141                 case '.':
142                 case '%':
143                 case '&':
144                 case ':':
145                 case ';':
146                     if(j+2<targetLen){
147                        uprv_strcat(target,"\\\\");
148                     }
149                     j+=2;
150                     break;
151                 case '"':
152                 case '\'':
153                     if(j+3<targetLen){
154                        uprv_strcat(target,"\\\\\\");
155                     }
156                     j+=3;
157                     break;
158                 default :
159                     if(j<targetLen){
160                         target[j]=(char)source[i];
161                     }
162                     j++;
163                     break;
164                 }
165             }else{
166                 if(j<targetLen){
167                     uprv_strcat(target,"\\\\");
168                 }
169                 j+=2;
170             }
171         }else if(source[i]>=0x20 && source[i]<0x7F/*ASCII*/){
172             if(j<targetLen){
173                 target[j] = (char) source[i];
174             }
175             j++;
176         }else{
177             if(*enc =='\0' || source[i]==0x0000){
178                 uprv_strcpy(str,"\\u");
179                 itostr(str+2,source[i],16,4);
180                 if(j+6<targetLen){
181                     uprv_strcat(target,str);
182                 }
183                 j+=6;
184             }else{
185                 char dest[30] = {0};
186                 int retVal=ucnv_fromUChars(conv,dest,30,source+i,1,status);
187                 if(U_FAILURE(*status)){
188                     return 0;
189                 }
190                 if(j+retVal<targetLen){
191                     uprv_strcat(target,dest);
192                 }
193                 j+=retVal;
194             }
195         }
196         i++;
197     }
198     return j;
199 }
200 
201 
202 static uint32_t
strrch(const char * source,uint32_t sourceLen,char find)203 strrch(const char* source,uint32_t sourceLen,char find){
204     const char* tSourceEnd =source + (sourceLen-1);
205     while(tSourceEnd>= source){
206         if(*tSourceEnd==find){
207             return (uint32_t)(tSourceEnd-source);
208         }
209         tSourceEnd--;
210     }
211     return (uint32_t)(tSourceEnd-source);
212 }
213 
getColumnCount(int32_t len)214 static int32_t getColumnCount(int32_t len){
215     int32_t columnCount = 80;
216     int32_t maxLines = 3000;
217     int32_t adjustedLen = len*5; /* assume that every codepoint is represented in \uXXXX format*/
218     /*
219      * calculate the number of lines that
220      * may be required if column count is 80
221      */
222     if (maxLines  < (adjustedLen / columnCount) ){
223         columnCount = adjustedLen / maxLines;
224     }
225     return columnCount;
226 }
227 static void
str_write_java(uint16_t * src,int32_t srcLen,UBool printEndLine,UErrorCode * status)228 str_write_java( uint16_t* src, int32_t srcLen, UBool printEndLine, UErrorCode *status){
229 
230     uint32_t length = srcLen*8;
231     uint32_t bufLen = 0;
232     uint32_t columnCount;
233     char* buf = (char*) malloc(sizeof(char)*length);
234 
235     if(buf == NULL) {
236         *status = U_MEMORY_ALLOCATION_ERROR;
237         return;
238     }
239 
240     columnCount = getColumnCount(srcLen);
241     memset(buf,0,length);
242 
243     bufLen = uCharsToChars(buf,length,src,srcLen,status);
244 
245     if(printEndLine)
246         write_tabs(out);
247 
248     if(U_FAILURE(*status)){
249         uprv_free(buf);
250         return;
251     }
252 
253     if(bufLen+(tabCount*4) > columnCount  ){
254         uint32_t len = 0;
255         char* current = buf;
256         uint32_t add;
257         while(len < bufLen){
258             add = columnCount-(tabCount*4)-5/* for ", +\n */;
259             current = buf +len;
260             if (add < (bufLen-len)) {
261                 uint32_t idx = strrch(current,add,'\\');
262                 if (idx > add) {
263                     idx = add;
264                 } else {
265                     int32_t num =idx-1;
266                     uint32_t seqLen;
267                     while(num>0){
268                         if(current[num]=='\\'){
269                             num--;
270                         }else{
271                             break;
272                         }
273                     }
274                     if ((idx-num)%2==0) {
275                         idx--;
276                     }
277                     seqLen = (current[idx+1]=='u') ? 6 : 2;
278                     if ((add-idx) < seqLen) {
279                         add = idx + seqLen;
280                     }
281                 }
282             }
283             T_FileStream_write(out,"\"",1);
284             if(len+add<bufLen){
285                 T_FileStream_write(out,current,add);
286                 T_FileStream_write(out,"\" +\n",4);
287                 write_tabs(out);
288             }else{
289                 T_FileStream_write(out,current,bufLen-len);
290             }
291             len+=add;
292         }
293     }else{
294         T_FileStream_write(out,"\"",1);
295         T_FileStream_write(out, buf,bufLen);
296     }
297     if(printEndLine){
298         T_FileStream_write(out,"\",\n",3);
299     }else{
300         T_FileStream_write(out,"\"",1);
301     }
302     uprv_free(buf);
303 }
304 
305 /* Writing Functions */
306 static void
string_write_java(struct SResource * res,UErrorCode * status)307 string_write_java(struct SResource *res,UErrorCode *status) {
308     char resKeyBuffer[8];
309     const char *resname = res_getKeyString(srBundle, res, resKeyBuffer);
310 
311     str_write_java(res->u.fString.fChars,res->u.fString.fLength,TRUE,status);
312 
313 	if(resname != NULL && uprv_strcmp(resname,"Rule")==0)
314 	{
315         UChar* buf = (UChar*) uprv_malloc(sizeof(UChar)*res->u.fString.fLength);
316         uprv_memcpy(buf,res->u.fString.fChars,res->u.fString.fLength);
317         uprv_free(buf);
318     }
319 
320 }
321 
322 static void
array_write_java(struct SResource * res,UErrorCode * status)323 array_write_java( struct SResource *res, UErrorCode *status) {
324 
325     uint32_t  i         = 0;
326     const char* arr ="new String[] { \n";
327     struct SResource *current = NULL;
328     UBool allStrings    = TRUE;
329 
330     if (U_FAILURE(*status)) {
331         return;
332     }
333 
334     if (res->u.fArray.fCount > 0) {
335 
336         current = res->u.fArray.fFirst;
337         i = 0;
338         while(current != NULL){
339             if(current->fType!=URES_STRING){
340                 allStrings = FALSE;
341                 break;
342             }
343             current= current->fNext;
344         }
345 
346         current = res->u.fArray.fFirst;
347         if(allStrings==FALSE){
348             const char* object = "new Object[]{\n";
349             write_tabs(out);
350             T_FileStream_write(out, object, (int32_t)uprv_strlen(object));
351             tabCount++;
352         }else{
353             write_tabs(out);
354             T_FileStream_write(out, arr, (int32_t)uprv_strlen(arr));
355             tabCount++;
356         }
357         while (current != NULL) {
358             /*if(current->fType==URES_STRING){
359                 write_tabs(out);
360             }*/
361             res_write_java(current, status);
362             if(U_FAILURE(*status)){
363                 return;
364             }
365             i++;
366             current = current->fNext;
367         }
368         T_FileStream_write(out,"\n",1);
369 
370         tabCount--;
371         write_tabs(out);
372         T_FileStream_write(out,"},\n",3);
373 
374     } else {
375         write_tabs(out);
376         T_FileStream_write(out,arr,(int32_t)uprv_strlen(arr));
377         write_tabs(out);
378         T_FileStream_write(out,"},\n",3);
379     }
380 }
381 
382 static void
intvector_write_java(struct SResource * res,UErrorCode * status)383 intvector_write_java( struct SResource *res, UErrorCode *status) {
384     uint32_t i = 0;
385     const char* intArr = "new int[] {\n";
386     /* const char* intC   = "new Integer(";   */
387     const char* stringArr = "new String[]{\n";
388     char resKeyBuffer[8];
389     const char *resname = res_getKeyString(srBundle, res, resKeyBuffer);
390     char buf[100];
391     int len =0;
392     buf[0]=0;
393     write_tabs(out);
394 
395     if(resname != NULL && uprv_strcmp(resname,"DateTimeElements")==0){
396         T_FileStream_write(out, stringArr, (int32_t)uprv_strlen(stringArr));
397         tabCount++;
398         for(i = 0; i<res->u.fIntVector.fCount; i++) {
399             write_tabs(out);
400             len=itostr(buf,res->u.fIntVector.fArray[i],10,0);
401             T_FileStream_write(out,"\"",1);
402             T_FileStream_write(out,buf,len);
403             T_FileStream_write(out,"\",",2);
404             T_FileStream_write(out,"\n",1);
405         }
406     }else{
407         T_FileStream_write(out, intArr, (int32_t)uprv_strlen(intArr));
408         tabCount++;
409         for(i = 0; i<res->u.fIntVector.fCount; i++) {
410             write_tabs(out);
411             /* T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); */
412             len=itostr(buf,res->u.fIntVector.fArray[i],10,0);
413             T_FileStream_write(out,buf,len);
414             /* T_FileStream_write(out,"),",2);  */
415             /* T_FileStream_write(out,"\n",1);  */
416             T_FileStream_write(out,",\n",2);
417         }
418     }
419     tabCount--;
420     write_tabs(out);
421     T_FileStream_write(out,"},\n",3);
422 }
423 
424 static void
int_write_java(struct SResource * res,UErrorCode * status)425 int_write_java(struct SResource *res,UErrorCode *status) {
426     const char* intC   =  "new Integer(";
427     char buf[100];
428     int len =0;
429     buf[0]=0;
430 
431     /* write the binary data */
432     write_tabs(out);
433     T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC));
434     len=itostr(buf, res->u.fIntValue.fValue, 10, 0);
435     T_FileStream_write(out,buf,len);
436     T_FileStream_write(out,"),\n",3 );
437 
438 }
439 
440 static void
bytes_write_java(struct SResource * res,UErrorCode * status)441 bytes_write_java( struct SResource *res, UErrorCode *status) {
442 	const char* type  = "new byte[] {";
443 	const char* byteDecl = "%i, ";
444     char byteBuffer[100] = { 0 };
445 	uint8_t*  byteArray = NULL;
446     int byteIterator = 0;
447 
448     int32_t srcLen=res->u.fBinaryValue.fLength;
449 
450     if(srcLen>0 )
451 	{
452         byteArray = res->u.fBinaryValue.fData;
453 
454         write_tabs(out);
455         T_FileStream_write(out, type, (int32_t)uprv_strlen(type));
456         T_FileStream_write(out, "\n", 1);
457         tabCount++;
458 
459 		for (;byteIterator<srcLen;byteIterator++)
460 		{
461             if (byteIterator%16 == 0)
462 			{
463 			    write_tabs(out);
464 			}
465 
466 			if (byteArray[byteIterator] < 128)
467 			{
468                 sprintf(byteBuffer, byteDecl, byteArray[byteIterator]);
469 			}
470 			else
471 			{
472                 sprintf(byteBuffer, byteDecl, (byteArray[byteIterator]-256));
473 			}
474 
475             T_FileStream_write(out, byteBuffer, (int32_t)uprv_strlen(byteBuffer));
476 
477 			if (byteIterator%16 == 15)
478 			{
479                 T_FileStream_write(out, "\n", 1);
480 			}
481 
482 		}
483 
484         if (((byteIterator-1)%16) != 15)
485 		{
486             T_FileStream_write(out, "\n", 1);
487 	    }
488 
489 		tabCount--;
490         write_tabs(out);
491 		T_FileStream_write(out, "},\n", 3);
492 
493 	}
494 	else
495     {
496 		/* Empty array */
497         write_tabs(out);
498         T_FileStream_write(out,type,(int32_t)uprv_strlen(type));
499 		T_FileStream_write(out,"},\n",3);
500     }
501 
502 }
503 
504 static UBool start = TRUE;
505 
506 static void
table_write_java(struct SResource * res,UErrorCode * status)507 table_write_java(struct SResource *res, UErrorCode *status) {
508     uint32_t  i         = 0;
509     struct SResource *current = NULL;
510     const char* obj = "new Object[][]{\n";
511 
512     if (U_FAILURE(*status)) {
513         return ;
514     }
515 
516     if (res->u.fTable.fCount > 0) {
517         if(start==FALSE){
518             write_tabs(out);
519             T_FileStream_write(out, obj, (int32_t)uprv_strlen(obj));
520             tabCount++;
521         }
522         start = FALSE;
523         current = res->u.fTable.fFirst;
524         i       = 0;
525 
526 
527         while (current != NULL) {
528             char currentKeyBuffer[8];
529             const char *currentKeyString = res_getKeyString(srBundle, current, currentKeyBuffer);
530 
531             assert(i < res->u.fTable.fCount);
532             write_tabs(out);
533 
534             T_FileStream_write(out, openBrace, 2);
535 
536 
537             tabCount++;
538 
539             write_tabs(out);
540             if(currentKeyString != NULL) {
541                 T_FileStream_write(out, "\"", 1);
542                 T_FileStream_write(out, currentKeyString,
543                                    (int32_t)uprv_strlen(currentKeyString));
544                 T_FileStream_write(out, "\",\n", 2);
545 
546                 T_FileStream_write(out, "\n", 1);
547             }
548             res_write_java(current, status);
549             if(U_FAILURE(*status)){
550                 return;
551             }
552             i++;
553             current = current->fNext;
554             tabCount--;
555             write_tabs(out);
556             T_FileStream_write(out, "},\n", 3);
557         }
558         if(tabCount>4){
559             tabCount--;
560             write_tabs(out);
561             T_FileStream_write(out, "},\n", 3);
562         }
563 
564     } else {
565         write_tabs(out);
566         T_FileStream_write(out,obj,(int32_t)uprv_strlen(obj));
567 
568         write_tabs(out);
569         T_FileStream_write(out,"},\n",3);
570 
571     }
572 
573 }
574 
575 void
res_write_java(struct SResource * res,UErrorCode * status)576 res_write_java(struct SResource *res,UErrorCode *status) {
577 
578     if (U_FAILURE(*status)) {
579         return ;
580     }
581 
582     if (res != NULL) {
583         switch (res->fType) {
584         case URES_STRING:
585              string_write_java    (res, status);
586              return;
587         case URES_ALIAS:
588              printf("Encountered unsupported resource type %d of alias\n", res->fType);
589              *status = U_UNSUPPORTED_ERROR;
590 			 return;
591         case URES_INT_VECTOR:
592              intvector_write_java (res, status);
593              return;
594         case URES_BINARY:
595              bytes_write_java     (res, status);
596              return;
597         case URES_INT:
598              int_write_java       (res, status);
599              return;
600         case URES_ARRAY:
601              array_write_java     (res, status);
602              return;
603         case URES_TABLE:
604              table_write_java     (res, status);
605              return;
606         default:
607             break;
608         }
609     }
610 
611     *status = U_INTERNAL_PROGRAM_ERROR;
612 }
613 
614 void
bundle_write_java(struct SRBRoot * bundle,const char * outputDir,const char * outputEnc,char * writtenFilename,int writtenFilenameLen,const char * packageName,const char * bundleName,UErrorCode * status)615 bundle_write_java(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc,
616                   char *writtenFilename, int writtenFilenameLen,
617                   const char* packageName, const char* bundleName,
618                   UErrorCode *status) {
619 
620     char fileName[256] = {'\0'};
621     char className[256]={'\0'};
622     /*char constructor[1000] = { 0 };*/
623     /*UBool j1 =FALSE;*/
624     /*outDir = outputDir;*/
625 
626     start = TRUE;                        /* Reset the start indictor*/
627 
628     bName = (bundleName==NULL) ? "LocaleElements" : bundleName;
629     pName = (packageName==NULL)? "com.ibm.icu.impl.data" : packageName;
630 
631     uprv_strcpy(className, bName);
632     srBundle = bundle;
633     if(uprv_strcmp(srBundle->fLocale,"root")!=0){
634         uprv_strcat(className,"_");
635         uprv_strcat(className,srBundle->fLocale);
636     }
637     if(outputDir){
638         uprv_strcpy(fileName, outputDir);
639         if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){
640             uprv_strcat(fileName,U_FILE_SEP_STRING);
641         }
642         uprv_strcat(fileName,className);
643         uprv_strcat(fileName,".java");
644     }else{
645         uprv_strcat(fileName,className);
646         uprv_strcat(fileName,".java");
647     }
648 
649     if (writtenFilename) {
650         uprv_strncpy(writtenFilename, fileName, writtenFilenameLen);
651     }
652 
653     if (U_FAILURE(*status)) {
654         return;
655     }
656 
657     out= T_FileStream_open(fileName,"w");
658 
659     if(out==NULL){
660         *status = U_FILE_ACCESS_ERROR;
661         return;
662     }
663     if(getIncludeCopyright()){
664         T_FileStream_write(out, copyRight, (int32_t)uprv_strlen(copyRight));
665         T_FileStream_write(out, warningMsg, (int32_t)uprv_strlen(warningMsg));
666     }
667     T_FileStream_write(out,"package ",(int32_t)uprv_strlen("package "));
668     T_FileStream_write(out,pName,(int32_t)uprv_strlen(pName));
669     T_FileStream_write(out,";\n\n",3);
670     T_FileStream_write(out, javaClass, (int32_t)uprv_strlen(javaClass));
671     T_FileStream_write(out, className, (int32_t)uprv_strlen(className));
672 	T_FileStream_write(out, javaClass1, (int32_t)uprv_strlen(javaClass1));
673 
674     /* if(j1){
675           T_FileStream_write(out, javaClass1, (int32_t)uprv_strlen(javaClass1));
676        }else{
677            sprintf(constructor,javaClassICU,className);
678            T_FileStream_write(out, constructor, (int32_t)uprv_strlen(constructor));
679        }
680     */
681 
682     if(outputEnc && *outputEnc!='\0'){
683         /* store the output encoding */
684         enc = outputEnc;
685         conv=ucnv_open(enc,status);
686         if(U_FAILURE(*status)){
687             return;
688         }
689     }
690     res_write_java(bundle->fRoot, status);
691 
692     T_FileStream_write(out, closeClass, (int32_t)uprv_strlen(closeClass));
693 
694     T_FileStream_close(out);
695 
696     ucnv_close(conv);
697 }
698