]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/genrb/wrtxml.c
ICU-8.11.1.tar.gz
[apple/icu.git] / icuSources / tools / genrb / wrtxml.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
73c04bcf 4* Copyright (C) 2002-2006, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7*******************************************************************************
8*
9* File wrtxml.c
10*
11* Modification History:
12*
13* Date Name Description
14* 10/01/02 Ram Creation.
15*******************************************************************************
16*/
17#include "reslist.h"
18#include "unewdata.h"
19#include "unicode/ures.h"
20#include "errmsg.h"
21#include "filestrm.h"
22#include "cstring.h"
23#include "unicode/ucnv.h"
24#include "genrb.h"
25#include "rle.h"
26#include "ucol_tok.h"
27#include "uhash.h"
28#include "uresimp.h"
29#include "unicode/ustring.h"
30#include "unicode/uchar.h"
374ca955
A
31#include "ustr.h"
32#include "prscmnts.h"
b75a7d8f
A
33#include <time.h>
34
35static int tabCount = 0;
36
37static FileStream* out=NULL;
38static struct SRBRoot* srBundle ;
39static const char* outDir = NULL;
40static const char* enc ="";
41static UConverter* conv = NULL;
42
43const char* const* ISOLanguages;
44const char* const* ISOCountries;
45const char* textExt = ".txt";
46const char* xliffExt = ".xlf";
47
48/*write indentation for formatting*/
49static void write_tabs(FileStream* os){
50 int i=0;
51 for(;i<=tabCount;i++){
52 T_FileStream_write(os," ",4);
53 }
54}
55
56/*get ID for each element. ID is globally unique.*/
57static char* getID(const char* id, char* curKey, char* result) {
374ca955 58 if(curKey == NULL) {
b75a7d8f
A
59 result = uprv_malloc(sizeof(char)*uprv_strlen(id) + 1);
60 uprv_memset(result, 0, sizeof(char)*uprv_strlen(id) + 1);
61 uprv_strcpy(result, id);
62 } else {
63 result = uprv_malloc(sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1);
64 uprv_memset(result, 0, sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1);
65 if(id[0]!='\0'){
66 uprv_strcpy(result, id);
67 uprv_strcat(result, "_");
68 }
69 uprv_strcat(result, curKey);
70 }
71 return result;
72}
73
74/*compute CRC for binary code*/
75/* The code is from http://www.theorem.com/java/CRC32.java
76 * Calculates the CRC32 - 32 bit Cyclical Redundancy Check
77 * <P> This check is used in numerous systems to verify the integrity
78 * of information. It's also used as a hashing function. Unlike a regular
79 * checksum, it's sensitive to the order of the characters.
80 * It produces a 32 bit
374ca955 81 *
b75a7d8f
A
82 * @author Michael Lecuyer (mjl@theorem.com)
83 * @version 1.1 August 11, 1998
84 */
374ca955 85
b75a7d8f 86/* ICU is not endian portable, because ICU data generated on big endian machines can be
374ca955
A
87 * ported to big endian machines but not to little endian machines and vice versa. The
88 * conversion is not portable across platforms with different endianess.
b75a7d8f 89 */
374ca955 90
b75a7d8f
A
91static uint32_t computeCRC(char *ptr, uint32_t len, uint32_t lastcrc){
92 int32_t crc;
93 uint32_t temp1;
94 uint32_t temp2;
95
96 int32_t crc_ta[256];
97 int i = 0;
98 int j = 0;
99 uint32_t crc2 = 0;
100
101#define CRC32_POLYNOMIAL 0xEDB88320
102
103 /*build crc table*/
104 for (i = 0; i <= 255; i++) {
105 crc2 = i;
106 for (j = 8; j > 0; j--) {
107 if ((crc2 & 1) == 1) {
108 crc2 = (crc2 >> 1) ^ CRC32_POLYNOMIAL;
109 } else {
110 crc2 >>= 1;
111 }
112 }
113 crc_ta[i] = crc2;
114 }
115
116 crc = lastcrc;
117 while(len--!=0) {
374ca955
A
118 temp1 = (uint32_t)crc>>8;
119 temp2 = crc_ta[(crc^*ptr) & 0xFF];
b75a7d8f
A
120 crc = temp1^temp2;
121 ptr++;
122 }
123 return(crc);
124}
125
73c04bcf
A
126static void strnrepchr(char* src, int32_t srcLen, char s, char r){
127 int32_t i = 0;
128 for(i=0;i<srcLen;i++){
129 if(src[i]==s){
130 src[i]=r;
b75a7d8f 131 }
b75a7d8f 132 }
b75a7d8f 133}
374ca955
A
134/* Parse the filename, and get its language information.
135 * If it fails to get the language information from the filename,
b75a7d8f
A
136 * use "en" as the default value for language
137 */
73c04bcf
A
138static char* parseFilename(const char* id, char* lang) {
139 int idLen = uprv_strlen(id);
140 char* localeID = (char*) uprv_malloc(idLen);
141 int pos = 0;
142 int canonCapacity = 0;
143 char* canon = NULL;
144 int canonLen = 0;
145 /*int i;*/
146 UErrorCode status = U_ZERO_ERROR;
147 char *ext = uprv_strchr(id, '.');
148 if(ext!=NULL){
149 pos = ext-id;
150 }else{
151 pos = idLen;
b75a7d8f 152 }
73c04bcf
A
153 uprv_memcpy(localeID, id, pos);
154 localeID[pos]=0; /* NUL terminate the string */
155
156 canonCapacity =pos*3;
157 canon = (char*) uprv_malloc(canonCapacity);
158 canonLen = uloc_canonicalize(localeID, canon, canonCapacity, &status);
b75a7d8f 159
73c04bcf
A
160 if(U_FAILURE(status)){
161 fprintf(stderr, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID, u_errorName(status));
162 exit(status);
b75a7d8f 163 }
73c04bcf
A
164 strnrepchr(canon, canonLen, '_', '-');
165 return canon;
b75a7d8f
A
166}
167
168static const char* xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
374ca955 169 "<!DOCTYPE xliff "
b75a7d8f
A
170 "SYSTEM \"http://www.oasis-open.org/committees/xliff/documents/xliff.dtd\">\n";
171static const char* bundleStart = "<xliff version = \"1.0\">\n";
172static const char* bundleEnd = "</xliff>\n";
173
73c04bcf 174void res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status);
b75a7d8f 175
374ca955 176static char* convertAndEscape(char** pDest, int32_t destCap, int32_t* destLength,
b75a7d8f
A
177 const UChar* src, int32_t srcLen, UErrorCode* status){
178 int32_t srcIndex=0;
179 char* dest=NULL;
180 char* temp=NULL;
181 int32_t destLen=0;
182 UChar32 c = 0;
183
184 if(status==NULL || U_FAILURE(*status) || pDest==NULL || srcLen==0 || src == NULL){
185 return NULL;
186 }
187 dest =*pDest;
188 if(dest==NULL || destCap <=0){
189 destCap = srcLen * 8;
190 dest = (char*) uprv_malloc(sizeof(char) * destCap);
191 if(dest==NULL){
192 *status=U_MEMORY_ALLOCATION_ERROR;
193 return NULL;
194 }
195 }
196
197 dest[0]=0;
198
199 while(srcIndex<srcLen){
200 U16_NEXT(src, srcIndex, srcLen, c);
201
202 if (U16_IS_LEAD(c) || U16_IS_TRAIL(c)) {
203 *status = U_ILLEGAL_CHAR_FOUND;
204 fprintf(stderr, "Illegal Surrogate! \n");
205 uprv_free(dest);
206 return NULL;
374ca955 207 }
b75a7d8f
A
208
209 if((destLen+UTF8_CHAR_LENGTH(c)) < destCap){
210
211 /* ASCII Range */
212 if(c <=0x007F){
213 switch(c) {
214 case '&':
215 uprv_strcpy(dest+( destLen),"&amp;");
374ca955 216 destLen+=(int32_t)uprv_strlen("&amp;");
b75a7d8f
A
217 break;
218 case '<':
219 uprv_strcpy(dest+(destLen),"&lt;");
374ca955 220 destLen+=(int32_t)uprv_strlen("&lt;");
b75a7d8f
A
221 break;
222 case '>':
223 uprv_strcpy(dest+(destLen),"&gt;");
374ca955 224 destLen+=(int32_t)uprv_strlen("&gt;");
b75a7d8f
A
225 break;
226 case '"':
227 uprv_strcpy(dest+(destLen),"&quot;");
374ca955 228 destLen+=(int32_t)uprv_strlen("&quot;");
b75a7d8f
A
229 break;
230 case '\'':
231 uprv_strcpy(dest+(destLen),"&apos;");
374ca955 232 destLen+=(int32_t)uprv_strlen("&apos;");
b75a7d8f
A
233 break;
234
235 /* Disallow C0 controls except TAB, CR, LF*/
236 case 0x00:
237 case 0x01:
238 case 0x02:
239 case 0x03:
240 case 0x04:
241 case 0x05:
242 case 0x06:
243 case 0x07:
244 case 0x08:
245 /*case 0x09:*/
246 /*case 0x0A: */
247 case 0x0B:
248 case 0x0C:
249 /*case 0x0D:*/
250 case 0x0E:
251 case 0x0F:
252 case 0x10:
253 case 0x11:
254 case 0x12:
255 case 0x13:
256 case 0x14:
257 case 0x15:
258 case 0x16:
259 case 0x17:
260 case 0x18:
261 case 0x19:
262 case 0x1A:
263 case 0x1B:
264 case 0x1C:
265 case 0x1D:
266 case 0x1E:
267 case 0x1F:
268 *status = U_ILLEGAL_CHAR_FOUND;
374ca955 269 fprintf(stderr, "Illegal Character \\u%04X!\n",(int)c);
b75a7d8f
A
270 uprv_free(dest);
271 return NULL;
272 default:
273 dest[destLen++]=(char)c;
274 }
275 }else{
276 UBool isError = FALSE;
277 U8_APPEND((unsigned char*)dest,destLen,destCap,c,isError);
278 if(isError){
279 *status = U_ILLEGAL_CHAR_FOUND;
374ca955 280 fprintf(stderr, "Illegal Character \\U%08X!\n",(int)c);
b75a7d8f
A
281 uprv_free(dest);
282 return NULL;
374ca955 283 }
b75a7d8f
A
284 }
285 }else{
286 destCap += destLen;
374ca955 287
b75a7d8f
A
288 temp = (char*) uprv_malloc(sizeof(char)*destCap);
289 if(temp==NULL){
290 *status=U_MEMORY_ALLOCATION_ERROR;
73c04bcf 291 uprv_free(dest);
b75a7d8f
A
292 return NULL;
293 }
294 uprv_memmove(temp,dest,destLen);
295 destLen=0;
296 uprv_free(dest);
297 dest=temp;
298 temp=NULL;
299 }
300
301 }
302 *destLength = destLen;
303 return dest;
304}
305
374ca955
A
306#define ASTERISK 0x002A
307#define SPACE 0x0020
308#define CR 0x000A
309#define LF 0x000D
310#define AT_SIGN 0x0040
311
374ca955 312
374ca955
A
313
314
315
316static void
317trim(char **src, int32_t *len){
318
319 char *s = NULL;
320 int32_t i = 0;
321 if(src == NULL || *src == NULL){
322 return;
323 }
324 s = *src;
325 /* trim from the end */
326 for( i=(*len-1); i>= 0; i--){
327 switch(s[i]){
328 case ASTERISK:
329 case SPACE:
330 case CR:
331 case LF:
332 s[i] = 0;
333 continue;
334 default:
335 break;
336 }
337 break;
338
339 }
340 *len = i+1;
341}
342
343static void
344print(UChar* src, int32_t srcLen,const char *tagStart,const char *tagEnd, UErrorCode *status){
345 int32_t bufCapacity = srcLen*4;
346 char *buf = NULL;
347 int32_t bufLen = 0;
348
349 if(U_FAILURE(*status)){
350 return;
351 }
352
353 buf = (char*) (uprv_malloc(bufCapacity));
354 if(buf==0){
355 fprintf(stderr, "Could not allocate memory!!");
356 exit(U_MEMORY_ALLOCATION_ERROR);
357 }
358 buf = convertAndEscape(&buf, bufCapacity, &bufLen, src, srcLen,status);
359 if(U_SUCCESS(*status)){
360 trim(&buf,&bufLen);
361 T_FileStream_write(out,tagStart, (int32_t)uprv_strlen(tagStart));
362 T_FileStream_write(out, buf, bufLen);
363 T_FileStream_write(out,tagEnd, (int32_t)uprv_strlen(tagEnd));
364 T_FileStream_write(out,"\n",1);
365
366 }
367}
368static void
369printNoteElements(struct UString *src, UErrorCode *status){
370
371#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
372
373 int32_t capacity = 0;
374 UChar* note = NULL;
375 int32_t noteLen = 0;
376 int32_t count = 0,i;
377
378 if(src == NULL){
379 return;
380 }
381
382 capacity = src->fLength;
383 note = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
384
385 count = getCount(src->fChars,src->fLength, UPC_NOTE, status);
386 if(U_FAILURE(*status)){
387 return;
388 }
389 for(i=0; i < count; i++){
390 noteLen = getAt(src->fChars,src->fLength, &note, capacity, i, UPC_NOTE, status);
391 if(U_FAILURE(*status)){
392 return;
393 }
394 if(noteLen > 0){
395 write_tabs(out);
396 print(note, noteLen,"<note>", "</note>", status);
397 }
398 }
399 uprv_free(note);
400#else
b75a7d8f 401
374ca955
A
402 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
403
404#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
405
406}
407
408static void
409printComments(struct UString *src, const char *resName, UBool printTranslate, UErrorCode *status){
410
411#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
412
413 int32_t capacity = src->fLength;
414 char* buf = NULL;
415 int32_t bufLen = 0;
416 const char* translateAttr = " translate=\"";
417 UChar* desc = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
418 UChar* trans = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
419
420 int32_t descLen = 0, transLen=0;
421 if(status==NULL || U_FAILURE(*status)){
422 uprv_free(desc);
423 uprv_free(trans);
424 return;
425 }
426 if(desc==NULL || trans==NULL){
427 *status = U_MEMORY_ALLOCATION_ERROR;
428 uprv_free(desc);
429 uprv_free(trans);
430 return;
431 }
432 src->fLength = removeCmtText(src->fChars, src->fLength, status);
433 descLen = getDescription(src->fChars,src->fLength, &desc, capacity, status);
434 transLen = getTranslate(src->fChars,src->fLength, &trans, capacity, status);
435
436 /* first print translate attribute */
437 if(transLen > 0){
438 if(printTranslate==TRUE){
439 /* print translate attribute */
440 buf = convertAndEscape(&buf, 0, &bufLen, trans, transLen, status);
441 if(U_SUCCESS(*status)){
442 T_FileStream_write(out,translateAttr, (int32_t)uprv_strlen(translateAttr));
443 T_FileStream_write(out,buf, bufLen);
444 T_FileStream_write(out,"\">\n", 3);
445 }
446 }else if(getShowWarning() == TRUE){
447 fprintf(stderr, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName);
448 /* no translate attribute .. just close the tag */
449 T_FileStream_write(out,">\n", 2);
450 }
451 }else{
452 /* no translate attribute .. just close the tag */
453 T_FileStream_write(out,">\n", 2);
454 }
455 if(descLen > 0){
456 write_tabs(out);
457 print(desc, descLen, "<!--", "-->", status);
458 }
459#else
460
461 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
462
463#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
464
465}
b75a7d8f 466/* Writing Functions */
374ca955 467static void
b75a7d8f
A
468string_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) {
469
470 char* buf = NULL;
471 int32_t bufLen = 0;
374ca955 472
b75a7d8f
A
473 char* sid = NULL;
474 const char* strStart = "<trans-unit xml:space = \"preserve\" id = \"";
73c04bcf 475 const char* valStrStart = "<source ";
b75a7d8f
A
476 const char* valStrEnd = "</source>\n";
477 const char* strEnd = "</trans-unit>\n";
374ca955 478
b75a7d8f
A
479 if(status==NULL || U_FAILURE(*status)){
480 return;
481 }
482
374ca955 483 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f 484 write_tabs(out);
374ca955 485 T_FileStream_write(out,strStart, (int32_t)uprv_strlen(strStart));
b75a7d8f 486 sid = getID(id, NULL, sid);
374ca955
A
487 T_FileStream_write(out,sid, (int32_t)uprv_strlen(sid));
488 T_FileStream_write(out,"\"", 1);
b75a7d8f 489 tabCount++;
374ca955
A
490 if(res->fComment!=NULL && res->fComment->fChars != NULL){
491 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
492
493 }else{
494 T_FileStream_write(out,">\n", 2);
495 }
496
b75a7d8f 497 write_tabs(out);
374ca955
A
498
499 T_FileStream_write(out,valStrStart, (int32_t)uprv_strlen(valStrStart));
73c04bcf
A
500 /* T_FileStream_write(out,language, (int32_t)uprv_strlen(language)); */
501 T_FileStream_write(out,">", 1);
374ca955 502
b75a7d8f
A
503 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,status);
504
505 if(U_FAILURE(*status)){
506 return;
507 }
374ca955 508
b75a7d8f 509 T_FileStream_write(out,buf,bufLen);
374ca955
A
510 T_FileStream_write(out,valStrEnd,(int32_t)uprv_strlen(valStrEnd));
511
512 printNoteElements(res->fComment, status);
513
b75a7d8f
A
514 tabCount--;
515 write_tabs(out);
374ca955 516 T_FileStream_write(out,strEnd,(int32_t)uprv_strlen(strEnd));
b75a7d8f
A
517 }else{
518 const char* keyStrStart = "resname = \"";
374ca955 519
b75a7d8f 520 write_tabs(out);
374ca955
A
521
522 T_FileStream_write(out, strStart, (int32_t)uprv_strlen(strStart));
b75a7d8f 523 sid = getID(id, srBundle->fKeys+res->fKey,sid);
374ca955 524 T_FileStream_write(out,sid, (int32_t)uprv_strlen(sid));
b75a7d8f 525 T_FileStream_write(out,"\" ", 2);
374ca955
A
526 T_FileStream_write(out,keyStrStart, (int32_t)uprv_strlen(keyStrStart));
527
528 T_FileStream_write(out,srBundle->fKeys+res->fKey, (int32_t)uprv_strlen(srBundle->fKeys+res->fKey));
529 T_FileStream_write(out,"\"", 1);
b75a7d8f 530 tabCount++;
374ca955
A
531 if(res->fComment!=NULL && res->fComment->fChars != NULL){
532 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
533 }else{
534 T_FileStream_write(out,">\n", 2);
535 }
536
b75a7d8f 537 write_tabs(out);
374ca955 538 T_FileStream_write(out,valStrStart, (int32_t)uprv_strlen(valStrStart));
b75a7d8f 539
73c04bcf
A
540 /*T_FileStream_write(out,language, (int32_t)uprv_strlen(language));*/
541 T_FileStream_write(out,">", 1);
b75a7d8f
A
542
543 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,status);
544 if(U_FAILURE(*status)){
545 return;
546 }
547 T_FileStream_write(out,buf,bufLen);
548
374ca955
A
549 T_FileStream_write(out,valStrEnd,(int32_t)uprv_strlen(valStrEnd));
550
551 printNoteElements(res->fComment, status);
552
b75a7d8f
A
553 tabCount--;
554 write_tabs(out);
374ca955 555 T_FileStream_write(out,strEnd,(int32_t)uprv_strlen(strEnd));
b75a7d8f
A
556 }
557 uprv_free(sid);
374ca955
A
558 sid = NULL;
559
b75a7d8f
A
560 uprv_free(buf);
561 buf = NULL;
562}
563
374ca955 564static void
b75a7d8f
A
565alias_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) {
566 static const char* startKey = "resname=\"";
567 static const char* val = "<source>";
568 static const char* endKey = "</source>\n";
569 static const char* start = "<trans-unit restype = \"alias\" xml:space = \"preserve\" id = \"";
570 static const char* end = "</trans-unit>\n";
571 char* sid = NULL;
374ca955 572
b75a7d8f
A
573 char* buf = NULL;
574 int32_t bufLen=0;
575 write_tabs(out);
374ca955 576 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f 577 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
374ca955 578
b75a7d8f
A
579 sid = getID(id, NULL, sid);
580 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
374ca955 581 T_FileStream_write(out, "\"", 1);
b75a7d8f 582 tabCount++;
374ca955
A
583 if(res->fComment!=NULL && res->fComment->fChars != NULL){
584 printComments(res->fComment,srBundle->fKeys+res->fKey, TRUE, status);
585
586 }else{
587 T_FileStream_write(out,">\n", 2);
588 }
589 write_tabs(out);
b75a7d8f
A
590 T_FileStream_write(out, val, (int32_t)uprv_strlen(val));
591 }else{
592 sid = getID(id, srBundle->fKeys+res->fKey, sid);
593 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
594 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
595 T_FileStream_write(out, "\" ", 2);
596 T_FileStream_write(out, startKey, (int32_t)uprv_strlen(startKey));
597 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
598
599 T_FileStream_write(out, "\"", 1);
b75a7d8f 600 tabCount++;
374ca955
A
601 if(res->fComment!=NULL && res->fComment->fChars != NULL){
602 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
603
604 }else{
605 T_FileStream_write(out,">\n", 2);
606 }
607
b75a7d8f 608 write_tabs(out);
374ca955 609
b75a7d8f
A
610 T_FileStream_write(out, val, (int32_t)uprv_strlen(val));
611 }
374ca955 612
b75a7d8f
A
613 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,/*FALSE,*/status);
614 if(U_FAILURE(*status)){
615 return;
616 }
617 T_FileStream_write(out,buf,bufLen);
374ca955
A
618 T_FileStream_write(out, endKey, (int32_t)uprv_strlen(endKey));
619
620 printNoteElements(res->fComment, status);
621
b75a7d8f
A
622 tabCount--;
623 write_tabs(out);
374ca955
A
624
625 T_FileStream_write(out, end, (int32_t)uprv_strlen(end));
b75a7d8f
A
626 uprv_free(buf);
627 uprv_free(sid);
628}
629
374ca955 630static void
b75a7d8f
A
631array_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) {
632 const char* start = "<group restype = \"array\" xml:space = \"preserve\" id = \"";
633 const char* end = "</group>\n";
634 const char* startKey= "resname=\"";
374ca955 635
b75a7d8f
A
636 char* sid = NULL;
637 int index = 0;
374ca955 638
b75a7d8f
A
639 struct SResource *current = NULL;
640 struct SResource *first =NULL;
374ca955 641
b75a7d8f 642 write_tabs(out);
374ca955
A
643 tabCount++;
644 if(res->fKey<0 ||uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
645 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
646 sid = getID(id, NULL, sid);
647 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
374ca955
A
648 T_FileStream_write(out, "\"", 1);
649 if(res->fComment!=NULL && res->fComment->fChars != NULL){
650 printComments(res->fComment, sid, FALSE, status);
651 printNoteElements(res->fComment, status);
652 }else{
653 T_FileStream_write(out,">\n", 2);
654 }
b75a7d8f
A
655 }else{
656 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
657 sid = getID(id, srBundle->fKeys+res->fKey, sid);
658 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
659 T_FileStream_write(out, "\" ", 2);
660 T_FileStream_write(out, startKey, (int32_t)uprv_strlen(startKey));
661 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
662 T_FileStream_write(out, "\"", 1);
663 if(res->fComment!=NULL && res->fComment->fChars != NULL){
664 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
665 printNoteElements(res->fComment, status);
666 }else{
667 T_FileStream_write(out,">\n", 2);
668 }
b75a7d8f
A
669 }
670 current = res->u.fArray.fFirst;
671 first=current;
374ca955 672
b75a7d8f
A
673 while (current != NULL) {
674 char c[256] = {0};
675 char* subId = NULL;
676 itostr(c, index,10,0);
677 index++;
678 subId = getID(sid, c, subId);
374ca955 679
73c04bcf 680 res_write_xml(current, subId, language, FALSE, status);
b75a7d8f
A
681 uprv_free(subId);
682 subId = NULL;
683 if(U_FAILURE(*status)){
684 return;
685 }
686 current = current->fNext;
687 }
688 tabCount--;
689 write_tabs(out);
374ca955 690 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
b75a7d8f
A
691 uprv_free(sid);
692 sid = NULL;
693}
694
374ca955 695static void
b75a7d8f
A
696intvector_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) {
697 const char* start = "<group restype = \"intvector\" xml:space = \"preserve\" id = \"";
698 const char* end = "</group>\n";
699 const char* startKey= "resname=\"";
b75a7d8f 700
73c04bcf 701 const char* intStart = "<trans-unit restype = \"int\" xml:space = \"preserve\" id = \"";
b75a7d8f
A
702 const char* valIntStart = "<source>";
703 const char* valIntEnd = "</source>\n";
704 const char* intEnd = "</trans-unit>\n";
705 char* sid = NULL;
706 char* ivd = NULL;
374ca955 707
b75a7d8f
A
708 uint32_t i=0;
709 uint32_t len=0;
710 char buf[256] = {'0'};
711 write_tabs(out);
374ca955
A
712 tabCount++;
713
714 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
715 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
716 sid = getID(id, NULL, sid);
374ca955
A
717 T_FileStream_write(out,sid, (int32_t)uprv_strlen(sid));
718 T_FileStream_write(out, "\"", 1);
719 if(res->fComment!=NULL && res->fComment->fChars != NULL){
720 printComments(res->fComment, sid, FALSE, status);
721
722 }else{
723 T_FileStream_write(out,">\n", 2);
724 }
b75a7d8f
A
725 }else{
726 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
727 sid = getID(id, srBundle->fKeys+res->fKey, sid);
374ca955 728 T_FileStream_write(out,sid, (int32_t)uprv_strlen(sid));
b75a7d8f 729 T_FileStream_write(out,"\" ", 2);
374ca955 730
b75a7d8f
A
731 T_FileStream_write(out, startKey, (int32_t)uprv_strlen(startKey));
732 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
733 T_FileStream_write(out, "\"", 1);
734 if(res->fComment!=NULL && res->fComment->fChars != NULL){
735 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
736 printNoteElements(res->fComment, status);
737 }else{
738 T_FileStream_write(out,">\n", 2);
739 }
b75a7d8f 740 }
374ca955
A
741
742
b75a7d8f
A
743 for(i = 0; i<res->u.fIntVector.fCount; i++) {
744 char c[256] = {0};
745 itostr(c, i,10,0);
746 ivd = getID(sid, c, ivd);
747 len=itostr(buf,res->u.fIntVector.fArray[i],10,0);
374ca955 748
b75a7d8f
A
749 write_tabs(out);
750 T_FileStream_write(out, intStart, (int32_t)uprv_strlen(intStart));
374ca955 751 T_FileStream_write(out, ivd, (int32_t)uprv_strlen(ivd));
b75a7d8f
A
752 T_FileStream_write(out,"\">\n", 3);
753 tabCount++;
754 write_tabs(out);
374ca955
A
755 T_FileStream_write(out,valIntStart, (int32_t)uprv_strlen(valIntStart));
756
b75a7d8f 757 T_FileStream_write(out,buf,len);
374ca955
A
758
759 T_FileStream_write(out,valIntEnd, (int32_t)uprv_strlen(valIntEnd));
b75a7d8f
A
760 tabCount--;
761 write_tabs(out);
762 T_FileStream_write(out, intEnd, (int32_t)uprv_strlen(intEnd));
374ca955 763
b75a7d8f
A
764 uprv_free(ivd);
765 ivd = NULL;
766 }
374ca955 767
b75a7d8f
A
768 tabCount--;
769 write_tabs(out);
374ca955
A
770
771 T_FileStream_write(out, end, (int32_t)uprv_strlen(end));
b75a7d8f
A
772 uprv_free(sid);
773 sid = NULL;
774}
775
374ca955 776static void
b75a7d8f 777int_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) {
374ca955 778 const char* intStart = "<trans-unit restype = \"int\" xml:space = \"preserve\" id = \"";
b75a7d8f
A
779 const char* valIntStart = "<source>";
780 const char* valIntEnd = "</source>\n";
781 const char* intEnd = "</trans-unit>\n";
782 const char* keyIntStart = "resname = \"";
783 char* sid = NULL;
784 char buf[256] = {0};
374ca955 785
b75a7d8f
A
786 uint32_t len=0;
787 write_tabs(out);
374ca955 788
b75a7d8f 789 tabCount++;
374ca955
A
790
791 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
792 T_FileStream_write(out, intStart, (int32_t)uprv_strlen(intStart));
793 sid = getID(id, NULL, sid);
374ca955
A
794 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
795 T_FileStream_write(out,"\"", 1);
796
797 if(res->fComment!=NULL && res->fComment->fChars != NULL){
798 printComments(res->fComment, sid, TRUE, status);
799
800 }else{
801 T_FileStream_write(out,">\n", 2);
802 }
b75a7d8f 803 write_tabs(out);
374ca955 804 T_FileStream_write(out,valIntStart, (int32_t)uprv_strlen(valIntStart));
b75a7d8f 805 }else{
374ca955 806 T_FileStream_write(out, intStart, (int32_t)uprv_strlen(intStart));
b75a7d8f 807 sid = getID(id, srBundle->fKeys+res->fKey, sid);
374ca955 808 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
b75a7d8f 809 T_FileStream_write(out,"\" ", 2);
374ca955
A
810 T_FileStream_write(out,keyIntStart, (int32_t)uprv_strlen(keyIntStart));
811
b75a7d8f 812 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
813 T_FileStream_write(out,"\"", 1);
814
815 if(res->fComment!=NULL && res->fComment->fChars != NULL){
816 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
817
818 }else{
819 T_FileStream_write(out,">\n", 2);
820 }
b75a7d8f
A
821 write_tabs(out);
822 T_FileStream_write(out, valIntStart, (int32_t)uprv_strlen(valIntStart));
374ca955 823
b75a7d8f
A
824 }
825 len=itostr(buf,res->u.fIntValue.fValue,10,0);
826 T_FileStream_write(out,buf,len);
374ca955
A
827
828 T_FileStream_write(out, valIntEnd, (int32_t)uprv_strlen(valIntEnd));
829 printNoteElements(res->fComment, status);
b75a7d8f
A
830 tabCount--;
831 write_tabs(out);
374ca955 832 T_FileStream_write(out, intEnd, (int32_t)uprv_strlen(intEnd));
b75a7d8f
A
833 uprv_free(sid);
834 sid = NULL;
835}
836
374ca955 837static void
b75a7d8f 838bin_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) {
374ca955
A
839 const char* start = "<bin-unit restype = \"bin\" id = \"";
840 const char* importStart = "<bin-unit restype = \"import\" id = \"";
b75a7d8f
A
841 const char* mime = " mime-type = ";
842 const char* key = "\" resname = \"";
843 const char* valStart = "<bin-source>\n";
844 const char* fileStart = "<internal-file form = \"application\" crc = \"";
845 const char* fileEnd = "</internal-file>\n";
846 const char* valEnd = "</bin-source>\n";
847 const char* end = "</bin-unit>\n";
848 const char* externalFileStart = "<external-file href = \"";
849 const char* externalFileEnd = "\"/>\n";
850 const char* m_type = "\"application";
851 char* sid = NULL;
852 uint32_t crc = 0xFFFFFFFF;
374ca955 853
b75a7d8f 854 char fileName[1024] ={0};
374ca955
A
855 int32_t tLen = ( outDir == NULL) ? 0 :(int32_t)uprv_strlen(outDir);
856 char* fn = (char*) uprv_malloc(sizeof(char) * (tLen+1024 +
857 (res->u.fBinaryValue.fFileName !=NULL ?
b75a7d8f
A
858 uprv_strlen(res->u.fBinaryValue.fFileName) :0)));
859 const char* ext = NULL;
374ca955
A
860
861 char* f = NULL;
862
b75a7d8f
A
863 fn[0]=0;
864
865 if(res->u.fBinaryValue.fFileName!=NULL){
866 uprv_strcpy(fileName, res->u.fBinaryValue.fFileName);
867 f = uprv_strrchr(fileName, '\\');
73c04bcf
A
868 if (f != NULL) {
869 f++;
870 }
871 else {
872 f = fileName;
873 }
b75a7d8f
A
874 ext = uprv_strrchr(fileName, '.');
875
73c04bcf
A
876 if (ext == NULL) {
877 fprintf(stderr, "Error: %s is an unknown binary filename type.\n", fileName);
878 exit(U_ILLEGAL_ARGUMENT_ERROR);
879 }
b75a7d8f
A
880 if(uprv_strcmp(ext, ".jpg")==0 || uprv_strcmp(ext, ".jpeg")==0 || uprv_strcmp(ext, ".gif")==0 ){
881 m_type = "\"image";
882 } else if(uprv_strcmp(ext, ".wav")==0 || uprv_strcmp(ext, ".au")==0 ){
883 m_type = "\"audio";
884 } else if(uprv_strcmp(ext, ".avi")==0 || uprv_strcmp(ext, ".mpg")==0 || uprv_strcmp(ext, ".mpeg")==0){
885 m_type = "\"video";
886 } else if(uprv_strcmp(ext, ".txt")==0 || uprv_strcmp(ext, ".text")==0){
887 m_type = "\"text";
888 }
889
890 write_tabs(out);
891 T_FileStream_write(out, importStart, (int32_t)uprv_strlen(importStart));
374ca955 892 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
893 sid = getID(id, NULL, sid);
894 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
895 } else {
896 sid = getID(id, srBundle->fKeys+res->fKey, sid);
897 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
898 }
899 T_FileStream_write(out, "\" ", 2);
900 T_FileStream_write(out, mime, (int32_t)uprv_strlen(mime));
901 T_FileStream_write(out, m_type, (int32_t)uprv_strlen(m_type));
374ca955 902 if(!(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0)){
b75a7d8f
A
903 T_FileStream_write(out, key, (int32_t)uprv_strlen(key));
904 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
905 }
906 T_FileStream_write(out,"\"", 1);
b75a7d8f 907 tabCount++;
374ca955
A
908 if(res->fComment!=NULL && res->fComment->fChars != NULL){
909 printComments(res->fComment, sid, TRUE, status);
910
911 }else{
912 T_FileStream_write(out,">\n", 2);
913 }
914
b75a7d8f 915 write_tabs(out);
374ca955
A
916
917 T_FileStream_write(out, valStart, (int32_t)uprv_strlen(valStart));
b75a7d8f
A
918 tabCount++;
919 write_tabs(out);
374ca955 920 T_FileStream_write(out, externalFileStart, (int32_t)uprv_strlen(externalFileStart));
b75a7d8f 921 T_FileStream_write(out, f, (int32_t)uprv_strlen(f));
374ca955 922 T_FileStream_write(out, externalFileEnd, (int32_t)uprv_strlen(externalFileEnd));
b75a7d8f
A
923 tabCount--;
924 write_tabs(out);
374ca955
A
925 T_FileStream_write(out, valEnd, (int32_t)uprv_strlen(valEnd));
926
927 printNoteElements(res->fComment, status);
b75a7d8f
A
928 tabCount--;
929 write_tabs(out);
374ca955 930 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
b75a7d8f
A
931 } else {
932 char temp[256] = {0};
933 uint32_t i = 0;
934 int32_t len=0;
935
936 write_tabs(out);
937 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
374ca955 938 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
939 sid = getID(id, NULL, sid);
940 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
941 } else {
942 sid = getID(id, srBundle->fKeys+res->fKey, sid);
943 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
944 }
374ca955 945
b75a7d8f
A
946 T_FileStream_write(out, "\" ", 2);
947 T_FileStream_write(out, mime, (int32_t)uprv_strlen(mime));
948 T_FileStream_write(out, m_type, (int32_t)uprv_strlen(m_type));
374ca955 949 if(!(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0)){
b75a7d8f
A
950 T_FileStream_write(out, key, (int32_t)uprv_strlen(key));
951 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
952 }
374ca955 953 T_FileStream_write(out,"\"", 1);
b75a7d8f 954 tabCount++;
374ca955
A
955 if(res->fComment!=NULL && res->fComment->fChars != NULL){
956 printComments(res->fComment, sid, TRUE, status);
957
958 }else{
959 T_FileStream_write(out,">\n", 2);
960 }
961
b75a7d8f 962 write_tabs(out);
374ca955 963 T_FileStream_write(out, valStart, (int32_t)uprv_strlen(valStart));
b75a7d8f
A
964 tabCount++;
965 write_tabs(out);
374ca955
A
966 T_FileStream_write(out, fileStart, (int32_t)uprv_strlen(fileStart));
967
b75a7d8f
A
968 while(i <res->u.fBinaryValue.fLength){
969 len = itostr(temp,res->u.fBinaryValue.fData[i],16,2);
970 crc = computeCRC(temp, len, crc);
971 i++;
972 }
374ca955 973
b75a7d8f
A
974 len = itostr(temp, crc, 10, 0);
975 T_FileStream_write(out,temp,len);
976 T_FileStream_write(out,"\">",2);
374ca955 977
b75a7d8f
A
978 i = 0;
979 while(i <res->u.fBinaryValue.fLength){
980 len = itostr(temp,res->u.fBinaryValue.fData[i],16,2);
981 T_FileStream_write(out,temp,len);
982 i++;
983 }
374ca955 984 T_FileStream_write(out, fileEnd, (int32_t)uprv_strlen(fileEnd));
b75a7d8f
A
985 tabCount--;
986 write_tabs(out);
374ca955
A
987 T_FileStream_write(out, valEnd, (int32_t)uprv_strlen(valEnd));
988 printNoteElements(res->fComment, status);
989
b75a7d8f
A
990 tabCount--;
991 write_tabs(out);
374ca955
A
992 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
993
b75a7d8f
A
994 uprv_free(sid);
995 sid = NULL;
996 }
73c04bcf 997 uprv_free(fn);
b75a7d8f
A
998}
999
1000
1001
374ca955 1002static void
73c04bcf 1003table_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
b75a7d8f
A
1004
1005 uint32_t i = 0;
1006
1007 struct SResource *current = NULL;
1008 struct SResource *save = NULL;
1009
1010 char* sid = NULL;
1011 const char* start = "<group restype = \"table\" xml:space = \"preserve\"";
1012 const char* idstr = " id = \"";
1013 const char* end = "</group>\n";
1014 const char* startKey= "resname=\"";
b75a7d8f
A
1015
1016 if (U_FAILURE(*status)) {
1017 return ;
1018 }
374ca955 1019
b75a7d8f
A
1020 if (res->u.fTable.fCount > 0) {
1021 write_tabs(out);
374ca955
A
1022 tabCount++;
1023
1024 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f 1025 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
374ca955 1026
73c04bcf
A
1027 if(isTopLevel){
1028 int32_t len = uprv_strlen(id);
1029 T_FileStream_write(out, idstr, (int32_t)uprv_strlen(idstr));
1030 T_FileStream_write(out, id,len);
1031 T_FileStream_write(out, "\" ", 2);
1032 id="";
1033 }
b75a7d8f
A
1034 sid = getID(id, NULL, sid);
1035 /* only write the id if the sid!="" */
1036 if(sid[0]!='\0'){
1037 T_FileStream_write(out, idstr, (int32_t)uprv_strlen(idstr));
1038 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
1039 T_FileStream_write(out, "\" ", 2);
1040
1041 }
374ca955 1042
73c04bcf 1043
374ca955
A
1044 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1045 printComments(res->fComment, sid, FALSE, status);
1046 printNoteElements(res->fComment, status);
1047 }else{
1048 T_FileStream_write(out,">\n", 2);
1049 }
b75a7d8f
A
1050 }else{
1051 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
1052 sid = getID(id, srBundle->fKeys+res->fKey, sid);
1053
1054 /* only write the id if the sid!="" */
1055 if(sid[0]!='\0'){
1056 T_FileStream_write(out, idstr, (int32_t)uprv_strlen(idstr));
1057 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
1058 T_FileStream_write(out, "\" ", 2);
1059 }
374ca955 1060
b75a7d8f
A
1061 T_FileStream_write(out, startKey, (int32_t)uprv_strlen(startKey));
1062 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
1063 T_FileStream_write(out, "\" ", 2);
374ca955
A
1064
1065 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1066 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
1067 printNoteElements(res->fComment, status);
1068 }else{
1069 T_FileStream_write(out,">\n", 2);
1070 }
b75a7d8f 1071 }
374ca955 1072
b75a7d8f
A
1073 save = current = res->u.fTable.fFirst;
1074 i = 0;
1075 while (current != NULL) {
73c04bcf 1076 res_write_xml(current, sid, language, FALSE, status);
374ca955 1077
b75a7d8f
A
1078 if(U_FAILURE(*status)){
1079 return;
1080 }
1081 i++;
1082 current = current->fNext;
1083 }
1084 tabCount--;
1085 write_tabs(out);
374ca955 1086 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
b75a7d8f
A
1087 } else {
1088 write_tabs(out);
374ca955 1089 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
b75a7d8f
A
1090 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
1091 sid = getID(id, NULL, sid);
1092 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
374ca955
A
1093 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1094 printComments(res->fComment, sid, FALSE, status);
1095 printNoteElements(res->fComment, status);
1096 }else{
1097 T_FileStream_write(out,">\n", 2);
1098 }
b75a7d8f
A
1099 }else{
1100 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
1101 sid = getID(id, srBundle->fKeys+res->fKey, sid);
1102 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
1103 T_FileStream_write(out, "\" ", 2);
1104 T_FileStream_write(out, startKey, (int32_t)uprv_strlen(startKey));
1105 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
374ca955
A
1106
1107 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1108 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
1109 printNoteElements(res->fComment, status);
1110 }else{
1111 T_FileStream_write(out,">\n", 2);
1112 }
b75a7d8f 1113 }
374ca955 1114
b75a7d8f 1115 write_tabs(out);
374ca955 1116 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
b75a7d8f
A
1117 }
1118 uprv_free(sid);
1119 sid = NULL;
1120}
1121
374ca955 1122void
73c04bcf 1123res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
374ca955 1124
b75a7d8f
A
1125 if (U_FAILURE(*status)) {
1126 return ;
1127 }
1128
1129 if (res != NULL) {
1130 switch (res->fType) {
1131 case URES_STRING:
1132 string_write_xml (res, id, language, status);
1133 return;
1134 case URES_ALIAS:
1135 alias_write_xml (res, id, language, status);
1136 return;
1137 case URES_INT_VECTOR:
1138 intvector_write_xml (res, id, language, status);
1139 return;
1140 case URES_BINARY:
1141 bin_write_xml (res, id, language, status);
1142 return;
1143 case URES_INT:
1144 int_write_xml (res, id, language, status);
1145 return;
1146 case URES_ARRAY:
1147 array_write_xml (res, id, language, status);
1148 return;
1149 case URES_TABLE:
374ca955 1150 case URES_TABLE32:
73c04bcf 1151 table_write_xml (res, id, language, isTopLevel, status);
b75a7d8f
A
1152 return;
1153
1154 default:
1155 break;
1156 }
1157 }
1158
1159 *status = U_INTERNAL_PROGRAM_ERROR;
1160}
1161
374ca955 1162void
b75a7d8f 1163bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* filename,
374ca955
A
1164 char *writtenFilename, int writtenFilenameLen,
1165 const char* language, const char* outFileName, UErrorCode *status) {
b75a7d8f
A
1166
1167 char* xmlfileName = NULL;
1168 char* outputFileName = NULL;
1169 char* originalFileName = NULL;
1170 const char* fileStart = "<file xml:space = \"preserve\" source-language = \"";
73c04bcf 1171 const char* file1 = "\" datatype = \"ICUResourceBundle\" ";
b75a7d8f
A
1172 const char* file2 = "original = \"";
1173 const char* file3 = "\" tool = \"genrb\" ";
1174 const char* file4 = "date = \"";
b75a7d8f
A
1175 const char* fileEnd = "</file>\n";
1176 const char* headerStart = "<header>";
1177 const char* headerEnd = "</header>\n";
1178 const char* bodyStart = "<body>\n";
1179 const char* bodyEnd = "</body>\n";
374ca955 1180
b75a7d8f
A
1181 char* pid = NULL;
1182 char* temp = NULL;
1183 char* lang = NULL;
1184 char* pos;
374ca955 1185 int32_t first, index;
b75a7d8f
A
1186 time_t currTime;
1187 char timeBuf[128];
374ca955 1188
b75a7d8f
A
1189 outDir = outputDir;
1190
1191 srBundle = bundle;
374ca955 1192
b75a7d8f
A
1193 pos = uprv_strrchr(filename, '\\');
1194 if(pos != NULL) {
374ca955 1195 first = (int32_t)(pos - filename + 1);
b75a7d8f
A
1196 } else {
1197 first = 0;
1198 }
374ca955 1199 index = (int32_t)(uprv_strlen(filename) - uprv_strlen(textExt) - first);
b75a7d8f
A
1200 originalFileName = uprv_malloc(sizeof(char)*index+1);
1201 uprv_memset(originalFileName, 0, sizeof(char)*index+1);
1202 uprv_strncpy(originalFileName, filename + first, index);
374ca955 1203
b75a7d8f 1204 if(uprv_strcmp(originalFileName, srBundle->fLocale) != 0) {
374ca955 1205 fprintf(stdout, "Warning: The file name is not same as the resource name!\n");
b75a7d8f
A
1206 }
1207
1208 temp = originalFileName;
1209 originalFileName = uprv_malloc(sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1);
1210 uprv_memset(originalFileName, 0, sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1);
1211 uprv_strcat(originalFileName, temp);
1212 uprv_strcat(originalFileName, textExt);
1213 uprv_free(temp);
1214 temp = NULL;
1215
73c04bcf 1216
b75a7d8f 1217 if (language == NULL) {
73c04bcf
A
1218/* lang = parseFilename(filename, lang);
1219 if (lang == NULL) {*/
374ca955
A
1220 /* now check if locale name is valid or not
1221 * this is to cater for situation where
1222 * pegasusServer.txt contains
1223 *
1224 * en{
1225 * ..
1226 * }
1227 */
1228 lang = parseFilename(srBundle->fLocale, lang);
1229 /*
1230 * Neither the file name nor the table name inside the
1231 * txt file contain a valid country and language codes
1232 * throw an error.
1233 * pegasusServer.txt contains
1234 *
1235 * testelements{
1236 * ....
1237 * }
1238 */
1239 if(lang==NULL){
1240 fprintf(stderr, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
1241 exit(U_ILLEGAL_ARGUMENT_ERROR);
1242 }
73c04bcf 1243 /* }*/
b75a7d8f
A
1244 } else {
1245 lang = uprv_malloc(sizeof(char)*uprv_strlen(language) +1);
1246 uprv_memset(lang, 0, sizeof(char)*uprv_strlen(language) +1);
1247 uprv_strcpy(lang, language);
1248 }
1249
374ca955
A
1250 if(outFileName) {
1251 outputFileName = uprv_malloc(sizeof(char)*uprv_strlen(outFileName) + 1);
1252 uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(outFileName) + 1);
1253 uprv_strcpy(outputFileName,outFileName);
b75a7d8f
A
1254 } else {
1255 outputFileName = uprv_malloc(sizeof(char)*uprv_strlen(srBundle->fLocale) + 1);
1256 uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(srBundle->fLocale) + 1);
1257 uprv_strcpy(outputFileName,srBundle->fLocale);
1258 }
374ca955 1259
b75a7d8f
A
1260 if(outputDir) {
1261 xmlfileName = uprv_malloc(sizeof(char)*(uprv_strlen(outputDir) + uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1);
1262 uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputDir)+ uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1);
1263 } else {
1264 xmlfileName = uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1);
1265 uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1);
1266 }
374ca955 1267
b75a7d8f
A
1268 if(outputDir){
1269 uprv_strcpy(xmlfileName, outputDir);
1270 if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){
1271 uprv_strcat(xmlfileName,U_FILE_SEP_STRING);
1272 }
1273 }
1274 uprv_strcat(xmlfileName,outputFileName);
1275 uprv_strcat(xmlfileName,xliffExt);
1276
1277 if (writtenFilename) {
1278 uprv_strncpy(writtenFilename, xmlfileName, writtenFilenameLen);
1279 }
1280
1281 if (U_FAILURE(*status)) {
73c04bcf 1282 goto cleanup_bundle_write_xml;
b75a7d8f 1283 }
374ca955 1284
b75a7d8f
A
1285 out= T_FileStream_open(xmlfileName,"w");
1286
1287 if(out==NULL){
1288 *status = U_FILE_ACCESS_ERROR;
73c04bcf 1289 goto cleanup_bundle_write_xml;
b75a7d8f 1290 }
374ca955
A
1291 T_FileStream_write(out,xmlHeader, (int32_t)uprv_strlen(xmlHeader));
1292
b75a7d8f
A
1293 if(outputEnc && *outputEnc!='\0'){
1294 /* store the output encoding */
1295 enc = outputEnc;
1296 conv=ucnv_open(enc,status);
1297 if(U_FAILURE(*status)){
73c04bcf 1298 goto cleanup_bundle_write_xml;
b75a7d8f
A
1299 }
1300 }
374ca955 1301 T_FileStream_write(out,bundleStart, (int32_t)uprv_strlen(bundleStart));
b75a7d8f 1302 write_tabs(out);
374ca955
A
1303 T_FileStream_write(out, fileStart, (int32_t)uprv_strlen(fileStart));
1304 /* check if lang and language are the same */
1305 if(language != NULL && uprv_strcmp(lang, srBundle->fLocale)!=0){
1306 fprintf(stderr,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
1307 }
1308 T_FileStream_write(out,lang, (int32_t)uprv_strlen(lang));
1309 T_FileStream_write(out,file1, (int32_t)uprv_strlen(file1));
1310 T_FileStream_write(out,file2, (int32_t)uprv_strlen(file2));
1311 T_FileStream_write(out,originalFileName, (int32_t)uprv_strlen(originalFileName));
1312 T_FileStream_write(out,file3, (int32_t)uprv_strlen(file3));
1313 T_FileStream_write(out,file4, (int32_t)uprv_strlen(file4));
b75a7d8f
A
1314
1315 time(&currTime);
1316 strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime));
374ca955 1317 T_FileStream_write(out,timeBuf, (int32_t)uprv_strlen(timeBuf));
b75a7d8f 1318
b75a7d8f
A
1319 T_FileStream_write(out,"\">\n", 3);
1320
1321 tabCount++;
1322 write_tabs(out);
374ca955
A
1323 T_FileStream_write(out,headerStart, (int32_t)uprv_strlen(headerStart));
1324 T_FileStream_write(out,headerEnd, (int32_t)uprv_strlen(headerEnd));
b75a7d8f
A
1325 write_tabs(out);
1326 tabCount++;
374ca955
A
1327 T_FileStream_write(out,bodyStart, (int32_t)uprv_strlen(bodyStart));
1328
1329
73c04bcf 1330 res_write_xml(bundle->fRoot, bundle->fLocale, lang, TRUE, status);
b75a7d8f
A
1331
1332 tabCount--;
1333 write_tabs(out);
374ca955 1334 T_FileStream_write(out,bodyEnd, (int32_t)uprv_strlen(bodyEnd));
b75a7d8f
A
1335 tabCount--;
1336 write_tabs(out);
374ca955 1337 T_FileStream_write(out,fileEnd, (int32_t)uprv_strlen(fileEnd));
b75a7d8f
A
1338 tabCount--;
1339 write_tabs(out);
374ca955 1340 T_FileStream_write(out,bundleEnd,(int32_t)uprv_strlen(bundleEnd));
b75a7d8f
A
1341 T_FileStream_close(out);
1342
1343 ucnv_close(conv);
1344
73c04bcf 1345cleanup_bundle_write_xml:
b75a7d8f
A
1346 if(originalFileName!= NULL) {
1347 uprv_free(originalFileName);
1348 originalFileName = NULL;
1349 }
1350 if(lang != NULL) {
1351 uprv_free(lang);
1352 lang = NULL;
1353 }
1354 if(pid != NULL) {
1355 uprv_free(pid);
1356 pid = NULL;
1357 }
1358 if(xmlfileName != NULL) {
1359 uprv_free(xmlfileName);
1360 pid = NULL;
1361 }
1362 if(outputFileName != NULL){
1363 uprv_free(outputFileName);
374ca955
A
1364 pid = NULL;
1365 }
b75a7d8f 1366}