]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/genrb/reslist.c
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / tools / genrb / reslist.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
4* Copyright (C) 2000-2003, International Business Machines
5* Corporation and others. All Rights Reserved.
6*
7*******************************************************************************
8*
9* File reslist.c
10*
11* Modification History:
12*
13* Date Name Description
14* 02/21/00 weiv Creation.
15*******************************************************************************
16*/
17
18#include <assert.h>
19#include "reslist.h"
20#include "unewdata.h"
21#include "unicode/ures.h"
22#include "errmsg.h"
23
24#define BIN_ALIGNMENT 16
25
26static UBool gIncludeCopyright = FALSE;
27
28uint32_t res_write(UNewDataMemory *mem, struct SResource *res,
29 uint32_t usedOffset, UErrorCode *status);
30
31static const UDataInfo dataInfo= {
32 sizeof(UDataInfo),
33 0,
34
35 U_IS_BIG_ENDIAN,
36 U_CHARSET_FAMILY,
37 sizeof(UChar),
38 0,
39
40 {0x52, 0x65, 0x73, 0x42}, /* dataFormat="resb" */
41 {1, 0, 0, 0}, /* formatVersion */
42 {1, 4, 0, 0} /* dataVersion take a look at version inside parsed resb*/
43};
44
45static uint8_t calcPadding(uint32_t size) {
46 /* returns space we need to pad */
47 return (uint8_t) ((size % sizeof(uint32_t)) ? (sizeof(uint32_t) - (size % sizeof(uint32_t))) : 0);
48
49}
50
51void setIncludeCopyright(UBool val){
52 gIncludeCopyright=val;
53}
54
55UBool getIncludeCopyright(void){
56 return gIncludeCopyright;
57}
58
59/* Writing Functions */
60static uint32_t string_write(UNewDataMemory *mem, struct SResource *res,
61 uint32_t usedOffset, UErrorCode *status) {
62 udata_write32(mem, res->u.fString.fLength);
63 udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1);
64 udata_writePadding(mem, calcPadding(res->fSize));
65
66 return usedOffset;
67}
68
69/* Writing Functions */
70static uint32_t alias_write(UNewDataMemory *mem, struct SResource *res,
71 uint32_t usedOffset, UErrorCode *status) {
72 udata_write32(mem, res->u.fString.fLength);
73 udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1);
74 udata_writePadding(mem, calcPadding(res->fSize));
75
76 return usedOffset;
77}
78
79static uint32_t array_write(UNewDataMemory *mem, struct SResource *res,
80 uint32_t usedOffset, UErrorCode *status) {
81 uint32_t *resources = NULL;
82 uint32_t i = 0;
83
84 struct SResource *current = NULL;
85
86 if (U_FAILURE(*status)) {
87 return 0;
88 }
89
90 if (res->u.fArray.fCount > 0) {
91 resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fArray.fCount);
92
93 if (resources == NULL) {
94 *status = U_MEMORY_ALLOCATION_ERROR;
95 return 0;
96 }
97
98 current = res->u.fArray.fFirst;
99 i = 0;
100
101 while (current != NULL) {
102 if (current->fType == URES_INT) {
103 resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF);
104 } else if (current->fType == URES_BINARY) {
105 uint32_t uo = usedOffset;
106
107 usedOffset = res_write(mem, current, usedOffset, status);
108 resources[i] = (current->fType << 28) | (usedOffset >> 2);
109 usedOffset += current->fSize + calcPadding(current->fSize) - (usedOffset - uo);
110 } else {
111 usedOffset = res_write(mem, current, usedOffset, status);
112 resources[i] = (current->fType << 28) | (usedOffset >> 2);
113 usedOffset += current->fSize + calcPadding(current->fSize);
114 }
115
116 i++;
117 current = current->fNext;
118 }
119
120 /* usedOffset += res->fSize + pad; */
121
122 udata_write32(mem, res->u.fArray.fCount);
123 udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fArray.fCount);
124 uprv_free(resources);
125 } else {
126 /* array is empty */
127 udata_write32(mem, 0);
128 }
129
130 return usedOffset;
131}
132
133static uint32_t intvector_write(UNewDataMemory *mem, struct SResource *res,
134 uint32_t usedOffset, UErrorCode *status) {
135 uint32_t i = 0;
136 udata_write32(mem, res->u.fIntVector.fCount);
137 for(i = 0; i<res->u.fIntVector.fCount; i++) {
138 udata_write32(mem, res->u.fIntVector.fArray[i]);
139 }
140
141 return usedOffset;
142}
143
144static uint32_t bin_write(UNewDataMemory *mem, struct SResource *res,
145 uint32_t usedOffset, UErrorCode *status) {
146 uint32_t pad = 0;
147 uint32_t extrapad = calcPadding(res->fSize);
148 uint32_t dataStart = usedOffset + sizeof(res->u.fBinaryValue.fLength);
149
150 if (dataStart % BIN_ALIGNMENT) {
151 pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT);
152 udata_writePadding(mem, pad);
153 usedOffset += pad;
154 }
155
156 udata_write32(mem, res->u.fBinaryValue.fLength);
157 if (res->u.fBinaryValue.fLength > 0) {
158 udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength);
159 }
160 udata_writePadding(mem, (BIN_ALIGNMENT - pad + extrapad));
161
162 return usedOffset;
163}
164
165static uint32_t int_write(UNewDataMemory *mem, struct SResource *res,
166 uint32_t usedOffset, UErrorCode *status) {
167 return usedOffset;
168}
169
170static uint32_t table_write(UNewDataMemory *mem, struct SResource *res,
171 uint32_t usedOffset, UErrorCode *status) {
172 uint8_t pad = 0;
173 uint32_t i = 0;
174 uint16_t *keys = NULL;
175 uint32_t *resources = NULL;
176
177 struct SResource *current = NULL;
178
179 if (U_FAILURE(*status)) {
180 return 0;
181 }
182
183 pad = calcPadding(res->fSize);
184
185 if (res->u.fTable.fCount > 0) {
186 keys = (uint16_t *) uprv_malloc(sizeof(uint16_t) * res->u.fTable.fCount);
187
188 if (keys == NULL) {
189 *status = U_MEMORY_ALLOCATION_ERROR;
190 return 0;
191 }
192
193 resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fTable.fCount);
194
195 if (resources == NULL) {
196 uprv_free(keys);
197 *status = U_MEMORY_ALLOCATION_ERROR;
198 return 0;
199 }
200
201 current = res->u.fTable.fFirst;
202 i = 0;
203
204 while (current != NULL) {
205 assert(i < res->u.fTable.fCount);
206
207 /* where the key is plus root pointer */
208 keys[i] = (uint16_t) (current->fKey + sizeof(uint32_t));
209
210 if (current->fType == URES_INT) {
211 resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF);
212 } else if (current->fType == URES_BINARY) {
213 uint32_t uo = usedOffset;
214
215 usedOffset = res_write(mem, current, usedOffset, status);
216 resources[i] = (current->fType << 28) | (usedOffset >> 2);
217 usedOffset += current->fSize + calcPadding(current->fSize) - (usedOffset - uo);
218 } else {
219 usedOffset = res_write(mem, current, usedOffset, status);
220 resources[i] = (current->fType << 28) | (usedOffset >> 2);
221 usedOffset += current->fSize + calcPadding(current->fSize);
222 }
223
224 i++;
225 current = current->fNext;
226 }
227
228 udata_write16(mem, res->u.fTable.fCount);
229
230 udata_writeBlock(mem, keys, sizeof(uint16_t) * res->u.fTable.fCount);
231 udata_writePadding(mem, pad);
232 udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fTable.fCount);
233
234 uprv_free(keys);
235 uprv_free(resources);
236 } else {
237 /* table is empty */
238 udata_write16(mem, 0);
239 udata_writePadding(mem, pad);
240 }
241
242 return usedOffset;
243}
244
245uint32_t res_write(UNewDataMemory *mem, struct SResource *res,
246 uint32_t usedOffset, UErrorCode *status) {
247 if (U_FAILURE(*status)) {
248 return 0;
249 }
250
251 if (res != NULL) {
252 switch (res->fType) {
253 case URES_STRING:
254 return string_write (mem, res, usedOffset, status);
255 case URES_ALIAS:
256 return alias_write (mem, res, usedOffset, status);
257 case URES_INT_VECTOR:
258 return intvector_write (mem, res, usedOffset, status);
259 case URES_BINARY:
260 return bin_write (mem, res, usedOffset, status);
261 case URES_INT:
262 return int_write (mem, res, usedOffset, status);
263 case URES_ARRAY:
264 return array_write (mem, res, usedOffset, status);
265 case URES_TABLE:
266 return table_write (mem, res, usedOffset, status);
267
268 default:
269 break;
270 }
271 }
272
273 *status = U_INTERNAL_PROGRAM_ERROR;
274 return 0;
275}
276
277void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status) {
278 UNewDataMemory *mem = NULL;
279 uint8_t pad = 0;
280 uint32_t root = 0;
281 uint32_t usedOffset = 0;
282 char dataName[1024];
283
284 if (writtenFilename && writtenFilenameLen) {
285 *writtenFilename = 0;
286 }
287
288 if (U_FAILURE(*status)) {
289 return;
290 }
291
292 if (writtenFilename) {
293 int32_t off = 0, len = 0;
294 if (outputDir) {
295 len = (int32_t)uprv_strlen(outputDir);
296 if (len > writtenFilenameLen) {
297 len = writtenFilenameLen;
298 }
299 uprv_strncpy(writtenFilename, outputDir, len);
300 }
301 if (writtenFilenameLen -= len) {
302 off += len;
303 writtenFilename[off] = U_FILE_SEP_CHAR;
304 if (--writtenFilenameLen) {
305 ++off;
306 if(outputPkg != NULL)
307 {
308 uprv_strcpy(writtenFilename+off, outputPkg);
309 off += uprv_strlen(outputPkg);
310 writtenFilename[off] = '_';
311 ++off;
312 }
313
314 len = (int32_t)uprv_strlen(bundle->fLocale);
315 if (len > writtenFilenameLen) {
316 len = writtenFilenameLen;
317 }
318 uprv_strncpy(writtenFilename + off, bundle->fLocale, len);
319 if (writtenFilenameLen -= len) {
320 off += len;
321 len = 5;
322 if (len > writtenFilenameLen) {
323 len = writtenFilenameLen;
324 }
325 uprv_strncpy(writtenFilename + off, ".res", len);
326 }
327 }
328 }
329 }
330
331 if(outputPkg)
332 {
333 uprv_strcpy(dataName, outputPkg);
334 uprv_strcat(dataName, "_");
335 uprv_strcat(dataName, bundle->fLocale);
336 }
337 else
338 {
339 uprv_strcpy(dataName, bundle->fLocale);
340 }
341
342 mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status);
343 if(U_FAILURE(*status)){
344 return;
345 }
346 pad = calcPadding(bundle->fKeyPoint);
347
348 usedOffset = sizeof(uint32_t) + bundle->fKeyPoint + pad ; /*this is how much root and keys are taking up*/
349
350 root = ((usedOffset + bundle->fRoot->u.fTable.fChildrenSize) >> 2) | (URES_TABLE << 28); /* we're gonna put the main table at the end */
351
352 udata_write32(mem, root);
353
354 udata_writeBlock(mem, bundle->fKeys, bundle->fKeyPoint);
355
356 udata_writePadding(mem, pad);
357
358 usedOffset = res_write(mem, bundle->fRoot, usedOffset, status);
359
360 udata_finish(mem, status);
361}
362
363/* Opening Functions */
364struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {
365 struct SResource *res;
366
367 if (U_FAILURE(*status)) {
368 return NULL;
369 }
370
371 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
372
373 if (res == NULL) {
374 *status = U_MEMORY_ALLOCATION_ERROR;
375 return NULL;
376 }
377
378 res->fType = URES_TABLE;
379 res->fKey = bundle_addtag(bundle, tag, status);
380
381 if (U_FAILURE(*status)) {
382 uprv_free(res);
383 return NULL;
384 }
385
386 res->fNext = NULL;
387 res->fSize = sizeof(uint16_t);
388
389 res->u.fTable.fCount = 0;
390 res->u.fTable.fChildrenSize = 0;
391 res->u.fTable.fFirst = NULL;
392 res->u.fTable.fRoot = bundle;
393
394 return res;
395}
396
397struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {
398 struct SResource *res;
399
400 if (U_FAILURE(*status)) {
401 return NULL;
402 }
403
404 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
405
406 if (res == NULL) {
407 *status = U_MEMORY_ALLOCATION_ERROR;
408 return NULL;
409 }
410
411 res->fType = URES_ARRAY;
412 res->fKey = bundle_addtag(bundle, tag, status);
413
414 if (U_FAILURE(*status)) {
415 uprv_free(res);
416 return NULL;
417 }
418
419 res->fNext = NULL;
420 res->fSize = sizeof(int32_t);
421
422 res->u.fArray.fCount = 0;
423 res->u.fArray.fChildrenSize = 0;
424 res->u.fArray.fFirst = NULL;
425 res->u.fArray.fLast = NULL;
426
427 return res;
428}
429
430struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, UErrorCode *status) {
431 struct SResource *res;
432
433 if (U_FAILURE(*status)) {
434 return NULL;
435 }
436
437 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
438
439 if (res == NULL) {
440 *status = U_MEMORY_ALLOCATION_ERROR;
441 return NULL;
442 }
443
444 res->fType = URES_STRING;
445 res->fKey = bundle_addtag(bundle, tag, status);
446
447 if (U_FAILURE(*status)) {
448 uprv_free(res);
449 return NULL;
450 }
451
452 res->fNext = NULL;
453
454 res->u.fString.fLength = len;
455 res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1));
456
457 if (res->u.fString.fChars == NULL) {
458 *status = U_MEMORY_ALLOCATION_ERROR;
459 uprv_free(res);
460 return NULL;
461 }
462
463 uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1));
464 res->fSize = sizeof(int32_t) + sizeof(UChar) * (len+1);
465
466 return res;
467}
468
469/* TODO: make alias_open and string_open use the same code */
470struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, UErrorCode *status) {
471 struct SResource *res;
472
473 if (U_FAILURE(*status)) {
474 return NULL;
475 }
476
477 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
478
479 if (res == NULL) {
480 *status = U_MEMORY_ALLOCATION_ERROR;
481 return NULL;
482 }
483
484 res->fType = URES_ALIAS;
485 res->fKey = bundle_addtag(bundle, tag, status);
486
487 if (U_FAILURE(*status)) {
488 uprv_free(res);
489 return NULL;
490 }
491
492 res->fNext = NULL;
493
494 res->u.fString.fLength = len;
495 res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1));
496
497 if (res->u.fString.fChars == NULL) {
498 *status = U_MEMORY_ALLOCATION_ERROR;
499 uprv_free(res);
500 return NULL;
501 }
502
503 uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1));
504 res->fSize = sizeof(int32_t) + sizeof(UChar) * (len + 1);
505
506 return res;
507}
508
509
510struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) {
511 struct SResource *res;
512
513 if (U_FAILURE(*status)) {
514 return NULL;
515 }
516
517 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
518
519 if (res == NULL) {
520 *status = U_MEMORY_ALLOCATION_ERROR;
521 return NULL;
522 }
523
524 res->fType = URES_INT_VECTOR;
525 res->fKey = bundle_addtag(bundle, tag, status);
526
527 if (U_FAILURE(*status)) {
528 uprv_free(res);
529 return NULL;
530 }
531
532 res->fNext = NULL;
533 res->fSize = sizeof(int32_t);
534
535 res->u.fIntVector.fCount = 0;
536 res->u.fIntVector.fArray = (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR);
537
538 if (res->u.fIntVector.fArray == NULL) {
539 *status = U_MEMORY_ALLOCATION_ERROR;
540 uprv_free(res);
541 return NULL;
542 }
543
544 return res;
545}
546
547struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, UErrorCode *status) {
548 struct SResource *res;
549
550 if (U_FAILURE(*status)) {
551 return NULL;
552 }
553
554 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
555
556 if (res == NULL) {
557 *status = U_MEMORY_ALLOCATION_ERROR;
558 return NULL;
559 }
560
561 res->fType = URES_INT;
562 res->fKey = bundle_addtag(bundle, tag, status);
563
564 if (U_FAILURE(*status)) {
565 uprv_free(res);
566 return NULL;
567 }
568
569 res->fSize = 0;
570 res->fNext = NULL;
571 res->u.fIntValue.fValue = value;
572
573 return res;
574}
575
576struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data,const char* fileName,UErrorCode *status) {
577 struct SResource *res;
578
579 if (U_FAILURE(*status)) {
580 return NULL;
581 }
582
583 res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
584
585 if (res == NULL) {
586 *status = U_MEMORY_ALLOCATION_ERROR;
587 return NULL;
588 }
589
590 res->fType = URES_BINARY;
591 res->fKey = bundle_addtag(bundle, tag, status);
592
593 if (U_FAILURE(*status)) {
594 uprv_free(res);
595 return NULL;
596 }
597
598 res->fNext = NULL;
599
600 res->u.fBinaryValue.fLength = length;
601 res->u.fBinaryValue.fFileName = NULL;
602 if(fileName!=NULL && uprv_strcmp(fileName, "") !=0){
603 res->u.fBinaryValue.fFileName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(fileName)+1));
604 uprv_strcpy(res->u.fBinaryValue.fFileName,fileName);
605 }
606 if (length > 0) {
607 res->u.fBinaryValue.fData = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length);
608
609 if (res->u.fBinaryValue.fData == NULL) {
610 *status = U_MEMORY_ALLOCATION_ERROR;
611 uprv_free(res);
612 return NULL;
613 }
614
615 uprv_memcpy(res->u.fBinaryValue.fData, data, length);
616 }
617 else {
618 res->u.fBinaryValue.fData = NULL;
619 }
620
621 res->fSize = sizeof(int32_t) + sizeof(uint8_t) * length + BIN_ALIGNMENT;
622
623 return res;
624}
625
626struct SRBRoot *bundle_open(UErrorCode *status) {
627 struct SRBRoot *bundle = NULL;
628
629 if (U_FAILURE(*status)) {
630 return NULL;
631 }
632
633 bundle = (struct SRBRoot *) uprv_malloc(sizeof(struct SRBRoot));
634
635 if (bundle == NULL) {
636 *status = U_MEMORY_ALLOCATION_ERROR;
637 return 0;
638 }
639
640 bundle->fLocale = NULL;
641 bundle->fKeyPoint = 0;
642 bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE);
643
644 if (bundle->fKeys == NULL) {
645 *status = U_MEMORY_ALLOCATION_ERROR;
646 uprv_free(bundle);
647 return NULL;
648 }
649
650 bundle->fCount = 0;
651 bundle->fRoot = table_open(bundle, NULL, status);
652
653 if (bundle->fRoot == NULL || U_FAILURE(*status)) {
654 *status = U_MEMORY_ALLOCATION_ERROR;
655
656 uprv_free(bundle->fKeys);
657 uprv_free(bundle);
658
659 return NULL;
660 }
661
662 return bundle;
663}
664
665/* Closing Functions */
666void table_close(struct SResource *table, UErrorCode *status) {
667 struct SResource *current = NULL;
668 struct SResource *prev = NULL;
669
670 current = table->u.fTable.fFirst;
671
672 while (current != NULL) {
673 prev = current;
674 current = current->fNext;
675
676 res_close(prev, status);
677 }
678
679 table->u.fTable.fFirst = NULL;
680}
681
682void array_close(struct SResource *array, UErrorCode *status) {
683 struct SResource *current = NULL;
684 struct SResource *prev = NULL;
685
686 current = array->u.fArray.fFirst;
687
688 while (current != NULL) {
689 prev = current;
690 current = current->fNext;
691
692 res_close(prev, status);
693 }
694 array->u.fArray.fFirst = NULL;
695}
696
697void string_close(struct SResource *string, UErrorCode *status) {
698 if (string->u.fString.fChars != NULL) {
699 uprv_free(string->u.fString.fChars);
700 string->u.fString.fChars =NULL;
701 }
702}
703
704void alias_close(struct SResource *alias, UErrorCode *status) {
705 if (alias->u.fString.fChars != NULL) {
706 uprv_free(alias->u.fString.fChars);
707 alias->u.fString.fChars =NULL;
708 }
709}
710
711void intvector_close(struct SResource *intvector, UErrorCode *status) {
712 if (intvector->u.fIntVector.fArray != NULL) {
713 uprv_free(intvector->u.fIntVector.fArray);
714 intvector->u.fIntVector.fArray =NULL;
715 }
716}
717
718void int_close(struct SResource *intres, UErrorCode *status) {
719 /* Intentionally left blank */
720}
721
722void bin_close(struct SResource *binres, UErrorCode *status) {
723 if (binres->u.fBinaryValue.fData != NULL) {
724 uprv_free(binres->u.fBinaryValue.fData);
725 binres->u.fBinaryValue.fData = NULL;
726 }
727}
728
729void res_close(struct SResource *res, UErrorCode *status) {
730 if (res != NULL) {
731 switch(res->fType) {
732 case URES_STRING:
733 string_close(res, status);
734 break;
735 case URES_ALIAS:
736 alias_close(res, status);
737 break;
738 case URES_INT_VECTOR:
739 intvector_close(res, status);
740 break;
741 case URES_BINARY:
742 bin_close(res, status);
743 break;
744 case URES_INT:
745 int_close(res, status);
746 break;
747 case URES_ARRAY:
748 array_close(res, status);
749 break;
750 case URES_TABLE :
751 table_close(res, status);
752 break;
753 default:
754 /* Shouldn't happen */
755 break;
756 }
757
758 uprv_free(res);
759 }
760}
761
762void bundle_close(struct SRBRoot *bundle, UErrorCode *status) {
763 struct SResource *current = NULL;
764 struct SResource *prev = NULL;
765
766 if (bundle->fRoot != NULL) {
767 current = bundle->fRoot->u.fTable.fFirst;
768
769 while (current != NULL) {
770 prev = current;
771 current = current->fNext;
772
773 res_close(prev, status);
774 }
775
776 uprv_free(bundle->fRoot);
777 }
778
779 if (bundle->fLocale != NULL) {
780 uprv_free(bundle->fLocale);
781 }
782
783 if (bundle->fKeys != NULL) {
784 uprv_free(bundle->fKeys);
785 }
786
787 uprv_free(bundle);
788}
789
790/* Adding Functions */
791void table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status) {
792 struct SResource *current = NULL;
793 struct SResource *prev = NULL;
794 struct SResTable *list;
795
796 if (U_FAILURE(*status)) {
797 return;
798 }
799
800 /* remember this linenumber to report to the user if there is a duplicate key */
801 res->line = linenumber;
802
803 /* here we need to traverse the list */
804 list = &(table->u.fTable);
805
806 ++(list->fCount);
807 table->fSize += sizeof(uint32_t) + sizeof(uint16_t);
808
809 table->u.fTable.fChildrenSize += res->fSize + calcPadding(res->fSize);
810
811 if (res->fType == URES_TABLE) {
812 table->u.fTable.fChildrenSize += res->u.fTable.fChildrenSize;
813 } else if (res->fType == URES_ARRAY) {
814 table->u.fTable.fChildrenSize += res->u.fArray.fChildrenSize;
815 }
816
817 /* is list still empty? */
818 if (list->fFirst == NULL) {
819 list->fFirst = res;
820 res->fNext = NULL;
821 return;
822 }
823
824 current = list->fFirst;
825
826 while (current != NULL) {
827 if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) < 0) {
828 prev = current;
829 current = current->fNext;
830 } else if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) > 0) {
831 /* we're either in front of list, or in middle */
832 if (prev == NULL) {
833 /* front of the list */
834 list->fFirst = res;
835 } else {
836 /* middle of the list */
837 prev->fNext = res;
838 }
839
840 res->fNext = current;
841 return;
842 } else {
843 /* Key already exists! ERROR! */
844 error(linenumber, "duplicate key '%s' in table, first appeared at line %d", list->fRoot->fKeys + current->fKey, current->line);
845 *status = U_UNSUPPORTED_ERROR;
846 return;
847 }
848 }
849
850 /* end of list */
851 prev->fNext = res;
852 res->fNext = NULL;
853}
854
855void array_add(struct SResource *array, struct SResource *res, UErrorCode *status) {
856 if (U_FAILURE(*status)) {
857 return;
858 }
859
860 if (array->u.fArray.fFirst == NULL) {
861 array->u.fArray.fFirst = res;
862 array->u.fArray.fLast = res;
863 } else {
864 array->u.fArray.fLast->fNext = res;
865 array->u.fArray.fLast = res;
866 }
867
868 (array->u.fArray.fCount)++;
869
870 array->fSize += sizeof(uint32_t);
871 array->u.fArray.fChildrenSize += res->fSize + calcPadding(res->fSize);
872
873 if (res->fType == URES_TABLE) {
874 array->u.fArray.fChildrenSize += res->u.fTable.fChildrenSize;
875 } else if (res->fType == URES_ARRAY) {
876 array->u.fArray.fChildrenSize += res->u.fArray.fChildrenSize;
877 }
878}
879
880void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) {
881 if (U_FAILURE(*status)) {
882 return;
883 }
884
885 *(intvector->u.fIntVector.fArray + intvector->u.fIntVector.fCount) = value;
886 intvector->u.fIntVector.fCount++;
887
888 intvector->fSize += sizeof(uint32_t);
889}
890
891/* Misc Functions */
892
893void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) {
894
895 if(U_FAILURE(*status)) {
896 return;
897 }
898
899 if (bundle->fLocale!=NULL) {
900 uprv_free(bundle->fLocale);
901 }
902
903 bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1));
904
905 if(bundle->fLocale == NULL) {
906 *status = U_MEMORY_ALLOCATION_ERROR;
907 return;
908 }
909
910 /*u_strcpy(bundle->fLocale, locale);*/
911 u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1);
912
913}
914
915uint16_t bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) {
916 uint16_t keypos;
917
918 if (U_FAILURE(*status)) {
919 return (uint16_t) - 1;
920 }
921
922 if (tag == NULL) {
923 return (uint16_t) - 1;
924 }
925
926 keypos = (uint16_t)bundle->fKeyPoint;
927
928 bundle->fKeyPoint += (uint16_t) (uprv_strlen(tag) + 1);
929
930 if (bundle->fKeyPoint > KEY_SPACE_SIZE) {
931 *status = U_MEMORY_ALLOCATION_ERROR;
932 return (uint16_t) - 1;
933 }
934
935 uprv_strcpy(bundle->fKeys + keypos, tag);
936
937 return keypos;
938}