X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..d5d484b0fbe924d3663b177965538d517ee412c1:/icuSources/tools/genrb/reslist.c diff --git a/icuSources/tools/genrb/reslist.c b/icuSources/tools/genrb/reslist.c index 8ecf8792..9f30ca9c 100644 --- a/icuSources/tools/genrb/reslist.c +++ b/icuSources/tools/genrb/reslist.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2000-2003, International Business Machines +* Copyright (C) 2000-2006, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -16,9 +16,11 @@ */ #include +#include #include "reslist.h" #include "unewdata.h" #include "unicode/ures.h" +#include "unicode/putil.h" #include "errmsg.h" #define BIN_ALIGNMENT 16 @@ -38,7 +40,7 @@ static const UDataInfo dataInfo= { 0, {0x52, 0x65, 0x73, 0x42}, /* dataFormat="resb" */ - {1, 0, 0, 0}, /* formatVersion */ + {1, 2, 0, 0}, /* formatVersion */ {1, 4, 0, 0} /* dataVersion take a look at version inside parsed resb*/ }; @@ -171,7 +173,8 @@ static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, uint32_t usedOffset, UErrorCode *status) { uint8_t pad = 0; uint32_t i = 0; - uint16_t *keys = NULL; + uint16_t *keys16 = NULL; + int32_t *keys32 = NULL; uint32_t *resources = NULL; struct SResource *current = NULL; @@ -183,17 +186,25 @@ static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, pad = calcPadding(res->fSize); if (res->u.fTable.fCount > 0) { - keys = (uint16_t *) uprv_malloc(sizeof(uint16_t) * res->u.fTable.fCount); - - if (keys == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return 0; + if(res->fType == URES_TABLE) { + keys16 = (uint16_t *) uprv_malloc(sizeof(uint16_t) * res->u.fTable.fCount); + if (keys16 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + } else { + keys32 = (int32_t *) uprv_malloc(sizeof(int32_t) * res->u.fTable.fCount); + if (keys32 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } } resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fTable.fCount); if (resources == NULL) { - uprv_free(keys); + uprv_free(keys16); + uprv_free(keys32); *status = U_MEMORY_ALLOCATION_ERROR; return 0; } @@ -204,8 +215,12 @@ static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, while (current != NULL) { assert(i < res->u.fTable.fCount); - /* where the key is plus root pointer */ - keys[i] = (uint16_t) (current->fKey + sizeof(uint32_t)); + /* where the key is */ + if(res->fType == URES_TABLE) { + keys16[i] = (uint16_t) current->fKey; + } else { + keys32[i] = current->fKey; + } if (current->fType == URES_INT) { resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF); @@ -225,18 +240,30 @@ static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, current = current->fNext; } - udata_write16(mem, res->u.fTable.fCount); + if(res->fType == URES_TABLE) { + udata_write16(mem, (uint16_t)res->u.fTable.fCount); + + udata_writeBlock(mem, keys16, sizeof(uint16_t) * res->u.fTable.fCount); + udata_writePadding(mem, pad); + } else { + udata_write32(mem, res->u.fTable.fCount); + + udata_writeBlock(mem, keys32, sizeof(int32_t) * res->u.fTable.fCount); + } - udata_writeBlock(mem, keys, sizeof(uint16_t) * res->u.fTable.fCount); - udata_writePadding(mem, pad); udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fTable.fCount); - uprv_free(keys); + uprv_free(keys16); + uprv_free(keys32); uprv_free(resources); } else { /* table is empty */ - udata_write16(mem, 0); - udata_writePadding(mem, pad); + if(res->fType == URES_TABLE) { + udata_write16(mem, 0); + udata_writePadding(mem, pad); + } else { + udata_write32(mem, 0); + } } return usedOffset; @@ -263,6 +290,7 @@ uint32_t res_write(UNewDataMemory *mem, struct SResource *res, case URES_ARRAY: return array_write (mem, res, usedOffset, status); case URES_TABLE: + case URES_TABLE32: return table_write (mem, res, usedOffset, status); default: @@ -279,7 +307,9 @@ void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *out uint8_t pad = 0; uint32_t root = 0; uint32_t usedOffset = 0; + uint32_t top, size; char dataName[1024]; + int32_t indexes[URES_INDEX_TOP]; if (writtenFilename && writtenFilenameLen) { *writtenFilename = 0; @@ -306,7 +336,7 @@ void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *out if(outputPkg != NULL) { uprv_strcpy(writtenFilename+off, outputPkg); - off += uprv_strlen(outputPkg); + off += (int32_t)uprv_strlen(outputPkg); writtenFilename[off] = '_'; ++off; } @@ -345,23 +375,63 @@ void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *out } pad = calcPadding(bundle->fKeyPoint); - usedOffset = sizeof(uint32_t) + bundle->fKeyPoint + pad ; /*this is how much root and keys are taking up*/ + usedOffset = bundle->fKeyPoint + pad ; /* top of the strings */ - root = ((usedOffset + bundle->fRoot->u.fTable.fChildrenSize) >> 2) | (URES_TABLE << 28); /* we're gonna put the main table at the end */ + /* we're gonna put the main table at the end */ + top = usedOffset + bundle->fRoot->u.fTable.fChildrenSize; + root = (top) >> 2 | (bundle->fRoot->fType << 28); + /* write the root item */ udata_write32(mem, root); - udata_writeBlock(mem, bundle->fKeys, bundle->fKeyPoint); - + /* add to top the size of the root item */ + top += bundle->fRoot->fSize; + top += calcPadding(top); + + /* + * formatVersion 1.1 (ICU 2.8): + * write int32_t indexes[] after root and before the strings + * to make it easier to parse resource bundles in icuswap or from Java etc. + */ + uprv_memset(indexes, 0, sizeof(indexes)); + indexes[URES_INDEX_LENGTH]= URES_INDEX_TOP; + indexes[URES_INDEX_STRINGS_TOP]= (int32_t)(usedOffset>>2); + indexes[URES_INDEX_RESOURCES_TOP]= (int32_t)(top>>2); + indexes[URES_INDEX_BUNDLE_TOP]= indexes[URES_INDEX_RESOURCES_TOP]; + indexes[URES_INDEX_MAX_TABLE_LENGTH]= bundle->fMaxTableLength; + + /* + * formatVersion 1.2 (ICU 3.6): + * write indexes[URES_INDEX_ATTRIBUTES] with URES_ATT_NO_FALLBACK set or not set + * the memset() above initialized all indexes[] to 0 + */ + if(bundle->noFallback) { + indexes[URES_INDEX_ATTRIBUTES]=URES_ATT_NO_FALLBACK; + } + + /* write the indexes[] */ + udata_writeBlock(mem, indexes, sizeof(indexes)); + + /* write the table key strings */ + udata_writeBlock(mem, bundle->fKeys+URES_STRINGS_BOTTOM, + bundle->fKeyPoint-URES_STRINGS_BOTTOM); + + /* write the padding bytes after the table key strings */ udata_writePadding(mem, pad); + /* write all of the bundle contents: the root item and its children */ usedOffset = res_write(mem, bundle->fRoot, usedOffset, status); - udata_finish(mem, status); + size = udata_finish(mem, status); + if(top != size) { + fprintf(stderr, "genrb error: wrote %u bytes but counted %u\n", + (int)size, (int)top); + *status = U_INTERNAL_PROGRAM_ERROR; + } } /* Opening Functions */ -struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) { +struct SResource* res_open(const struct UString* comment, UErrorCode* status){ struct SResource *res; if (U_FAILURE(*status)) { @@ -374,16 +444,41 @@ struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *stat *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } + uprv_memset(res, 0, sizeof(struct SResource)); + + res->fComment = NULL; + if(comment != NULL){ + res->fComment = (struct UString *) uprv_malloc(sizeof(struct UString)); + if(res->fComment == NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + ustr_init(res->fComment); + ustr_cpy(res->fComment, comment, status); + } + return res; + +} +struct SResource* table_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status) { + + struct SResource *res = res_open(comment, status); - res->fType = URES_TABLE; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } res->fNext = NULL; + + /* + * always open a table not a table32 in case it remains empty - + * try to use table32 only when necessary + */ + res->fType = URES_TABLE; res->fSize = sizeof(uint16_t); res->u.fTable.fCount = 0; @@ -394,17 +489,11 @@ struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *stat return res; } -struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) { - struct SResource *res; +struct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) { - if (U_FAILURE(*status)) { - return NULL; - } - - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); + struct SResource *res = res_open(comment, status); - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; + if (U_FAILURE(*status)) { return NULL; } @@ -412,6 +501,7 @@ struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *stat res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } @@ -427,24 +517,18 @@ struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *stat return res; } -struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, UErrorCode *status) { - struct SResource *res; +struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); if (U_FAILURE(*status)) { return NULL; } - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); - - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - res->fType = URES_STRING; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } @@ -467,24 +551,18 @@ struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *va } /* TODO: make alias_open and string_open use the same code */ -struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, UErrorCode *status) { - struct SResource *res; +struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); if (U_FAILURE(*status)) { return NULL; } - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); - - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - res->fType = URES_ALIAS; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } @@ -507,24 +585,18 @@ struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, in } -struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, UErrorCode *status) { - struct SResource *res; +struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); if (U_FAILURE(*status)) { return NULL; } - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); - - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - res->fType = URES_INT_VECTOR; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } @@ -544,24 +616,18 @@ struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, UErrorCode * return res; } -struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, UErrorCode *status) { - struct SResource *res; +struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); if (U_FAILURE(*status)) { return NULL; } - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); - - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - res->fType = URES_INT; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } @@ -573,28 +639,22 @@ struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, UEr return res; } -struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data,const char* fileName,UErrorCode *status) { - struct SResource *res; +struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); if (U_FAILURE(*status)) { return NULL; } - res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); - - if (res == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - res->fType = URES_BINARY; res->fKey = bundle_addtag(bundle, tag, status); if (U_FAILURE(*status)) { + uprv_free(res->fComment); uprv_free(res); return NULL; } - + res->fNext = NULL; res->u.fBinaryValue.fLength = length; @@ -623,7 +683,7 @@ struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t len return res; } -struct SRBRoot *bundle_open(UErrorCode *status) { +struct SRBRoot *bundle_open(const struct UString* comment, UErrorCode *status) { struct SRBRoot *bundle = NULL; if (U_FAILURE(*status)) { @@ -636,10 +696,16 @@ struct SRBRoot *bundle_open(UErrorCode *status) { *status = U_MEMORY_ALLOCATION_ERROR; return 0; } + uprv_memset(bundle, 0, sizeof(struct SRBRoot)); bundle->fLocale = NULL; - bundle->fKeyPoint = 0; + bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE); + bundle->fKeysCapacity = KEY_SPACE_SIZE; + + if(comment != NULL){ + + } if (bundle->fKeys == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; @@ -647,11 +713,17 @@ struct SRBRoot *bundle_open(UErrorCode *status) { return NULL; } + /* formatVersion 1.1: start fKeyPoint after the root item and indexes[] */ + bundle->fKeyPoint = URES_STRINGS_BOTTOM; + uprv_memset(bundle->fKeys, 0, URES_STRINGS_BOTTOM); + bundle->fCount = 0; - bundle->fRoot = table_open(bundle, NULL, status); + bundle->fRoot = table_open(bundle, NULL, comment, status); if (bundle->fRoot == NULL || U_FAILURE(*status)) { - *status = U_MEMORY_ALLOCATION_ERROR; + if (U_SUCCESS(*status)) { + *status = U_MEMORY_ALLOCATION_ERROR; + } uprv_free(bundle->fKeys); uprv_free(bundle); @@ -682,9 +754,12 @@ void table_close(struct SResource *table, UErrorCode *status) { void array_close(struct SResource *array, UErrorCode *status) { struct SResource *current = NULL; struct SResource *prev = NULL; - + + if(array==NULL){ + return; + } current = array->u.fArray.fFirst; - + while (current != NULL) { prev = current; current = current->fNext; @@ -747,7 +822,8 @@ void res_close(struct SResource *res, UErrorCode *status) { case URES_ARRAY: array_close(res, status); break; - case URES_TABLE : + case URES_TABLE: + case URES_TABLE32: table_close(res, status); break; default: @@ -803,12 +879,31 @@ void table_add(struct SResource *table, struct SResource *res, int linenumber, U /* here we need to traverse the list */ list = &(table->u.fTable); + if(table->fType == URES_TABLE && res->fKey > 0xffff) { + /* this table straddles the 64k strings boundary, update to a table32 */ + table->fType = URES_TABLE32; + + /* + * increase the size because count and each string offset + * increase from uint16_t to int32_t + */ + table->fSize += (1 + list->fCount) * 2; + } + ++(list->fCount); - table->fSize += sizeof(uint32_t) + sizeof(uint16_t); + if(list->fCount > (uint32_t)list->fRoot->fMaxTableLength) { + list->fRoot->fMaxTableLength = list->fCount; + } + + /* + * URES_TABLE: 6 bytes = 1 uint16_t key string offset + 1 uint32_t Resource + * URES_TABLE32: 8 bytes = 1 int32_t key string offset + 1 uint32_t Resource + */ + table->fSize += table->fType == URES_TABLE ? 6 : 8; table->u.fTable.fChildrenSize += res->fSize + calcPadding(res->fSize); - if (res->fType == URES_TABLE) { + if (res->fType == URES_TABLE || res->fType == URES_TABLE32) { table->u.fTable.fChildrenSize += res->u.fTable.fChildrenSize; } else if (res->fType == URES_ARRAY) { table->u.fTable.fChildrenSize += res->u.fArray.fChildrenSize; @@ -870,7 +965,7 @@ void array_add(struct SResource *array, struct SResource *res, UErrorCode *statu array->fSize += sizeof(uint32_t); array->u.fArray.fChildrenSize += res->fSize + calcPadding(res->fSize); - if (res->fType == URES_TABLE) { + if (res->fType == URES_TABLE || res->fType == URES_TABLE32) { array->u.fArray.fChildrenSize += res->u.fTable.fChildrenSize; } else if (res->fType == URES_ARRAY) { array->u.fArray.fChildrenSize += res->u.fArray.fChildrenSize; @@ -912,27 +1007,35 @@ void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) } -uint16_t bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) { - uint16_t keypos; + +int32_t +bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) { + int32_t keypos, length; if (U_FAILURE(*status)) { - return (uint16_t) - 1; + return -1; } if (tag == NULL) { - return (uint16_t) - 1; + /* do not set an error: the root table has a NULL tag */ + return -1; } - keypos = (uint16_t)bundle->fKeyPoint; + keypos = bundle->fKeyPoint; - bundle->fKeyPoint += (uint16_t) (uprv_strlen(tag) + 1); + bundle->fKeyPoint += length = (int32_t) (uprv_strlen(tag) + 1); - if (bundle->fKeyPoint > KEY_SPACE_SIZE) { - *status = U_MEMORY_ALLOCATION_ERROR; - return (uint16_t) - 1; + if (bundle->fKeyPoint >= bundle->fKeysCapacity) { + /* overflow - resize the keys buffer */ + bundle->fKeysCapacity += KEY_SPACE_SIZE; + bundle->fKeys = uprv_realloc(bundle->fKeys, bundle->fKeysCapacity); + if(bundle->fKeys == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return -1; + } } - uprv_strcpy(bundle->fKeys + keypos, tag); + uprv_memcpy(bundle->fKeys + keypos, tag, length); return keypos; }