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