michael@0: /* michael@0: ******************************************************************************* michael@0: * michael@0: * Copyright (C) 2000-2012, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: * michael@0: ******************************************************************************* michael@0: * michael@0: * File wrtjava.c michael@0: * michael@0: * Modification History: michael@0: * michael@0: * Date Name Description michael@0: * 01/11/02 Ram Creation. michael@0: * 02/12/08 Spieth Fix errant 'new Object[][]{' insertion michael@0: * 02/19/08 Spieth Removed ICUListResourceBundle dependancy michael@0: ******************************************************************************* michael@0: */ michael@0: michael@0: #include michael@0: #include "reslist.h" michael@0: #include "unewdata.h" michael@0: #include "unicode/ures.h" michael@0: #include "errmsg.h" michael@0: #include "filestrm.h" michael@0: #include "cstring.h" michael@0: #include "unicode/ucnv.h" michael@0: #include "genrb.h" michael@0: #include "rle.h" michael@0: #include "uhash.h" michael@0: #include "uresimp.h" michael@0: #include "unicode/ustring.h" michael@0: michael@0: void res_write_java(struct SResource *res,UErrorCode *status); michael@0: michael@0: michael@0: static const char copyRight[] = michael@0: "/* \n" michael@0: " *******************************************************************************\n" michael@0: " *\n" michael@0: " * Copyright (C) International Business Machines\n" michael@0: " * Corporation and others. All Rights Reserved.\n" michael@0: " *\n" michael@0: " *******************************************************************************\n" michael@0: " * $" "Source: $ \n" michael@0: " * $" "Date: $ \n" michael@0: " * $" "Revision: $ \n" michael@0: " *******************************************************************************\n" michael@0: " */\n\n"; michael@0: static const char warningMsg[] = michael@0: "/*********************************************************************\n" michael@0: "######################################################################\n" michael@0: "\n" michael@0: " WARNING: This file is generated by genrb Version " GENRB_VERSION ".\n" michael@0: " If you edit this file, please make sure that, the source\n" michael@0: " of this file (XXXX.txt in LocaleElements_XXXX.java)\n" michael@0: " is also edited.\n" michael@0: "######################################################################\n" michael@0: " *********************************************************************\n" michael@0: " */\n\n"; michael@0: static const char* openBrace="{\n"; michael@0: static const char* closeClass=" };\n" michael@0: "}\n"; michael@0: michael@0: static const char* javaClass = "import java.util.ListResourceBundle;\n\n" michael@0: "public class "; michael@0: michael@0: static const char* javaClass1= " extends ListResourceBundle {\n\n" michael@0: " /**\n" michael@0: " * Overrides ListResourceBundle \n" michael@0: " */\n" michael@0: " public final Object[][] getContents() { \n" michael@0: " return contents;\n" michael@0: " }\n\n" michael@0: " private static Object[][] contents = {\n"; michael@0: /*static const char* javaClassICU= " extends ListResourceBundle {\n\n" michael@0: " public %s () {\n" michael@0: " super.contents = data;\n" michael@0: " }\n" michael@0: " static final Object[][] data = new Object[][] { \n";*/ michael@0: static int tabCount = 3; michael@0: michael@0: static FileStream* out=NULL; michael@0: static struct SRBRoot* srBundle ; michael@0: /*static const char* outDir = NULL;*/ michael@0: michael@0: static const char* bName=NULL; michael@0: static const char* pName=NULL; michael@0: michael@0: static void write_tabs(FileStream* os){ michael@0: int i=0; michael@0: for(;i<=tabCount;i++){ michael@0: T_FileStream_write(os," ",4); michael@0: } michael@0: } michael@0: michael@0: #define ZERO 0x30 michael@0: michael@0: static const char* enc =""; michael@0: static UConverter* conv = NULL; michael@0: michael@0: static int32_t michael@0: uCharsToChars( char* target,int32_t targetLen, UChar* source, int32_t sourceLen,UErrorCode* status){ michael@0: int i=0, j=0; michael@0: char str[30]={'\0'}; michael@0: while(i=0x20 && source[i]<0x7F/*ASCII*/){ michael@0: if(j= source){ michael@0: if(*tSourceEnd==find){ michael@0: return (uint32_t)(tSourceEnd-source); michael@0: } michael@0: tSourceEnd--; michael@0: } michael@0: return (uint32_t)(tSourceEnd-source); michael@0: } michael@0: michael@0: static int32_t getColumnCount(int32_t len){ michael@0: int32_t columnCount = 80; michael@0: int32_t maxLines = 3000; michael@0: int32_t adjustedLen = len*5; /* assume that every codepoint is represented in \uXXXX format*/ michael@0: /* michael@0: * calculate the number of lines that michael@0: * may be required if column count is 80 michael@0: */ michael@0: if (maxLines < (adjustedLen / columnCount) ){ michael@0: columnCount = adjustedLen / maxLines; michael@0: } michael@0: return columnCount; michael@0: } michael@0: static void michael@0: str_write_java( uint16_t* src, int32_t srcLen, UBool printEndLine, UErrorCode *status){ michael@0: michael@0: uint32_t length = srcLen*8; michael@0: uint32_t bufLen = 0; michael@0: uint32_t columnCount; michael@0: char* buf = (char*) malloc(sizeof(char)*length); michael@0: michael@0: if(buf == NULL) { michael@0: *status = U_MEMORY_ALLOCATION_ERROR; michael@0: return; michael@0: } michael@0: michael@0: columnCount = getColumnCount(srcLen); michael@0: memset(buf,0,length); michael@0: michael@0: bufLen = uCharsToChars(buf,length,src,srcLen,status); michael@0: michael@0: if(printEndLine) michael@0: write_tabs(out); michael@0: michael@0: if(U_FAILURE(*status)){ michael@0: uprv_free(buf); michael@0: return; michael@0: } michael@0: michael@0: if(bufLen+(tabCount*4) > columnCount ){ michael@0: uint32_t len = 0; michael@0: char* current = buf; michael@0: uint32_t add; michael@0: while(len < bufLen){ michael@0: add = columnCount-(tabCount*4)-5/* for ", +\n */; michael@0: current = buf +len; michael@0: if (add < (bufLen-len)) { michael@0: uint32_t idx = strrch(current,add,'\\'); michael@0: if (idx > add) { michael@0: idx = add; michael@0: } else { michael@0: int32_t num =idx-1; michael@0: uint32_t seqLen; michael@0: while(num>0){ michael@0: if(current[num]=='\\'){ michael@0: num--; michael@0: }else{ michael@0: break; michael@0: } michael@0: } michael@0: if ((idx-num)%2==0) { michael@0: idx--; michael@0: } michael@0: seqLen = (current[idx+1]=='u') ? 6 : 2; michael@0: if ((add-idx) < seqLen) { michael@0: add = idx + seqLen; michael@0: } michael@0: } michael@0: } michael@0: T_FileStream_write(out,"\"",1); michael@0: if(len+addu.fString.fChars,res->u.fString.fLength,TRUE,status); michael@0: michael@0: if(resname != NULL && uprv_strcmp(resname,"Rule")==0) michael@0: { michael@0: UChar* buf = (UChar*) uprv_malloc(sizeof(UChar)*res->u.fString.fLength); michael@0: uprv_memcpy(buf,res->u.fString.fChars,res->u.fString.fLength); michael@0: uprv_free(buf); michael@0: } michael@0: michael@0: } michael@0: michael@0: static void michael@0: array_write_java( struct SResource *res, UErrorCode *status) { michael@0: michael@0: uint32_t i = 0; michael@0: const char* arr ="new String[] { \n"; michael@0: struct SResource *current = NULL; michael@0: UBool allStrings = TRUE; michael@0: michael@0: if (U_FAILURE(*status)) { michael@0: return; michael@0: } michael@0: michael@0: if (res->u.fArray.fCount > 0) { michael@0: michael@0: current = res->u.fArray.fFirst; michael@0: i = 0; michael@0: while(current != NULL){ michael@0: if(current->fType!=URES_STRING){ michael@0: allStrings = FALSE; michael@0: break; michael@0: } michael@0: current= current->fNext; michael@0: } michael@0: michael@0: current = res->u.fArray.fFirst; michael@0: if(allStrings==FALSE){ michael@0: const char* object = "new Object[]{\n"; michael@0: write_tabs(out); michael@0: T_FileStream_write(out, object, (int32_t)uprv_strlen(object)); michael@0: tabCount++; michael@0: }else{ michael@0: write_tabs(out); michael@0: T_FileStream_write(out, arr, (int32_t)uprv_strlen(arr)); michael@0: tabCount++; michael@0: } michael@0: while (current != NULL) { michael@0: /*if(current->fType==URES_STRING){ michael@0: write_tabs(out); michael@0: }*/ michael@0: res_write_java(current, status); michael@0: if(U_FAILURE(*status)){ michael@0: return; michael@0: } michael@0: i++; michael@0: current = current->fNext; michael@0: } michael@0: T_FileStream_write(out,"\n",1); michael@0: michael@0: tabCount--; michael@0: write_tabs(out); michael@0: T_FileStream_write(out,"},\n",3); michael@0: michael@0: } else { michael@0: write_tabs(out); michael@0: T_FileStream_write(out,arr,(int32_t)uprv_strlen(arr)); michael@0: write_tabs(out); michael@0: T_FileStream_write(out,"},\n",3); michael@0: } michael@0: } michael@0: michael@0: static void michael@0: intvector_write_java( struct SResource *res, UErrorCode *status) { michael@0: uint32_t i = 0; michael@0: const char* intArr = "new int[] {\n"; michael@0: /* const char* intC = "new Integer("; */ michael@0: const char* stringArr = "new String[]{\n"; michael@0: char resKeyBuffer[8]; michael@0: const char *resname = res_getKeyString(srBundle, res, resKeyBuffer); michael@0: char buf[100]; michael@0: int len =0; michael@0: buf[0]=0; michael@0: write_tabs(out); michael@0: michael@0: if(resname != NULL && uprv_strcmp(resname,"DateTimeElements")==0){ michael@0: T_FileStream_write(out, stringArr, (int32_t)uprv_strlen(stringArr)); michael@0: tabCount++; michael@0: for(i = 0; iu.fIntVector.fCount; i++) { michael@0: write_tabs(out); michael@0: len=itostr(buf,res->u.fIntVector.fArray[i],10,0); michael@0: T_FileStream_write(out,"\"",1); michael@0: T_FileStream_write(out,buf,len); michael@0: T_FileStream_write(out,"\",",2); michael@0: T_FileStream_write(out,"\n",1); michael@0: } michael@0: }else{ michael@0: T_FileStream_write(out, intArr, (int32_t)uprv_strlen(intArr)); michael@0: tabCount++; michael@0: for(i = 0; iu.fIntVector.fCount; i++) { michael@0: write_tabs(out); michael@0: /* T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); */ michael@0: len=itostr(buf,res->u.fIntVector.fArray[i],10,0); michael@0: T_FileStream_write(out,buf,len); michael@0: /* T_FileStream_write(out,"),",2); */ michael@0: /* T_FileStream_write(out,"\n",1); */ michael@0: T_FileStream_write(out,",\n",2); michael@0: } michael@0: } michael@0: tabCount--; michael@0: write_tabs(out); michael@0: T_FileStream_write(out,"},\n",3); michael@0: } michael@0: michael@0: static void michael@0: int_write_java(struct SResource *res,UErrorCode *status) { michael@0: const char* intC = "new Integer("; michael@0: char buf[100]; michael@0: int len =0; michael@0: buf[0]=0; michael@0: michael@0: /* write the binary data */ michael@0: write_tabs(out); michael@0: T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); michael@0: len=itostr(buf, res->u.fIntValue.fValue, 10, 0); michael@0: T_FileStream_write(out,buf,len); michael@0: T_FileStream_write(out,"),\n",3 ); michael@0: michael@0: } michael@0: michael@0: static void michael@0: bytes_write_java( struct SResource *res, UErrorCode *status) { michael@0: const char* type = "new byte[] {"; michael@0: const char* byteDecl = "%i, "; michael@0: char byteBuffer[100] = { 0 }; michael@0: uint8_t* byteArray = NULL; michael@0: int byteIterator = 0; michael@0: michael@0: int32_t srcLen=res->u.fBinaryValue.fLength; michael@0: michael@0: if(srcLen>0 ) michael@0: { michael@0: byteArray = res->u.fBinaryValue.fData; michael@0: michael@0: write_tabs(out); michael@0: T_FileStream_write(out, type, (int32_t)uprv_strlen(type)); michael@0: T_FileStream_write(out, "\n", 1); michael@0: tabCount++; michael@0: michael@0: for (;byteIteratoru.fTable.fCount > 0) { michael@0: if(start==FALSE){ michael@0: write_tabs(out); michael@0: T_FileStream_write(out, obj, (int32_t)uprv_strlen(obj)); michael@0: tabCount++; michael@0: } michael@0: start = FALSE; michael@0: current = res->u.fTable.fFirst; michael@0: i = 0; michael@0: michael@0: michael@0: while (current != NULL) { michael@0: char currentKeyBuffer[8]; michael@0: const char *currentKeyString = res_getKeyString(srBundle, current, currentKeyBuffer); michael@0: michael@0: assert(i < res->u.fTable.fCount); michael@0: write_tabs(out); michael@0: michael@0: T_FileStream_write(out, openBrace, 2); michael@0: michael@0: michael@0: tabCount++; michael@0: michael@0: write_tabs(out); michael@0: if(currentKeyString != NULL) { michael@0: T_FileStream_write(out, "\"", 1); michael@0: T_FileStream_write(out, currentKeyString, michael@0: (int32_t)uprv_strlen(currentKeyString)); michael@0: T_FileStream_write(out, "\",\n", 2); michael@0: michael@0: T_FileStream_write(out, "\n", 1); michael@0: } michael@0: res_write_java(current, status); michael@0: if(U_FAILURE(*status)){ michael@0: return; michael@0: } michael@0: i++; michael@0: current = current->fNext; michael@0: tabCount--; michael@0: write_tabs(out); michael@0: T_FileStream_write(out, "},\n", 3); michael@0: } michael@0: if(tabCount>4){ michael@0: tabCount--; michael@0: write_tabs(out); michael@0: T_FileStream_write(out, "},\n", 3); michael@0: } michael@0: michael@0: } else { michael@0: write_tabs(out); michael@0: T_FileStream_write(out,obj,(int32_t)uprv_strlen(obj)); michael@0: michael@0: write_tabs(out); michael@0: T_FileStream_write(out,"},\n",3); michael@0: michael@0: } michael@0: michael@0: } michael@0: michael@0: void michael@0: res_write_java(struct SResource *res,UErrorCode *status) { michael@0: michael@0: if (U_FAILURE(*status)) { michael@0: return ; michael@0: } michael@0: michael@0: if (res != NULL) { michael@0: switch (res->fType) { michael@0: case URES_STRING: michael@0: string_write_java (res, status); michael@0: return; michael@0: case URES_ALIAS: michael@0: printf("Encountered unsupported resource type %d of alias\n", res->fType); michael@0: *status = U_UNSUPPORTED_ERROR; michael@0: return; michael@0: case URES_INT_VECTOR: michael@0: intvector_write_java (res, status); michael@0: return; michael@0: case URES_BINARY: michael@0: bytes_write_java (res, status); michael@0: return; michael@0: case URES_INT: michael@0: int_write_java (res, status); michael@0: return; michael@0: case URES_ARRAY: michael@0: array_write_java (res, status); michael@0: return; michael@0: case URES_TABLE: michael@0: table_write_java (res, status); michael@0: return; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: michael@0: *status = U_INTERNAL_PROGRAM_ERROR; michael@0: } michael@0: michael@0: void michael@0: bundle_write_java(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, michael@0: char *writtenFilename, int writtenFilenameLen, michael@0: const char* packageName, const char* bundleName, michael@0: UErrorCode *status) { michael@0: michael@0: char fileName[256] = {'\0'}; michael@0: char className[256]={'\0'}; michael@0: /*char constructor[1000] = { 0 };*/ michael@0: /*UBool j1 =FALSE;*/ michael@0: /*outDir = outputDir;*/ michael@0: michael@0: start = TRUE; /* Reset the start indictor*/ michael@0: michael@0: bName = (bundleName==NULL) ? "LocaleElements" : bundleName; michael@0: pName = (packageName==NULL)? "com.ibm.icu.impl.data" : packageName; michael@0: michael@0: uprv_strcpy(className, bName); michael@0: srBundle = bundle; michael@0: if(uprv_strcmp(srBundle->fLocale,"root")!=0){ michael@0: uprv_strcat(className,"_"); michael@0: uprv_strcat(className,srBundle->fLocale); michael@0: } michael@0: if(outputDir){ michael@0: uprv_strcpy(fileName, outputDir); michael@0: if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){ michael@0: uprv_strcat(fileName,U_FILE_SEP_STRING); michael@0: } michael@0: uprv_strcat(fileName,className); michael@0: uprv_strcat(fileName,".java"); michael@0: }else{ michael@0: uprv_strcat(fileName,className); michael@0: uprv_strcat(fileName,".java"); michael@0: } michael@0: michael@0: if (writtenFilename) { michael@0: uprv_strncpy(writtenFilename, fileName, writtenFilenameLen); michael@0: } michael@0: michael@0: if (U_FAILURE(*status)) { michael@0: return; michael@0: } michael@0: michael@0: out= T_FileStream_open(fileName,"w"); michael@0: michael@0: if(out==NULL){ michael@0: *status = U_FILE_ACCESS_ERROR; michael@0: return; michael@0: } michael@0: if(getIncludeCopyright()){ michael@0: T_FileStream_write(out, copyRight, (int32_t)uprv_strlen(copyRight)); michael@0: T_FileStream_write(out, warningMsg, (int32_t)uprv_strlen(warningMsg)); michael@0: } michael@0: T_FileStream_write(out,"package ",(int32_t)uprv_strlen("package ")); michael@0: T_FileStream_write(out,pName,(int32_t)uprv_strlen(pName)); michael@0: T_FileStream_write(out,";\n\n",3); michael@0: T_FileStream_write(out, javaClass, (int32_t)uprv_strlen(javaClass)); michael@0: T_FileStream_write(out, className, (int32_t)uprv_strlen(className)); michael@0: T_FileStream_write(out, javaClass1, (int32_t)uprv_strlen(javaClass1)); michael@0: michael@0: /* if(j1){ michael@0: T_FileStream_write(out, javaClass1, (int32_t)uprv_strlen(javaClass1)); michael@0: }else{ michael@0: sprintf(constructor,javaClassICU,className); michael@0: T_FileStream_write(out, constructor, (int32_t)uprv_strlen(constructor)); michael@0: } michael@0: */ michael@0: michael@0: if(outputEnc && *outputEnc!='\0'){ michael@0: /* store the output encoding */ michael@0: enc = outputEnc; michael@0: conv=ucnv_open(enc,status); michael@0: if(U_FAILURE(*status)){ michael@0: return; michael@0: } michael@0: } michael@0: res_write_java(bundle->fRoot, status); michael@0: michael@0: T_FileStream_write(out, closeClass, (int32_t)uprv_strlen(closeClass)); michael@0: michael@0: T_FileStream_close(out); michael@0: michael@0: ucnv_close(conv); michael@0: }