/* * Enumerate one resource item and its children and extract dependencies from * aliases. */ static void ures_enumDependencies(const char *itemName, const ResourceData *pResData, Resource res, const char *inKey, const char *parentKey, int32_t depth, CheckDependency check, void *context, Package *pkg, UErrorCode *pErrorCode) { switch(res_getPublicType(res)) { case URES_STRING: { UBool useResSuffix = TRUE; // Check for %%ALIAS if(depth==1 && inKey!=NULL) { if(0!=strcmp(inKey, "%%ALIAS")) { break; } } // Check for %%DEPENDENCY else if(depth==2 && parentKey!=NULL) { if(0!=strcmp(parentKey, "%%DEPENDENCY")) { break; } useResSuffix = FALSE; } else { // we ignore all other strings break; } int32_t length; const UChar *alias=res_getString(pResData, res, &length); checkAlias(itemName, res, alias, length, useResSuffix, check, context, pErrorCode); } break; case URES_ALIAS: { int32_t length; const UChar *alias=res_getAlias(pResData, res, &length); checkAlias(itemName, res, alias, length, TRUE, check, context, pErrorCode); } break; case URES_TABLE: { /* recurse */ int32_t count=res_countArrayItems(pResData, res); for(int32_t i=0; i<count; ++i) { const char *itemKey; Resource item=res_getTableItemByIndex(pResData, res, i, &itemKey); ures_enumDependencies( itemName, pResData, item, itemKey, inKey, depth+1, check, context, pkg, pErrorCode); if(U_FAILURE(*pErrorCode)) { fprintf(stderr, "icupkg/ures_enumDependencies(%s table res=%08x)[%d].recurse(%s: %08x) failed\n", itemName, res, i, itemKey, item); break; } } } break; case URES_ARRAY: { /* recurse */ int32_t count=res_countArrayItems(pResData, res); for(int32_t i=0; i<count; ++i) { Resource item=res_getArrayItem(pResData, res, i); ures_enumDependencies( itemName, pResData, item, NULL, inKey, depth+1, check, context, pkg, pErrorCode); if(U_FAILURE(*pErrorCode)) { fprintf(stderr, "icupkg/ures_enumDependencies(%s array res=%08x)[%d].recurse(%08x) failed\n", itemName, res, i, item); break; } } } break; default: break; } }
U_CFUNC Resource res_findResource(const ResourceData *pResData, Resource r, char** path, const char** key) { /* we pass in a path. CollationElements/Sequence or zoneStrings/3/2 etc. * iterates over a path and stops when a scalar resource is found. This * CAN be an alias. Path gets set to the part that has not yet been processed. */ char *pathP = *path, *nextSepP = *path; char *closeIndex = NULL; Resource t1 = r; Resource t2; int32_t indexR = 0; UResType type = (UResType)RES_GET_TYPE(t1); /* if you come in with an empty path, you'll be getting back the same resource */ if(!uprv_strlen(pathP)) { return r; } /* one needs to have an aggregate resource in order to search in it */ if(!URES_IS_CONTAINER(type)) { return RES_BOGUS; } while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) { /* Iteration stops if: the path has been consumed, we found a non-existing * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias) */ nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR); /* if there are more separators, terminate string * and set path to the remaining part of the string */ if(nextSepP != NULL) { *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */ *path = nextSepP+1; } else { *path = uprv_strchr(pathP, 0); } /* if the resource is a table */ /* try the key based access */ if(URES_IS_TABLE(type)) { *key = pathP; t2 = res_getTableItemByKey(pResData, t1, &indexR, key); if(t2 == RES_BOGUS) { /* if we fail to get the resource by key, maybe we got an index */ indexR = uprv_strtol(pathP, &closeIndex, 10); if(closeIndex != pathP) { /* if we indeed have an index, try to get the item by index */ t2 = res_getTableItemByIndex(pResData, t1, indexR, key); } } } else if(URES_IS_ARRAY(type)) { indexR = uprv_strtol(pathP, &closeIndex, 10); if(closeIndex != pathP) { t2 = res_getArrayItem(pResData, t1, indexR); } else { t2 = RES_BOGUS; /* have an array, but don't have a valid index */ } *key = NULL; } else { /* can't do much here, except setting t2 to bogus */ t2 = RES_BOGUS; } t1 = t2; type = (UResType)RES_GET_TYPE(t1); /* position pathP to next resource key/index */ pathP = *path; } return t1; }
static void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status) { static const UChar cr[] = { 0xA }; // LF /* int32_t noOfElements = ures_getSize(resource);*/ int32_t i = 0; const char *key = ures_getKey(resource); switch(ures_getType(resource)) { case URES_STRING : { int32_t len=0; const UChar* thestr = ures_getString(resource, &len, status); UChar *string = quotedString(thestr); /* TODO: String truncation */ if(opt_truncate && len > truncsize) { char msg[128]; printIndent(out, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", (long)len, (long)(truncsize/2)); printCString(out, msg, -1); len = truncsize/2; } printIndent(out, indent); if(key != NULL) { static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */ static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */ printCString(out, key, (int32_t)uprv_strlen(key)); printString(out, openStr, UPRV_LENGTHOF(openStr)); printString(out, string, len); printString(out, closeStr, UPRV_LENGTHOF(closeStr)); } else { static const UChar openStr[] = { 0x0022 }; /* "\"" */ static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */ printString(out, openStr, UPRV_LENGTHOF(openStr)); printString(out, string, (int32_t)(u_strlen(string))); printString(out, closeStr, UPRV_LENGTHOF(closeStr)); } if(verbose) { printCString(out, "// STRING", -1); } printString(out, cr, UPRV_LENGTHOF(cr)); uprv_free(string); } break; case URES_INT : { static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */ static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */ UChar num[20]; printIndent(out, indent); if(key != NULL) { printCString(out, key, -1); } printString(out, openStr, UPRV_LENGTHOF(openStr)); uprv_itou(num, 20, ures_getInt(resource, status), 10, 0); printString(out, num, u_strlen(num)); printString(out, closeStr, UPRV_LENGTHOF(closeStr)); if(verbose) { printCString(out, "// INT", -1); } printString(out, cr, UPRV_LENGTHOF(cr)); break; } case URES_BINARY : { int32_t len = 0; const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status); if(opt_truncate && len > truncsize) { char msg[128]; printIndent(out, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", (long)len, (long)(truncsize/2)); printCString(out, msg, -1); len = truncsize; } if(U_SUCCESS(*status)) { static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ printIndent(out, indent); if(key != NULL) { printCString(out, key, -1); } printString(out, openStr, UPRV_LENGTHOF(openStr)); for(i = 0; i<len; i++) { printHex(out, *data++); } printString(out, closeStr, UPRV_LENGTHOF(closeStr)); if(verbose) { printCString(out, " // BINARY", -1); } printString(out, cr, UPRV_LENGTHOF(cr)); } else { reportError(pname, status, "getting binary value"); } } break; case URES_INT_VECTOR : { int32_t len = 0; const int32_t *data = ures_getIntVector(resource, &len, status); if(U_SUCCESS(*status)) { static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */ static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ UChar num[20]; printIndent(out, indent); if(key != NULL) { printCString(out, key, -1); } printString(out, openStr, UPRV_LENGTHOF(openStr)); for(i = 0; i < len - 1; i++) { int32_t numLen = uprv_itou(num, 20, data[i], 10, 0); num[numLen++] = 0x002C; /* ',' */ num[numLen++] = 0x0020; /* ' ' */ num[numLen] = 0; printString(out, num, u_strlen(num)); } if(len > 0) { uprv_itou(num, 20, data[len - 1], 10, 0); printString(out, num, u_strlen(num)); } printString(out, closeStr, UPRV_LENGTHOF(closeStr)); if(verbose) { printCString(out, "// INTVECTOR", -1); } printString(out, cr, UPRV_LENGTHOF(cr)); } else { reportError(pname, status, "getting int vector"); } } break; case URES_TABLE : case URES_ARRAY : { static const UChar openStr[] = { 0x007B }; /* "{" */ static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */ UResourceBundle *t = NULL; ures_resetIterator(resource); printIndent(out, indent); if(key != NULL) { printCString(out, key, -1); } printString(out, openStr, UPRV_LENGTHOF(openStr)); if(verbose) { if(ures_getType(resource) == URES_TABLE) { printCString(out, "// TABLE", -1); } else { printCString(out, "// ARRAY", -1); } } printString(out, cr, UPRV_LENGTHOF(cr)); if(suppressAliases == FALSE) { while(U_SUCCESS(*status) && ures_hasNext(resource)) { t = ures_getNextResource(resource, t, status); if(U_SUCCESS(*status)) { printOutBundle(out, t, indent+indentsize, pname, status); } else { reportError(pname, status, "While processing table"); *status = U_ZERO_ERROR; } } } else { /* we have to use low level access to do this */ Resource r; int32_t resSize = ures_getSize(resource); UBool isTable = (UBool)(ures_getType(resource) == URES_TABLE); for(i = 0; i < resSize; i++) { /* need to know if it's an alias */ if(isTable) { r = res_getTableItemByIndex(&resource->fResData, resource->fRes, i, &key); } else { r = res_getArrayItem(&resource->fResData, resource->fRes, i); } if(U_SUCCESS(*status)) { if(res_getPublicType(r) == URES_ALIAS) { printOutAlias(out, resource, r, key, indent+indentsize, pname, status); } else { t = ures_getByIndex(resource, i, t, status); printOutBundle(out, t, indent+indentsize, pname, status); } } else { reportError(pname, status, "While processing table"); *status = U_ZERO_ERROR; } } } printIndent(out, indent); printString(out, closeStr, UPRV_LENGTHOF(closeStr)); ures_close(t); } break; default: break; } }