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