2 *******************************************************************************
4 * Copyright (C) 2000-2003, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 02/21/00 weiv Creation.
15 *******************************************************************************
21 #include "unicode/ures.h"
24 #define BIN_ALIGNMENT 16
26 static UBool gIncludeCopyright
= FALSE
;
28 uint32_t res_write(UNewDataMemory
*mem
, struct SResource
*res
,
29 uint32_t usedOffset
, UErrorCode
*status
);
31 static const UDataInfo dataInfo
= {
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*/
45 static 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);
51 void setIncludeCopyright(UBool val
){
52 gIncludeCopyright
=val
;
55 UBool
getIncludeCopyright(void){
56 return gIncludeCopyright
;
59 /* Writing Functions */
60 static 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
));
69 /* Writing Functions */
70 static 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
));
79 static uint32_t array_write(UNewDataMemory
*mem
, struct SResource
*res
,
80 uint32_t usedOffset
, UErrorCode
*status
) {
81 uint32_t *resources
= NULL
;
84 struct SResource
*current
= NULL
;
86 if (U_FAILURE(*status
)) {
90 if (res
->u
.fArray
.fCount
> 0) {
91 resources
= (uint32_t *) uprv_malloc(sizeof(uint32_t) * res
->u
.fArray
.fCount
);
93 if (resources
== NULL
) {
94 *status
= U_MEMORY_ALLOCATION_ERROR
;
98 current
= res
->u
.fArray
.fFirst
;
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
;
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
);
111 usedOffset
= res_write(mem
, current
, usedOffset
, status
);
112 resources
[i
] = (current
->fType
<< 28) | (usedOffset
>> 2);
113 usedOffset
+= current
->fSize
+ calcPadding(current
->fSize
);
117 current
= current
->fNext
;
120 /* usedOffset += res->fSize + pad; */
122 udata_write32(mem
, res
->u
.fArray
.fCount
);
123 udata_writeBlock(mem
, resources
, sizeof(uint32_t) * res
->u
.fArray
.fCount
);
124 uprv_free(resources
);
127 udata_write32(mem
, 0);
133 static uint32_t intvector_write(UNewDataMemory
*mem
, struct SResource
*res
,
134 uint32_t usedOffset
, UErrorCode
*status
) {
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
]);
144 static uint32_t bin_write(UNewDataMemory
*mem
, struct SResource
*res
,
145 uint32_t usedOffset
, UErrorCode
*status
) {
147 uint32_t extrapad
= calcPadding(res
->fSize
);
148 uint32_t dataStart
= usedOffset
+ sizeof(res
->u
.fBinaryValue
.fLength
);
150 if (dataStart
% BIN_ALIGNMENT
) {
151 pad
= (BIN_ALIGNMENT
- dataStart
% BIN_ALIGNMENT
);
152 udata_writePadding(mem
, pad
);
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
);
160 udata_writePadding(mem
, (BIN_ALIGNMENT
- pad
+ extrapad
));
165 static uint32_t int_write(UNewDataMemory
*mem
, struct SResource
*res
,
166 uint32_t usedOffset
, UErrorCode
*status
) {
170 static uint32_t table_write(UNewDataMemory
*mem
, struct SResource
*res
,
171 uint32_t usedOffset
, UErrorCode
*status
) {
174 uint16_t *keys
= NULL
;
175 uint32_t *resources
= NULL
;
177 struct SResource
*current
= NULL
;
179 if (U_FAILURE(*status
)) {
183 pad
= calcPadding(res
->fSize
);
185 if (res
->u
.fTable
.fCount
> 0) {
186 keys
= (uint16_t *) uprv_malloc(sizeof(uint16_t) * res
->u
.fTable
.fCount
);
189 *status
= U_MEMORY_ALLOCATION_ERROR
;
193 resources
= (uint32_t *) uprv_malloc(sizeof(uint32_t) * res
->u
.fTable
.fCount
);
195 if (resources
== NULL
) {
197 *status
= U_MEMORY_ALLOCATION_ERROR
;
201 current
= res
->u
.fTable
.fFirst
;
204 while (current
!= NULL
) {
205 assert(i
< res
->u
.fTable
.fCount
);
207 /* where the key is plus root pointer */
208 keys
[i
] = (uint16_t) (current
->fKey
+ sizeof(uint32_t));
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
;
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
);
219 usedOffset
= res_write(mem
, current
, usedOffset
, status
);
220 resources
[i
] = (current
->fType
<< 28) | (usedOffset
>> 2);
221 usedOffset
+= current
->fSize
+ calcPadding(current
->fSize
);
225 current
= current
->fNext
;
228 udata_write16(mem
, res
->u
.fTable
.fCount
);
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
);
235 uprv_free(resources
);
238 udata_write16(mem
, 0);
239 udata_writePadding(mem
, pad
);
245 uint32_t res_write(UNewDataMemory
*mem
, struct SResource
*res
,
246 uint32_t usedOffset
, UErrorCode
*status
) {
247 if (U_FAILURE(*status
)) {
252 switch (res
->fType
) {
254 return string_write (mem
, res
, usedOffset
, status
);
256 return alias_write (mem
, res
, usedOffset
, status
);
257 case URES_INT_VECTOR
:
258 return intvector_write (mem
, res
, usedOffset
, status
);
260 return bin_write (mem
, res
, usedOffset
, status
);
262 return int_write (mem
, res
, usedOffset
, status
);
264 return array_write (mem
, res
, usedOffset
, status
);
266 return table_write (mem
, res
, usedOffset
, status
);
273 *status
= U_INTERNAL_PROGRAM_ERROR
;
277 void bundle_write(struct SRBRoot
*bundle
, const char *outputDir
, const char *outputPkg
, char *writtenFilename
, int writtenFilenameLen
, UErrorCode
*status
) {
278 UNewDataMemory
*mem
= NULL
;
281 uint32_t usedOffset
= 0;
284 if (writtenFilename
&& writtenFilenameLen
) {
285 *writtenFilename
= 0;
288 if (U_FAILURE(*status
)) {
292 if (writtenFilename
) {
293 int32_t off
= 0, len
= 0;
295 len
= (int32_t)uprv_strlen(outputDir
);
296 if (len
> writtenFilenameLen
) {
297 len
= writtenFilenameLen
;
299 uprv_strncpy(writtenFilename
, outputDir
, len
);
301 if (writtenFilenameLen
-= len
) {
303 writtenFilename
[off
] = U_FILE_SEP_CHAR
;
304 if (--writtenFilenameLen
) {
306 if(outputPkg
!= NULL
)
308 uprv_strcpy(writtenFilename
+off
, outputPkg
);
309 off
+= uprv_strlen(outputPkg
);
310 writtenFilename
[off
] = '_';
314 len
= (int32_t)uprv_strlen(bundle
->fLocale
);
315 if (len
> writtenFilenameLen
) {
316 len
= writtenFilenameLen
;
318 uprv_strncpy(writtenFilename
+ off
, bundle
->fLocale
, len
);
319 if (writtenFilenameLen
-= len
) {
322 if (len
> writtenFilenameLen
) {
323 len
= writtenFilenameLen
;
325 uprv_strncpy(writtenFilename
+ off
, ".res", len
);
333 uprv_strcpy(dataName
, outputPkg
);
334 uprv_strcat(dataName
, "_");
335 uprv_strcat(dataName
, bundle
->fLocale
);
339 uprv_strcpy(dataName
, bundle
->fLocale
);
342 mem
= udata_create(outputDir
, "res", dataName
, &dataInfo
, (gIncludeCopyright
==TRUE
)? U_COPYRIGHT_STRING
:NULL
, status
);
343 if(U_FAILURE(*status
)){
346 pad
= calcPadding(bundle
->fKeyPoint
);
348 usedOffset
= sizeof(uint32_t) + bundle
->fKeyPoint
+ pad
; /*this is how much root and keys are taking up*/
350 root
= ((usedOffset
+ bundle
->fRoot
->u
.fTable
.fChildrenSize
) >> 2) | (URES_TABLE
<< 28); /* we're gonna put the main table at the end */
352 udata_write32(mem
, root
);
354 udata_writeBlock(mem
, bundle
->fKeys
, bundle
->fKeyPoint
);
356 udata_writePadding(mem
, pad
);
358 usedOffset
= res_write(mem
, bundle
->fRoot
, usedOffset
, status
);
360 udata_finish(mem
, status
);
363 /* Opening Functions */
364 struct SResource
* table_open(struct SRBRoot
*bundle
, char *tag
, UErrorCode
*status
) {
365 struct SResource
*res
;
367 if (U_FAILURE(*status
)) {
371 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
374 *status
= U_MEMORY_ALLOCATION_ERROR
;
378 res
->fType
= URES_TABLE
;
379 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
381 if (U_FAILURE(*status
)) {
387 res
->fSize
= sizeof(uint16_t);
389 res
->u
.fTable
.fCount
= 0;
390 res
->u
.fTable
.fChildrenSize
= 0;
391 res
->u
.fTable
.fFirst
= NULL
;
392 res
->u
.fTable
.fRoot
= bundle
;
397 struct SResource
* array_open(struct SRBRoot
*bundle
, char *tag
, UErrorCode
*status
) {
398 struct SResource
*res
;
400 if (U_FAILURE(*status
)) {
404 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
407 *status
= U_MEMORY_ALLOCATION_ERROR
;
411 res
->fType
= URES_ARRAY
;
412 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
414 if (U_FAILURE(*status
)) {
420 res
->fSize
= sizeof(int32_t);
422 res
->u
.fArray
.fCount
= 0;
423 res
->u
.fArray
.fChildrenSize
= 0;
424 res
->u
.fArray
.fFirst
= NULL
;
425 res
->u
.fArray
.fLast
= NULL
;
430 struct SResource
*string_open(struct SRBRoot
*bundle
, char *tag
, const UChar
*value
, int32_t len
, UErrorCode
*status
) {
431 struct SResource
*res
;
433 if (U_FAILURE(*status
)) {
437 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
440 *status
= U_MEMORY_ALLOCATION_ERROR
;
444 res
->fType
= URES_STRING
;
445 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
447 if (U_FAILURE(*status
)) {
454 res
->u
.fString
.fLength
= len
;
455 res
->u
.fString
.fChars
= (UChar
*) uprv_malloc(sizeof(UChar
) * (len
+ 1));
457 if (res
->u
.fString
.fChars
== NULL
) {
458 *status
= U_MEMORY_ALLOCATION_ERROR
;
463 uprv_memcpy(res
->u
.fString
.fChars
, value
, sizeof(UChar
) * (len
+ 1));
464 res
->fSize
= sizeof(int32_t) + sizeof(UChar
) * (len
+1);
469 /* TODO: make alias_open and string_open use the same code */
470 struct SResource
*alias_open(struct SRBRoot
*bundle
, char *tag
, UChar
*value
, int32_t len
, UErrorCode
*status
) {
471 struct SResource
*res
;
473 if (U_FAILURE(*status
)) {
477 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
480 *status
= U_MEMORY_ALLOCATION_ERROR
;
484 res
->fType
= URES_ALIAS
;
485 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
487 if (U_FAILURE(*status
)) {
494 res
->u
.fString
.fLength
= len
;
495 res
->u
.fString
.fChars
= (UChar
*) uprv_malloc(sizeof(UChar
) * (len
+ 1));
497 if (res
->u
.fString
.fChars
== NULL
) {
498 *status
= U_MEMORY_ALLOCATION_ERROR
;
503 uprv_memcpy(res
->u
.fString
.fChars
, value
, sizeof(UChar
) * (len
+ 1));
504 res
->fSize
= sizeof(int32_t) + sizeof(UChar
) * (len
+ 1);
510 struct SResource
* intvector_open(struct SRBRoot
*bundle
, char *tag
, UErrorCode
*status
) {
511 struct SResource
*res
;
513 if (U_FAILURE(*status
)) {
517 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
520 *status
= U_MEMORY_ALLOCATION_ERROR
;
524 res
->fType
= URES_INT_VECTOR
;
525 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
527 if (U_FAILURE(*status
)) {
533 res
->fSize
= sizeof(int32_t);
535 res
->u
.fIntVector
.fCount
= 0;
536 res
->u
.fIntVector
.fArray
= (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR
);
538 if (res
->u
.fIntVector
.fArray
== NULL
) {
539 *status
= U_MEMORY_ALLOCATION_ERROR
;
547 struct SResource
*int_open(struct SRBRoot
*bundle
, char *tag
, int32_t value
, UErrorCode
*status
) {
548 struct SResource
*res
;
550 if (U_FAILURE(*status
)) {
554 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
557 *status
= U_MEMORY_ALLOCATION_ERROR
;
561 res
->fType
= URES_INT
;
562 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
564 if (U_FAILURE(*status
)) {
571 res
->u
.fIntValue
.fValue
= value
;
576 struct SResource
*bin_open(struct SRBRoot
*bundle
, const char *tag
, uint32_t length
, uint8_t *data
,const char* fileName
,UErrorCode
*status
) {
577 struct SResource
*res
;
579 if (U_FAILURE(*status
)) {
583 res
= (struct SResource
*) uprv_malloc(sizeof(struct SResource
));
586 *status
= U_MEMORY_ALLOCATION_ERROR
;
590 res
->fType
= URES_BINARY
;
591 res
->fKey
= bundle_addtag(bundle
, tag
, status
);
593 if (U_FAILURE(*status
)) {
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
);
607 res
->u
.fBinaryValue
.fData
= (uint8_t *) uprv_malloc(sizeof(uint8_t) * length
);
609 if (res
->u
.fBinaryValue
.fData
== NULL
) {
610 *status
= U_MEMORY_ALLOCATION_ERROR
;
615 uprv_memcpy(res
->u
.fBinaryValue
.fData
, data
, length
);
618 res
->u
.fBinaryValue
.fData
= NULL
;
621 res
->fSize
= sizeof(int32_t) + sizeof(uint8_t) * length
+ BIN_ALIGNMENT
;
626 struct SRBRoot
*bundle_open(UErrorCode
*status
) {
627 struct SRBRoot
*bundle
= NULL
;
629 if (U_FAILURE(*status
)) {
633 bundle
= (struct SRBRoot
*) uprv_malloc(sizeof(struct SRBRoot
));
635 if (bundle
== NULL
) {
636 *status
= U_MEMORY_ALLOCATION_ERROR
;
640 bundle
->fLocale
= NULL
;
641 bundle
->fKeyPoint
= 0;
642 bundle
->fKeys
= (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE
);
644 if (bundle
->fKeys
== NULL
) {
645 *status
= U_MEMORY_ALLOCATION_ERROR
;
651 bundle
->fRoot
= table_open(bundle
, NULL
, status
);
653 if (bundle
->fRoot
== NULL
|| U_FAILURE(*status
)) {
654 *status
= U_MEMORY_ALLOCATION_ERROR
;
656 uprv_free(bundle
->fKeys
);
665 /* Closing Functions */
666 void table_close(struct SResource
*table
, UErrorCode
*status
) {
667 struct SResource
*current
= NULL
;
668 struct SResource
*prev
= NULL
;
670 current
= table
->u
.fTable
.fFirst
;
672 while (current
!= NULL
) {
674 current
= current
->fNext
;
676 res_close(prev
, status
);
679 table
->u
.fTable
.fFirst
= NULL
;
682 void array_close(struct SResource
*array
, UErrorCode
*status
) {
683 struct SResource
*current
= NULL
;
684 struct SResource
*prev
= NULL
;
686 current
= array
->u
.fArray
.fFirst
;
688 while (current
!= NULL
) {
690 current
= current
->fNext
;
692 res_close(prev
, status
);
694 array
->u
.fArray
.fFirst
= NULL
;
697 void 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
;
704 void 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
;
711 void 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
;
718 void int_close(struct SResource
*intres
, UErrorCode
*status
) {
719 /* Intentionally left blank */
722 void 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
;
729 void res_close(struct SResource
*res
, UErrorCode
*status
) {
733 string_close(res
, status
);
736 alias_close(res
, status
);
738 case URES_INT_VECTOR
:
739 intvector_close(res
, status
);
742 bin_close(res
, status
);
745 int_close(res
, status
);
748 array_close(res
, status
);
751 table_close(res
, status
);
754 /* Shouldn't happen */
762 void bundle_close(struct SRBRoot
*bundle
, UErrorCode
*status
) {
763 struct SResource
*current
= NULL
;
764 struct SResource
*prev
= NULL
;
766 if (bundle
->fRoot
!= NULL
) {
767 current
= bundle
->fRoot
->u
.fTable
.fFirst
;
769 while (current
!= NULL
) {
771 current
= current
->fNext
;
773 res_close(prev
, status
);
776 uprv_free(bundle
->fRoot
);
779 if (bundle
->fLocale
!= NULL
) {
780 uprv_free(bundle
->fLocale
);
783 if (bundle
->fKeys
!= NULL
) {
784 uprv_free(bundle
->fKeys
);
790 /* Adding Functions */
791 void 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
;
796 if (U_FAILURE(*status
)) {
800 /* remember this linenumber to report to the user if there is a duplicate key */
801 res
->line
= linenumber
;
803 /* here we need to traverse the list */
804 list
= &(table
->u
.fTable
);
807 table
->fSize
+= sizeof(uint32_t) + sizeof(uint16_t);
809 table
->u
.fTable
.fChildrenSize
+= res
->fSize
+ calcPadding(res
->fSize
);
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
;
817 /* is list still empty? */
818 if (list
->fFirst
== NULL
) {
824 current
= list
->fFirst
;
826 while (current
!= NULL
) {
827 if (uprv_strcmp(((list
->fRoot
->fKeys
) + (current
->fKey
)), ((list
->fRoot
->fKeys
) + (res
->fKey
))) < 0) {
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 */
833 /* front of the list */
836 /* middle of the list */
840 res
->fNext
= current
;
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
;
855 void array_add(struct SResource
*array
, struct SResource
*res
, UErrorCode
*status
) {
856 if (U_FAILURE(*status
)) {
860 if (array
->u
.fArray
.fFirst
== NULL
) {
861 array
->u
.fArray
.fFirst
= res
;
862 array
->u
.fArray
.fLast
= res
;
864 array
->u
.fArray
.fLast
->fNext
= res
;
865 array
->u
.fArray
.fLast
= res
;
868 (array
->u
.fArray
.fCount
)++;
870 array
->fSize
+= sizeof(uint32_t);
871 array
->u
.fArray
.fChildrenSize
+= res
->fSize
+ calcPadding(res
->fSize
);
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
;
880 void intvector_add(struct SResource
*intvector
, int32_t value
, UErrorCode
*status
) {
881 if (U_FAILURE(*status
)) {
885 *(intvector
->u
.fIntVector
.fArray
+ intvector
->u
.fIntVector
.fCount
) = value
;
886 intvector
->u
.fIntVector
.fCount
++;
888 intvector
->fSize
+= sizeof(uint32_t);
893 void bundle_setlocale(struct SRBRoot
*bundle
, UChar
*locale
, UErrorCode
*status
) {
895 if(U_FAILURE(*status
)) {
899 if (bundle
->fLocale
!=NULL
) {
900 uprv_free(bundle
->fLocale
);
903 bundle
->fLocale
= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale
)+1));
905 if(bundle
->fLocale
== NULL
) {
906 *status
= U_MEMORY_ALLOCATION_ERROR
;
910 /*u_strcpy(bundle->fLocale, locale);*/
911 u_UCharsToChars(locale
, bundle
->fLocale
, u_strlen(locale
)+1);
915 uint16_t bundle_addtag(struct SRBRoot
*bundle
, const char *tag
, UErrorCode
*status
) {
918 if (U_FAILURE(*status
)) {
919 return (uint16_t) - 1;
923 return (uint16_t) - 1;
926 keypos
= (uint16_t)bundle
->fKeyPoint
;
928 bundle
->fKeyPoint
+= (uint16_t) (uprv_strlen(tag
) + 1);
930 if (bundle
->fKeyPoint
> KEY_SPACE_SIZE
) {
931 *status
= U_MEMORY_ALLOCATION_ERROR
;
932 return (uint16_t) - 1;
935 uprv_strcpy(bundle
->fKeys
+ keypos
, tag
);