- } else {
- /* this one is a bit trickier.
- * we start finding keys, but after we resolve one alias, the path might continue.
- * Consider:
- * aliastest:alias { "testtypes/anotheralias/Sequence" }
- * anotheralias:alias { "/ICUDATA/sh/CollationElements" }
- * aliastest resource should finally have the sequence, not collation elements.
- */
- result = mainRes;
- while(*keyPath && U_SUCCESS(*status)) {
- r = res_findResource(&(result->fResData), result->fRes, &keyPath, &temp);
- if(r == RES_BOGUS) {
- *status = U_MISSING_RESOURCE_ERROR;
- result = resB;
- break;
- }
- resB = init_resb_result(&(result->fResData), r, key, -1, result->fData, parent, noAlias+1, resB, status);
- result = resB;
+
+
+ {
+ /* got almost everything, let's try to open */
+ /* first, open the bundle with real data */
+ UResourceBundle *result = resB;
+ const char* temp = NULL;
+ UErrorCode intStatus = U_ZERO_ERROR;
+ UResourceBundle *mainRes = ures_openDirect(path, locale, &intStatus);
+ if(U_SUCCESS(intStatus)) {
+ if(keyPath == NULL) {
+ /* no key path. This means that we are going to
+ * to use the corresponding resource from
+ * another bundle
+ */
+ /* first, we are going to get a corresponding parent
+ * resource to the one we are searching.
+ */
+ char *aKey = parent->fResPath;
+ if(aKey) {
+ uprv_strcpy(chAlias, aKey); /* allocated large enough above */
+ aKey = chAlias;
+ r = res_findResource(&(mainRes->fResData), mainRes->fRes, &aKey, &temp);
+ } else {
+ r = mainRes->fRes;
+ }
+ if(key) {
+ /* we need to make keyPath from parent's fResPath and
+ * current key, if there is a key associated
+ */
+ len = (int32_t)(uprv_strlen(key) + 1);
+ if(len > capacity) {
+ capacity = len;
+ if(chAlias == stackAlias) {
+ chAlias = (char *)uprv_malloc(capacity);
+ } else {
+ chAlias = (char *)uprv_realloc(chAlias, capacity);
+ }
+ if(chAlias == NULL) {
+ ures_close(mainRes);
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return NULL;
+ }
+ }
+ uprv_memcpy(chAlias, key, len);
+ aKey = chAlias;
+ r = res_findResource(&(mainRes->fResData), r, &aKey, &temp);
+ } else if(idx != -1) {
+ /* if there is no key, but there is an index, try to get by the index */
+ /* here we have either a table or an array, so get the element */
+ UResType type = RES_GET_TYPE(r);
+ if(URES_IS_TABLE(type)) {
+ r = res_getTableItemByIndex(&(mainRes->fResData), r, idx, (const char **)&aKey);
+ } else { /* array */
+ r = res_getArrayItem(&(mainRes->fResData), r, idx);
+ }
+ }
+ if(r != RES_BOGUS) {
+ result = init_resb_result(&(mainRes->fResData), r, temp, -1, mainRes->fData, mainRes, noAlias+1, resB, status);
+ } else {
+ *status = U_MISSING_RESOURCE_ERROR;
+ result = resB;
+ }
+ } else {
+ /* this one is a bit trickier.
+ * we start finding keys, but after we resolve one alias, the path might continue.
+ * Consider:
+ * aliastest:alias { "testtypes/anotheralias/Sequence" }
+ * anotheralias:alias { "/ICUDATA/sh/CollationElements" }
+ * aliastest resource should finally have the sequence, not collation elements.
+ */
+ UResourceDataEntry *dataEntry = mainRes->fData;
+ char stackPath[URES_MAX_BUFFER_SIZE];
+ char *pathBuf = stackPath, *myPath = pathBuf;
+ if(uprv_strlen(keyPath) > URES_MAX_BUFFER_SIZE) {
+ pathBuf = (char *)uprv_malloc((uprv_strlen(keyPath)+1)*sizeof(char));
+ if(pathBuf == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return NULL;
+ }
+ }
+ uprv_strcpy(pathBuf, keyPath);
+ result = mainRes;
+ /* now we have fallback following here */
+ do {
+ r = dataEntry->fData.rootRes;
+ /* this loop handles 'found' resources over several levels */
+ while(*myPath && U_SUCCESS(*status)) {
+ r = res_findResource(&(dataEntry->fData), r, &myPath, &temp);
+ if(r != RES_BOGUS) { /* found a resource, but it might be an indirection */
+ resB = init_resb_result(&(dataEntry->fData), r, temp, -1, dataEntry, result, noAlias+1, resB, status);
+ result = resB;
+ if(result) {
+ r = result->fRes; /* switch to a new resource, possibly a new tree */
+ dataEntry = result->fData;
+ }
+ } else { /* no resource found, we don't really want to look anymore on this level */
+ break;
+ }
+ }
+ dataEntry = dataEntry->fParent;
+ uprv_strcpy(pathBuf, keyPath);
+ myPath = pathBuf;
+ } while(r == RES_BOGUS && dataEntry != NULL);
+ if(r == RES_BOGUS) {
+ *status = U_MISSING_RESOURCE_ERROR;
+ result = resB;
+ }
+ if(pathBuf != stackPath) {
+ uprv_free(pathBuf);
+ }
+ }
+ } else { /* we failed to open the resource we're aliasing to */
+ *status = intStatus;
+ }
+ if(chAlias != stackAlias) {
+ uprv_free(chAlias);
+ }
+ if(mainRes != result) {
+ ures_close(mainRes);
+ }
+ return result;