| OLD | NEW |
| 1 /* | 1 /* |
| 2 ****************************************************************************** | 2 ****************************************************************************** |
| 3 * Copyright (C) 1997-2014, International Business Machines Corporation and | 3 * Copyright (C) 1997-2015, International Business Machines Corporation and |
| 4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
| 5 ****************************************************************************** | 5 ****************************************************************************** |
| 6 * | 6 * |
| 7 * File URESBUND.C | 7 * File uresbund.cpp |
| 8 * | 8 * |
| 9 * Modification History: | 9 * Modification History: |
| 10 * | 10 * |
| 11 * Date Name Description | 11 * Date Name Description |
| 12 * 04/01/97 aliu Creation. | 12 * 04/01/97 aliu Creation. |
| 13 * 06/14/99 stephen Removed functions taking a filename suffix. | 13 * 06/14/99 stephen Removed functions taking a filename suffix. |
| 14 * 07/20/99 stephen Changed for UResourceBundle typedef'd to void* | 14 * 07/20/99 stephen Changed for UResourceBundle typedef'd to void* |
| 15 * 11/09/99 weiv Added ures_getLocale() | 15 * 11/09/99 weiv Added ures_getLocale() |
| 16 * March 2000 weiv Total overhaul - using data in DLLs | 16 * March 2000 weiv Total overhaul - using data in DLLs |
| 17 * 06/20/2000 helena OS/400 port changes; mostly typecast. | 17 * 06/20/2000 helena OS/400 port changes; mostly typecast. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 47 static icu::UInitOnce gCacheInitOnce; | 47 static icu::UInitOnce gCacheInitOnce; |
| 48 | 48 |
| 49 static UMutex resbMutex = U_MUTEX_INITIALIZER; | 49 static UMutex resbMutex = U_MUTEX_INITIALIZER; |
| 50 | 50 |
| 51 /* INTERNAL: hashes an entry */ | 51 /* INTERNAL: hashes an entry */ |
| 52 static int32_t U_CALLCONV hashEntry(const UHashTok parm) { | 52 static int32_t U_CALLCONV hashEntry(const UHashTok parm) { |
| 53 UResourceDataEntry *b = (UResourceDataEntry *)parm.pointer; | 53 UResourceDataEntry *b = (UResourceDataEntry *)parm.pointer; |
| 54 UHashTok namekey, pathkey; | 54 UHashTok namekey, pathkey; |
| 55 namekey.pointer = b->fName; | 55 namekey.pointer = b->fName; |
| 56 pathkey.pointer = b->fPath; | 56 pathkey.pointer = b->fPath; |
| 57 return uhash_hashChars(namekey)+37*uhash_hashChars(pathkey); | 57 return uhash_hashChars(namekey)+37u*uhash_hashChars(pathkey); |
| 58 } | 58 } |
| 59 | 59 |
| 60 /* INTERNAL: compares two entries */ | 60 /* INTERNAL: compares two entries */ |
| 61 static UBool U_CALLCONV compareEntries(const UHashTok p1, const UHashTok p2) { | 61 static UBool U_CALLCONV compareEntries(const UHashTok p1, const UHashTok p2) { |
| 62 UResourceDataEntry *b1 = (UResourceDataEntry *)p1.pointer; | 62 UResourceDataEntry *b1 = (UResourceDataEntry *)p1.pointer; |
| 63 UResourceDataEntry *b2 = (UResourceDataEntry *)p2.pointer; | 63 UResourceDataEntry *b2 = (UResourceDataEntry *)p2.pointer; |
| 64 UHashTok name1, name2, path1, path2; | 64 UHashTok name1, name2, path1, path2; |
| 65 name1.pointer = b1->fName; | 65 name1.pointer = b1->fName; |
| 66 name2.pointer = b2->fName; | 66 name2.pointer = b2->fName; |
| 67 path1.pointer = b1->fPath; | 67 path1.pointer = b1->fPath; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 */ | 180 */ |
| 181 umtx_lock(&resbMutex); | 181 umtx_lock(&resbMutex); |
| 182 if (cache == NULL) { | 182 if (cache == NULL) { |
| 183 umtx_unlock(&resbMutex); | 183 umtx_unlock(&resbMutex); |
| 184 return 0; | 184 return 0; |
| 185 } | 185 } |
| 186 | 186 |
| 187 do { | 187 do { |
| 188 deletedMore = FALSE; | 188 deletedMore = FALSE; |
| 189 /*creates an enumeration to iterate through every element in the table *
/ | 189 /*creates an enumeration to iterate through every element in the table *
/ |
| 190 pos = -1; | 190 pos = UHASH_FIRST; |
| 191 while ((e = uhash_nextElement(cache, &pos)) != NULL) | 191 while ((e = uhash_nextElement(cache, &pos)) != NULL) |
| 192 { | 192 { |
| 193 resB = (UResourceDataEntry *) e->value.pointer; | 193 resB = (UResourceDataEntry *) e->value.pointer; |
| 194 /* Deletes only if reference counter == 0 | 194 /* Deletes only if reference counter == 0 |
| 195 * Don't worry about the children of this node. | 195 * Don't worry about the children of this node. |
| 196 * Those will eventually get deleted too, if not already. | 196 * Those will eventually get deleted too, if not already. |
| 197 * Don't worry about the parents of this node. | 197 * Don't worry about the parents of this node. |
| 198 * Those will eventually get deleted too, if not already. | 198 * Those will eventually get deleted too, if not already. |
| 199 */ | 199 */ |
| 200 /* 04/05/2002 [weiv] fCountExisting should now be accurate. If it's
not zero, that means that */ | 200 /* 04/05/2002 [weiv] fCountExisting should now be accurate. If it's
not zero, that means that */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 215 umtx_unlock(&resbMutex); | 215 umtx_unlock(&resbMutex); |
| 216 | 216 |
| 217 return rbDeletedNum; | 217 return rbDeletedNum; |
| 218 } | 218 } |
| 219 | 219 |
| 220 #ifdef URES_DEBUG | 220 #ifdef URES_DEBUG |
| 221 #include <stdio.h> | 221 #include <stdio.h> |
| 222 | 222 |
| 223 U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) { | 223 U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) { |
| 224 UBool cacheNotEmpty = FALSE; | 224 UBool cacheNotEmpty = FALSE; |
| 225 int32_t pos = -1; | 225 int32_t pos = UHASH_FIRST; |
| 226 const UHashElement *e; | 226 const UHashElement *e; |
| 227 UResourceDataEntry *resB; | 227 UResourceDataEntry *resB; |
| 228 | 228 |
| 229 umtx_lock(&resbMutex); | 229 umtx_lock(&resbMutex); |
| 230 if (cache == NULL) { | 230 if (cache == NULL) { |
| 231 umtx_unlock(&resbMutex); | 231 umtx_unlock(&resbMutex); |
| 232 fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__); | 232 fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__); |
| 233 return FALSE; | 233 return FALSE; |
| 234 } | 234 } |
| 235 | 235 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 *status = U_USING_FALLBACK_WARNING; | 370 *status = U_USING_FALLBACK_WARNING; |
| 371 r->fBogus = U_USING_FALLBACK_WARNING; | 371 r->fBogus = U_USING_FALLBACK_WARNING; |
| 372 } else { /* if we have a regular entry */ | 372 } else { /* if we have a regular entry */ |
| 373 Resource aliasres; | 373 Resource aliasres; |
| 374 if (r->fData.usesPoolBundle) { | 374 if (r->fData.usesPoolBundle) { |
| 375 r->fPool = getPoolEntry(r->fPath, status); | 375 r->fPool = getPoolEntry(r->fPath, status); |
| 376 if (U_SUCCESS(*status)) { | 376 if (U_SUCCESS(*status)) { |
| 377 const int32_t *poolIndexes = r->fPool->fData.pRoot + 1; | 377 const int32_t *poolIndexes = r->fPool->fData.pRoot + 1; |
| 378 if(r->fData.pRoot[1 + URES_INDEX_POOL_CHECKSUM] == poolIndex
es[URES_INDEX_POOL_CHECKSUM]) { | 378 if(r->fData.pRoot[1 + URES_INDEX_POOL_CHECKSUM] == poolIndex
es[URES_INDEX_POOL_CHECKSUM]) { |
| 379 r->fData.poolBundleKeys = (const char *)(poolIndexes + (
poolIndexes[URES_INDEX_LENGTH] & 0xff)); | 379 r->fData.poolBundleKeys = (const char *)(poolIndexes + (
poolIndexes[URES_INDEX_LENGTH] & 0xff)); |
| 380 r->fData.poolBundleStrings = r->fPool->fData.p16BitUnits
; |
| 380 } else { | 381 } else { |
| 381 r->fBogus = *status = U_INVALID_FORMAT_ERROR; | 382 r->fBogus = *status = U_INVALID_FORMAT_ERROR; |
| 382 } | 383 } |
| 383 } else { | 384 } else { |
| 384 r->fBogus = *status; | 385 r->fBogus = *status; |
| 385 } | 386 } |
| 386 } | 387 } |
| 387 if (U_SUCCESS(*status)) { | 388 if (U_SUCCESS(*status)) { |
| 388 /* handle the alias by trying to get out the %%Alias tag.*/ | 389 /* handle the alias by trying to get out the %%Alias tag.*/ |
| 389 /* We'll try to get alias string from the bundle */ | 390 /* We'll try to get alias string from the bundle */ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 if( U_SUCCESS(*status) && | 440 if( U_SUCCESS(*status) && |
| 440 (poolBundle == NULL || poolBundle->fBogus != U_ZERO_ERROR || !poolBundle
->fData.isPoolBundle) | 441 (poolBundle == NULL || poolBundle->fBogus != U_ZERO_ERROR || !poolBundle
->fData.isPoolBundle) |
| 441 ) { | 442 ) { |
| 442 *status = U_INVALID_FORMAT_ERROR; | 443 *status = U_INVALID_FORMAT_ERROR; |
| 443 } | 444 } |
| 444 return poolBundle; | 445 return poolBundle; |
| 445 } | 446 } |
| 446 | 447 |
| 447 /* INTERNAL: */ | 448 /* INTERNAL: */ |
| 448 /* CAUTION: resbMutex must be locked when calling this function! */ | 449 /* CAUTION: resbMutex must be locked when calling this function! */ |
| 449 static UResourceDataEntry *findFirstExisting(const char* path, char* name, UBool
*isRoot, UBool *hasChopped, UBool *isDefault, UErrorCode* status) { | 450 static UResourceDataEntry * |
| 451 findFirstExisting(const char* path, char* name, |
| 452 UBool *isRoot, UBool *hasChopped, UBool *isDefault, UErrorCode
* status) { |
| 450 UResourceDataEntry *r = NULL; | 453 UResourceDataEntry *r = NULL; |
| 451 UBool hasRealData = FALSE; | 454 UBool hasRealData = FALSE; |
| 452 const char *defaultLoc = uloc_getDefault(); | 455 const char *defaultLoc = uloc_getDefault(); |
| 453 *hasChopped = TRUE; /* we're starting with a fresh name */ | 456 *hasChopped = TRUE; /* we're starting with a fresh name */ |
| 454 | 457 |
| 455 while(*hasChopped && !hasRealData) { | 458 while(*hasChopped && !hasRealData) { |
| 456 r = init_entry(name, path, status); | 459 r = init_entry(name, path, status); |
| 457 /* Null pointer test */ | 460 /* Null pointer test */ |
| 458 if (U_FAILURE(*status)) { | 461 if (U_FAILURE(*status)) { |
| 459 return NULL; | 462 return NULL; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 static UBool ures_isStackObject(const UResourceBundle* resB) { | 498 static UBool ures_isStackObject(const UResourceBundle* resB) { |
| 496 return((resB->fMagic1 == MAGIC1 && resB->fMagic2 == MAGIC2)?FALSE:TRUE); | 499 return((resB->fMagic1 == MAGIC1 && resB->fMagic2 == MAGIC2)?FALSE:TRUE); |
| 497 } | 500 } |
| 498 | 501 |
| 499 | 502 |
| 500 U_CFUNC void ures_initStackObject(UResourceBundle* resB) { | 503 U_CFUNC void ures_initStackObject(UResourceBundle* resB) { |
| 501 uprv_memset(resB, 0, sizeof(UResourceBundle)); | 504 uprv_memset(resB, 0, sizeof(UResourceBundle)); |
| 502 ures_setIsStackObject(resB, TRUE); | 505 ures_setIsStackObject(resB, TRUE); |
| 503 } | 506 } |
| 504 | 507 |
| 505 static UResourceDataEntry *entryOpen(const char* path, const char* localeID, UEr
rorCode* status) { | 508 static UBool // returns U_SUCCESS(*status) |
| 509 loadParentsExceptRoot(UResourceDataEntry *&t1, |
| 510 char name[], int32_t nameCapacity, |
| 511 UBool usingUSRData, char usrDataPath[], UErrorCode *status
) { |
| 512 if (U_FAILURE(*status)) { return FALSE; } |
| 513 UBool hasChopped = TRUE; |
| 514 while (hasChopped && t1->fParent == NULL && !t1->fData.noFallback && |
| 515 res_getResource(&t1->fData,"%%ParentIsRoot") == RES_BOGUS) { |
| 516 Resource parentRes = res_getResource(&t1->fData, "%%Parent"); |
| 517 if (parentRes != RES_BOGUS) { // An explicit parent was found. |
| 518 int32_t parentLocaleLen = 0; |
| 519 const UChar *parentLocaleName = res_getString(&(t1->fData), parentRe
s, &parentLocaleLen); |
| 520 if(parentLocaleName != NULL && 0 < parentLocaleLen && parentLocaleLe
n < nameCapacity) { |
| 521 u_UCharsToChars(parentLocaleName, name, parentLocaleLen + 1); |
| 522 if (uprv_strcmp(name, kRootLocaleName) == 0) { |
| 523 return TRUE; |
| 524 } |
| 525 } |
| 526 } |
| 527 // Insert regular parents. |
| 528 UErrorCode parentStatus = U_ZERO_ERROR; |
| 529 UResourceDataEntry *t2 = init_entry(name, t1->fPath, &parentStatus); |
| 530 if (U_FAILURE(parentStatus)) { |
| 531 *status = parentStatus; |
| 532 return FALSE; |
| 533 } |
| 534 UResourceDataEntry *u2 = NULL; |
| 535 UErrorCode usrStatus = U_ZERO_ERROR; |
| 536 if (usingUSRData) { // This code inserts user override data into the in
heritance chain. |
| 537 u2 = init_entry(name, usrDataPath, &usrStatus); |
| 538 } |
| 539 |
| 540 if (usingUSRData && U_SUCCESS(usrStatus) && u2->fBogus == U_ZERO_ERROR)
{ |
| 541 t1->fParent = u2; |
| 542 u2->fParent = t2; |
| 543 } else { |
| 544 t1->fParent = t2; |
| 545 if (usingUSRData) { |
| 546 // The USR override data wasn't found, set it to be deleted. |
| 547 u2->fCountExisting = 0; |
| 548 } |
| 549 } |
| 550 t1 = t2; |
| 551 hasChopped = chopLocale(name); |
| 552 } |
| 553 return TRUE; |
| 554 } |
| 555 |
| 556 static UBool // returns U_SUCCESS(*status) |
| 557 insertRootBundle(UResourceDataEntry *&t1, UErrorCode *status) { |
| 558 if (U_FAILURE(*status)) { return FALSE; } |
| 559 UErrorCode parentStatus = U_ZERO_ERROR; |
| 560 UResourceDataEntry *t2 = init_entry(kRootLocaleName, t1->fPath, &parentStatu
s); |
| 561 if (U_FAILURE(parentStatus)) { |
| 562 *status = parentStatus; |
| 563 return FALSE; |
| 564 } |
| 565 t1->fParent = t2; |
| 566 t1 = t2; |
| 567 return TRUE; |
| 568 } |
| 569 |
| 570 enum UResOpenType { |
| 571 /** |
| 572 * Open a resource bundle for the locale; |
| 573 * if there is not even a base language bundle, then fall back to the defaul
t locale; |
| 574 * if there is no bundle for that either, then load the root bundle. |
| 575 * |
| 576 * This is the default bundle loading behavior. |
| 577 */ |
| 578 URES_OPEN_LOCALE_DEFAULT_ROOT, |
| 579 // TODO: ICU ticket #11271 "consistent default locale across locale trees" |
| 580 // Add an option to look at the main locale tree for whether to |
| 581 // fall back to root directly (if the locale has main data) or |
| 582 // fall back to the default locale first (if the locale does not even have m
ain data). |
| 583 /** |
| 584 * Open a resource bundle for the locale; |
| 585 * if there is not even a base language bundle, then load the root bundle; |
| 586 * never fall back to the default locale. |
| 587 * |
| 588 * This is used for algorithms that have good pan-Unicode default behavior, |
| 589 * such as case mappings, collation, and segmentation (BreakIterator). |
| 590 */ |
| 591 URES_OPEN_LOCALE_ROOT, |
| 592 /** |
| 593 * Open a resource bundle for the exact bundle name as requested; |
| 594 * no fallbacks, do not load parent bundles. |
| 595 * |
| 596 * This is used for supplemental (non-locale) data. |
| 597 */ |
| 598 URES_OPEN_DIRECT |
| 599 }; |
| 600 typedef enum UResOpenType UResOpenType; |
| 601 |
| 602 static UResourceDataEntry *entryOpen(const char* path, const char* localeID, |
| 603 UResOpenType openType, UErrorCode* status)
{ |
| 604 U_ASSERT(openType != URES_OPEN_DIRECT); |
| 506 UErrorCode intStatus = U_ZERO_ERROR; | 605 UErrorCode intStatus = U_ZERO_ERROR; |
| 507 UErrorCode parentStatus = U_ZERO_ERROR; | |
| 508 UErrorCode usrStatus = U_ZERO_ERROR; | |
| 509 UResourceDataEntry *r = NULL; | 606 UResourceDataEntry *r = NULL; |
| 510 UResourceDataEntry *t1 = NULL; | 607 UResourceDataEntry *t1 = NULL; |
| 511 UResourceDataEntry *t2 = NULL; | |
| 512 UResourceDataEntry *u1 = NULL; | |
| 513 UResourceDataEntry *u2 = NULL; | |
| 514 UBool isDefault = FALSE; | 608 UBool isDefault = FALSE; |
| 515 UBool isRoot = FALSE; | 609 UBool isRoot = FALSE; |
| 516 UBool hasRealData = FALSE; | 610 UBool hasRealData = FALSE; |
| 517 UBool hasChopped = TRUE; | 611 UBool hasChopped = TRUE; |
| 518 UBool usingUSRData = U_USE_USRDATA && ( path == NULL || uprv_strncmp(path,U_
ICUDATA_NAME,8) == 0); | 612 UBool usingUSRData = U_USE_USRDATA && ( path == NULL || uprv_strncmp(path,U_
ICUDATA_NAME,8) == 0); |
| 519 | 613 |
| 520 char name[ULOC_FULLNAME_CAPACITY]; | 614 char name[ULOC_FULLNAME_CAPACITY]; |
| 521 char usrDataPath[96]; | 615 char usrDataPath[96]; |
| 522 | 616 |
| 523 initCache(status); | 617 initCache(status); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 543 | 637 |
| 544 umtx_lock(&resbMutex); | 638 umtx_lock(&resbMutex); |
| 545 { /* umtx_lock */ | 639 { /* umtx_lock */ |
| 546 /* We're going to skip all the locales that do not have any data */ | 640 /* We're going to skip all the locales that do not have any data */ |
| 547 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &int
Status); | 641 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &int
Status); |
| 548 | 642 |
| 549 if(r != NULL) { /* if there is one real locale, we can look for parents.
*/ | 643 if(r != NULL) { /* if there is one real locale, we can look for parents.
*/ |
| 550 t1 = r; | 644 t1 = r; |
| 551 hasRealData = TRUE; | 645 hasRealData = TRUE; |
| 552 if ( usingUSRData ) { /* This code inserts user override data into
the inheritance chain */ | 646 if ( usingUSRData ) { /* This code inserts user override data into
the inheritance chain */ |
| 553 u1 = init_entry(t1->fName, usrDataPath, &usrStatus); | 647 UErrorCode usrStatus = U_ZERO_ERROR; |
| 648 UResourceDataEntry *u1 = init_entry(t1->fName, usrDataPath, &usr
Status); |
| 554 if ( u1 != NULL ) { | 649 if ( u1 != NULL ) { |
| 555 if(u1->fBogus == U_ZERO_ERROR) { | 650 if(u1->fBogus == U_ZERO_ERROR) { |
| 556 u1->fParent = t1; | 651 u1->fParent = t1; |
| 557 r = u1; | 652 r = u1; |
| 558 } else { | 653 } else { |
| 559 /* the USR override data wasn't found, set it to be deleted *
/ | 654 /* the USR override data wasn't found, set it to be deleted *
/ |
| 560 u1->fCountExisting = 0; | 655 u1->fCountExisting = 0; |
| 561 } | 656 } |
| 562 } | 657 } |
| 563 } | 658 } |
| 564 while (hasChopped && !isRoot && t1->fParent == NULL && !t1->fData.no
Fallback) { | 659 if (hasChopped && !isRoot) { |
| 565 if ( res_getResource(&t1->fData,"%%Parent") != RES_BOGUS) { /* A
n explicit parent was found */ | 660 if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingU
SRData, usrDataPath, status)) { |
| 566 int32_t parentLocaleLen = 0; | |
| 567 const UChar *parentLocaleName = res_getString(&(t1->fData),
res_getResource(&t1->fData,"%%Parent") , &parentLocaleLen); | |
| 568 if(parentLocaleName != NULL && parentLocaleLen > 0) { | |
| 569 u_UCharsToChars(parentLocaleName, name, parentLocaleLen+
1); | |
| 570 if ( !uprv_strcmp(name,"root") ) { /* If parent is root,
we just terminate the loop */ | |
| 571 hasChopped = FALSE; | |
| 572 continue; | |
| 573 } | |
| 574 } | |
| 575 } | |
| 576 /* insert regular parents */ | |
| 577 t2 = init_entry(name, t1->fPath, &parentStatus); | |
| 578 if ( usingUSRData ) { /* This code inserts user override data i
nto the inheritance chain */ | |
| 579 usrStatus = U_ZERO_ERROR; | |
| 580 u2 = init_entry(name, usrDataPath, &usrStatus); | |
| 581 } | |
| 582 /* Check for null pointer. */ | |
| 583 if (t2 == NULL || ( usingUSRData && u2 == NULL)) { | |
| 584 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 585 goto finishUnlock; | 661 goto finishUnlock; |
| 586 } | 662 } |
| 587 | |
| 588 if ( usingUSRData && u2->fBogus == U_ZERO_ERROR ) { | |
| 589 t1->fParent = u2; | |
| 590 u2->fParent = t2; | |
| 591 } else { | |
| 592 t1->fParent = t2; | |
| 593 if(usingUSRData) { | |
| 594 /* the USR override data wasn't found, set it to be dele
ted */ | |
| 595 u2->fCountExisting = 0; | |
| 596 } | |
| 597 } | |
| 598 t1 = t2; | |
| 599 hasChopped = chopLocale(name); | |
| 600 } | 663 } |
| 601 } | 664 } |
| 602 | 665 |
| 603 /* we could have reached this point without having any real data */ | 666 /* we could have reached this point without having any real data */ |
| 604 /* if that is the case, we need to chain in the default locale */ | 667 /* if that is the case, we need to chain in the default locale */ |
| 605 if(r==NULL && !isDefault && !isRoot /*&& t1->fParent == NULL*/) { | 668 if(r==NULL && openType == URES_OPEN_LOCALE_DEFAULT_ROOT && !isDefault &&
!isRoot) { |
| 606 /* insert default locale */ | 669 /* insert default locale */ |
| 607 uprv_strcpy(name, uloc_getDefault()); | 670 uprv_strcpy(name, uloc_getDefault()); |
| 608 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault,
&intStatus); | 671 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault,
&intStatus); |
| 609 intStatus = U_USING_DEFAULT_WARNING; | 672 intStatus = U_USING_DEFAULT_WARNING; |
| 610 if(r != NULL) { /* the default locale exists */ | 673 if(r != NULL) { /* the default locale exists */ |
| 611 t1 = r; | 674 t1 = r; |
| 612 hasRealData = TRUE; | 675 hasRealData = TRUE; |
| 613 isDefault = TRUE; | 676 isDefault = TRUE; |
| 614 while (hasChopped && t1->fParent == NULL) { | 677 // TODO: Why not if (usingUSRData) { ... } like in the non-defau
lt-locale code path? |
| 615 if ( res_getResource(&t1->fData,"%%Parent") != RES_BOGUS) {
/* An explicit parent was found */ | 678 if (hasChopped && !isRoot) { |
| 616 int32_t parentLocaleLen = 0; | 679 if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), us
ingUSRData, usrDataPath, status)) { |
| 617 const UChar *parentLocaleName = res_getString(&(t1->fDat
a), res_getResource(&t1->fData,"%%Parent") , &parentLocaleLen); | |
| 618 if(parentLocaleName != NULL && parentLocaleLen > 0) { | |
| 619 u_UCharsToChars(parentLocaleName, name, parentLocale
Len+1); | |
| 620 if ( !uprv_strcmp(name,"root") ) { /* If parent is r
oot, we just terminate the loop */ | |
| 621 hasChopped = FALSE; | |
| 622 continue; | |
| 623 } | |
| 624 } | |
| 625 } | |
| 626 /* insert chopped defaults */ | |
| 627 t2 = init_entry(name, t1->fPath, &parentStatus); | |
| 628 /* Check for null pointer. */ | |
| 629 if (t2 == NULL) { | |
| 630 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 631 goto finishUnlock; | 680 goto finishUnlock; |
| 632 } | 681 } |
| 633 | |
| 634 if ( res_getResource(&t1->fData,"%%ParentIsRoot") == RES_BOG
US) { | |
| 635 t1->fParent = t2; | |
| 636 t1 = t2; | |
| 637 } | |
| 638 hasChopped = chopLocale(name); | |
| 639 } | 682 } |
| 640 } | 683 } |
| 641 } | 684 } |
| 642 | 685 |
| 643 /* we could still have r == NULL at this point - maybe even default loca
le is not */ | 686 /* we could still have r == NULL at this point - maybe even default loca
le is not */ |
| 644 /* present */ | 687 /* present */ |
| 645 if(r == NULL) { | 688 if(r == NULL) { |
| 646 uprv_strcpy(name, kRootLocaleName); | 689 uprv_strcpy(name, kRootLocaleName); |
| 647 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault,
&intStatus); | 690 r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault,
&intStatus); |
| 648 if(r != NULL) { | 691 if(r != NULL) { |
| 649 t1 = r; | 692 t1 = r; |
| 650 intStatus = U_USING_DEFAULT_WARNING; | 693 intStatus = U_USING_DEFAULT_WARNING; |
| 651 hasRealData = TRUE; | 694 hasRealData = TRUE; |
| 652 } else { /* we don't even have the root locale */ | 695 } else { /* we don't even have the root locale */ |
| 653 *status = U_MISSING_RESOURCE_ERROR; | 696 *status = U_MISSING_RESOURCE_ERROR; |
| 654 goto finishUnlock; | 697 goto finishUnlock; |
| 655 } | 698 } |
| 656 } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 && t1-
>fParent == NULL && !r->fData.noFallback) { | 699 } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 && |
| 657 /* insert root locale */ | 700 t1->fParent == NULL && !r->fData.noFallback) { |
| 658 t2 = init_entry(kRootLocaleName, t1->fPath, &parentStatus); | 701 if (!insertRootBundle(t1, status)) { |
| 659 /* Check for null pointer. */ | |
| 660 if (t2 == NULL) { | |
| 661 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 662 goto finishUnlock; | 702 goto finishUnlock; |
| 663 } | 703 } |
| 664 if(!hasRealData) { | 704 if(!hasRealData) { |
| 665 r->fBogus = U_USING_DEFAULT_WARNING; | 705 r->fBogus = U_USING_DEFAULT_WARNING; |
| 666 } | 706 } |
| 667 hasRealData = (UBool)((t2->fBogus == U_ZERO_ERROR) || hasRealData); | |
| 668 t1->fParent = t2; | |
| 669 t1 = t2; | |
| 670 } | 707 } |
| 671 | 708 |
| 709 // TODO: Does this ever loop? |
| 672 while(r != NULL && !isRoot && t1->fParent != NULL) { | 710 while(r != NULL && !isRoot && t1->fParent != NULL) { |
| 673 t1->fParent->fCountExisting++; | 711 t1->fParent->fCountExisting++; |
| 674 t1 = t1->fParent; | 712 t1 = t1->fParent; |
| 675 hasRealData = (UBool)((t1->fBogus == U_ZERO_ERROR) || hasRealData); | |
| 676 } | 713 } |
| 677 } /* umtx_lock */ | 714 } /* umtx_lock */ |
| 678 finishUnlock: | 715 finishUnlock: |
| 679 umtx_unlock(&resbMutex); | 716 umtx_unlock(&resbMutex); |
| 680 | 717 |
| 681 if(U_SUCCESS(*status)) { | 718 if(U_SUCCESS(*status)) { |
| 682 if(U_SUCCESS(parentStatus)) { | 719 if(intStatus != U_ZERO_ERROR) { |
| 683 if(intStatus != U_ZERO_ERROR) { | 720 *status = intStatus; |
| 684 *status = intStatus; | |
| 685 } | |
| 686 return r; | |
| 687 } else { | |
| 688 *status = parentStatus; | |
| 689 return NULL; | |
| 690 } | 721 } |
| 722 return r; |
| 691 } else { | 723 } else { |
| 692 return NULL; | 724 return NULL; |
| 693 } | 725 } |
| 694 } | 726 } |
| 695 | 727 |
| 728 /** |
| 729 * Version of entryOpen() and findFirstExisting() for ures_openDirect(), |
| 730 * with no fallbacks. |
| 731 * Parent and root locale bundles are loaded if |
| 732 * the requested bundle does not have the "nofallback" flag. |
| 733 */ |
| 734 static UResourceDataEntry * |
| 735 entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) { |
| 736 initCache(status); |
| 737 if(U_FAILURE(*status)) { |
| 738 return NULL; |
| 739 } |
| 740 |
| 741 umtx_lock(&resbMutex); |
| 742 // findFirstExisting() without fallbacks. |
| 743 UResourceDataEntry *r = init_entry(localeID, path, status); |
| 744 if(U_SUCCESS(*status)) { |
| 745 if(r->fBogus != U_ZERO_ERROR) { |
| 746 r->fCountExisting--; |
| 747 r = NULL; |
| 748 } |
| 749 } else { |
| 750 r = NULL; |
| 751 } |
| 752 |
| 753 // Some code depends on the ures_openDirect() bundle to have a parent bundle
chain, |
| 754 // unless it is marked with "nofallback". |
| 755 UResourceDataEntry *t1 = r; |
| 756 if(r != NULL && uprv_strcmp(localeID, kRootLocaleName) != 0 && // not root |
| 757 r->fParent == NULL && !r->fData.noFallback && |
| 758 uprv_strlen(localeID) < ULOC_FULLNAME_CAPACITY) { |
| 759 char name[ULOC_FULLNAME_CAPACITY]; |
| 760 uprv_strcpy(name, localeID); |
| 761 if(!chopLocale(name) || uprv_strcmp(name, kRootLocaleName) == 0 || |
| 762 loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), FALSE, NULL
, status)) { |
| 763 if(uprv_strcmp(t1->fName, kRootLocaleName) != 0 && t1->fParent == NU
LL) { |
| 764 insertRootBundle(t1, status); |
| 765 } |
| 766 } |
| 767 if(U_FAILURE(*status)) { |
| 768 r = NULL; |
| 769 } |
| 770 } |
| 771 |
| 772 if(r != NULL) { |
| 773 // TODO: Does this ever loop? |
| 774 while(t1->fParent != NULL) { |
| 775 t1->fParent->fCountExisting++; |
| 776 t1 = t1->fParent; |
| 777 } |
| 778 } |
| 779 umtx_unlock(&resbMutex); |
| 780 return r; |
| 781 } |
| 696 | 782 |
| 697 /** | 783 /** |
| 698 * Functions to create and destroy resource bundles. | 784 * Functions to create and destroy resource bundles. |
| 699 * CAUTION: resbMutex must be locked when calling this function. | 785 * CAUTION: resbMutex must be locked when calling this function. |
| 700 */ | 786 */ |
| 701 /* INTERNAL: */ | 787 /* INTERNAL: */ |
| 702 static void entryCloseInt(UResourceDataEntry *resB) { | 788 static void entryCloseInt(UResourceDataEntry *resB) { |
| 703 UResourceDataEntry *p = resB; | 789 UResourceDataEntry *p = resB; |
| 704 | 790 |
| 705 while(resB != NULL) { | 791 while(resB != NULL) { |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 #ifdef URES_DEBUG | 2092 #ifdef URES_DEBUG |
| 2007 U_CFUNC const char* ures_getPath(const UResourceBundle* resB) { | 2093 U_CFUNC const char* ures_getPath(const UResourceBundle* resB) { |
| 2008 if(resB == NULL) { | 2094 if(resB == NULL) { |
| 2009 return NULL; | 2095 return NULL; |
| 2010 } | 2096 } |
| 2011 | 2097 |
| 2012 return resB->fData->fPath; | 2098 return resB->fData->fPath; |
| 2013 } | 2099 } |
| 2014 #endif | 2100 #endif |
| 2015 | 2101 |
| 2016 /* OLD API implementation */ | 2102 static UResourceBundle* |
| 2017 | 2103 ures_openWithType(UResourceBundle *r, const char* path, const char* localeID, |
| 2018 /** | 2104 UResOpenType openType, UErrorCode* status) { |
| 2019 * API: This function is used to open a resource bundle | 2105 if(U_FAILURE(*status)) { |
| 2020 * proper fallback chaining is executed while initialization. | |
| 2021 * The result is stored in cache for later fallback search. | |
| 2022 */ | |
| 2023 U_CAPI void U_EXPORT2 | |
| 2024 ures_openFillIn(UResourceBundle *r, const char* path, | |
| 2025 const char* localeID, UErrorCode* status) { | |
| 2026 if(r == NULL) { | |
| 2027 *status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 2028 } else { | |
| 2029 UResourceDataEntry *firstData; | |
| 2030 UBool isStackObject = ures_isStackObject(r); | |
| 2031 char canonLocaleID[ULOC_FULLNAME_CAPACITY]; | |
| 2032 | |
| 2033 uloc_getBaseName(localeID, canonLocaleID, sizeof(canonLocaleID), status)
; | |
| 2034 if(U_FAILURE(*status) || *status == U_STRING_NOT_TERMINATED_WARNING) { | |
| 2035 *status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 2036 return; | |
| 2037 } | |
| 2038 | |
| 2039 ures_closeBundle(r, FALSE); | |
| 2040 uprv_memset(r, 0, sizeof(UResourceBundle)); | |
| 2041 ures_setIsStackObject(r, isStackObject); | |
| 2042 r->fHasFallback = TRUE; | |
| 2043 r->fIsTopLevel = TRUE; | |
| 2044 r->fIndex = -1; | |
| 2045 r->fData = entryOpen(path, canonLocaleID, status); | |
| 2046 if(U_FAILURE(*status)) { | |
| 2047 return; | |
| 2048 } | |
| 2049 /* this is a quick fix to get regular data in bundle - until constructio
n is cleaned up */ | |
| 2050 firstData = r->fData; | |
| 2051 while(firstData->fBogus != U_ZERO_ERROR && firstData->fParent != NULL) { | |
| 2052 firstData = firstData->fParent; | |
| 2053 } | |
| 2054 uprv_memcpy(&r->fResData, &firstData->fData, sizeof(ResourceData)); | |
| 2055 r->fHasFallback=(UBool)!r->fResData.noFallback; | |
| 2056 r->fRes = r->fResData.rootRes; | |
| 2057 r->fSize = res_countArrayItems(&(r->fResData), r->fRes); | |
| 2058 r->fTopLevelData = r->fData; | |
| 2059 } | |
| 2060 } | |
| 2061 | |
| 2062 U_CAPI UResourceBundle* U_EXPORT2 | |
| 2063 ures_open(const char* path, | |
| 2064 const char* localeID, | |
| 2065 UErrorCode* status) | |
| 2066 { | |
| 2067 char canonLocaleID[ULOC_FULLNAME_CAPACITY]; | |
| 2068 UResourceDataEntry *hasData = NULL; | |
| 2069 UResourceBundle *r; | |
| 2070 | |
| 2071 if(status == NULL || U_FAILURE(*status)) { | |
| 2072 return NULL; | 2106 return NULL; |
| 2073 } | 2107 } |
| 2074 | 2108 |
| 2075 /* first "canonicalize" the locale ID */ | 2109 UResourceDataEntry *entry; |
| 2076 uloc_getBaseName(localeID, canonLocaleID, sizeof(canonLocaleID), status); | 2110 if(openType != URES_OPEN_DIRECT) { |
| 2077 if(U_FAILURE(*status) || *status == U_STRING_NOT_TERMINATED_WARNING) { | 2111 /* first "canonicalize" the locale ID */ |
| 2078 *status = U_ILLEGAL_ARGUMENT_ERROR; | 2112 char canonLocaleID[ULOC_FULLNAME_CAPACITY]; |
| 2113 uloc_getBaseName(localeID, canonLocaleID, UPRV_LENGTHOF(canonLocaleID),
status); |
| 2114 if(U_FAILURE(*status) || *status == U_STRING_NOT_TERMINATED_WARNING) { |
| 2115 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 2116 return NULL; |
| 2117 } |
| 2118 entry = entryOpen(path, canonLocaleID, openType, status); |
| 2119 } else { |
| 2120 entry = entryOpenDirect(path, localeID, status); |
| 2121 } |
| 2122 if(U_FAILURE(*status)) { |
| 2123 return NULL; |
| 2124 } |
| 2125 if(entry == NULL) { |
| 2126 *status = U_MISSING_RESOURCE_ERROR; |
| 2079 return NULL; | 2127 return NULL; |
| 2080 } | 2128 } |
| 2081 | 2129 |
| 2082 r = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle)); | 2130 UBool isStackObject; |
| 2083 if(r == NULL) { | 2131 if(r == NULL) { |
| 2084 *status = U_MEMORY_ALLOCATION_ERROR; | 2132 r = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle)); |
| 2085 return NULL; | 2133 if(r == NULL) { |
| 2086 } | 2134 entryClose(entry); |
| 2087 | 2135 *status = U_MEMORY_ALLOCATION_ERROR; |
| 2088 uprv_memset(r, 0, sizeof(UResourceBundle)); | |
| 2089 r->fHasFallback = TRUE; | |
| 2090 r->fIsTopLevel = TRUE; | |
| 2091 ures_setIsStackObject(r, FALSE); | |
| 2092 r->fIndex = -1; | |
| 2093 r->fData = entryOpen(path, canonLocaleID, status); | |
| 2094 if(U_FAILURE(*status)) { | |
| 2095 uprv_free(r); | |
| 2096 return NULL; | |
| 2097 } | |
| 2098 r->fTopLevelData = r->fData; | |
| 2099 | |
| 2100 hasData = r->fData; | |
| 2101 while(hasData->fBogus != U_ZERO_ERROR) { | |
| 2102 hasData = hasData->fParent; | |
| 2103 if(hasData == NULL) { | |
| 2104 /* This can happen only if fallback chain gets broken by an act of God
*/ | |
| 2105 /* TODO: this unlikely to happen, consider removing it */ | |
| 2106 entryClose(r->fData); | |
| 2107 uprv_free(r); | |
| 2108 *status = U_MISSING_RESOURCE_ERROR; | |
| 2109 return NULL; | 2136 return NULL; |
| 2110 } | 2137 } |
| 2138 isStackObject = FALSE; |
| 2139 } else { // fill-in |
| 2140 isStackObject = ures_isStackObject(r); |
| 2141 ures_closeBundle(r, FALSE); |
| 2111 } | 2142 } |
| 2143 uprv_memset(r, 0, sizeof(UResourceBundle)); |
| 2144 ures_setIsStackObject(r, isStackObject); |
| 2112 | 2145 |
| 2113 uprv_memcpy(&r->fResData, &hasData->fData, sizeof(ResourceData)); | 2146 r->fTopLevelData = r->fData = entry; |
| 2114 r->fHasFallback=(UBool)!r->fResData.noFallback; | 2147 uprv_memcpy(&r->fResData, &entry->fData, sizeof(ResourceData)); |
| 2148 r->fHasFallback = openType != URES_OPEN_DIRECT && !r->fResData.noFallback; |
| 2149 r->fIsTopLevel = TRUE; |
| 2115 r->fRes = r->fResData.rootRes; | 2150 r->fRes = r->fResData.rootRes; |
| 2116 r->fSize = res_countArrayItems(&(r->fResData), r->fRes); | 2151 r->fSize = res_countArrayItems(&(r->fResData), r->fRes); |
| 2117 /* | 2152 r->fIndex = -1; |
| 2118 if(r->fData->fPath != NULL) { | |
| 2119 ures_setResPath(r, r->fData->fPath); | |
| 2120 ures_appendResPath(r, RES_PATH_PACKAGE_S); | |
| 2121 ures_appendResPath(r, r->fData->fName); | |
| 2122 } else { | |
| 2123 ures_setResPath(r, r->fData->fName); | |
| 2124 } | |
| 2125 */ | |
| 2126 | |
| 2127 | 2153 |
| 2128 return r; | 2154 return r; |
| 2129 } | 2155 } |
| 2130 | 2156 |
| 2157 U_CAPI UResourceBundle* U_EXPORT2 |
| 2158 ures_open(const char* path, const char* localeID, UErrorCode* status) { |
| 2159 return ures_openWithType(NULL, path, localeID, URES_OPEN_LOCALE_DEFAULT_ROOT
, status); |
| 2160 } |
| 2161 |
| 2162 U_CAPI UResourceBundle* U_EXPORT2 |
| 2163 ures_openNoDefault(const char* path, const char* localeID, UErrorCode* status) { |
| 2164 return ures_openWithType(NULL, path, localeID, URES_OPEN_LOCALE_ROOT, status
); |
| 2165 } |
| 2166 |
| 2131 /** | 2167 /** |
| 2132 * Opens a resource bundle without "canonicalizing" the locale name. No fallbac
k will be performed | 2168 * Opens a resource bundle without "canonicalizing" the locale name. No fallbac
k will be performed |
| 2133 * or sought. However, alias substitution will happen! | 2169 * or sought. However, alias substitution will happen! |
| 2134 */ | 2170 */ |
| 2135 U_CAPI UResourceBundle* U_EXPORT2 | 2171 U_CAPI UResourceBundle* U_EXPORT2 |
| 2136 ures_openDirect(const char* path, const char* localeID, UErrorCode* status) { | 2172 ures_openDirect(const char* path, const char* localeID, UErrorCode* status) { |
| 2137 UResourceBundle *r; | 2173 return ures_openWithType(NULL, path, localeID, URES_OPEN_DIRECT, status); |
| 2138 UErrorCode subStatus = U_ZERO_ERROR; | |
| 2139 | |
| 2140 if(status == NULL || U_FAILURE(*status)) { | |
| 2141 return NULL; | |
| 2142 } | |
| 2143 | |
| 2144 r = (UResourceBundle *)uprv_malloc(sizeof(UResourceBundle)); | |
| 2145 if(r == NULL) { | |
| 2146 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 2147 return NULL; | |
| 2148 } | |
| 2149 | |
| 2150 r->fHasFallback = FALSE; | |
| 2151 r->fIsTopLevel = TRUE; | |
| 2152 ures_setIsStackObject(r, FALSE); | |
| 2153 r->fIndex = -1; | |
| 2154 r->fData = entryOpen(path, localeID, &subStatus); | |
| 2155 if(U_FAILURE(subStatus)) { | |
| 2156 *status = subStatus; | |
| 2157 uprv_free(r); | |
| 2158 return NULL; | |
| 2159 } | |
| 2160 if(subStatus != U_ZERO_ERROR /*r->fData->fBogus != U_ZERO_ERROR*/) { | |
| 2161 /* we didn't find one we were looking for - so openDirect */ | |
| 2162 /* should fail */ | |
| 2163 entryClose(r->fData); | |
| 2164 uprv_free(r); | |
| 2165 *status = U_MISSING_RESOURCE_ERROR; | |
| 2166 return NULL; | |
| 2167 } | |
| 2168 | |
| 2169 r->fKey = NULL; | |
| 2170 r->fVersion = NULL; | |
| 2171 uprv_memcpy(&r->fResData, &r->fData->fData, sizeof(ResourceData)); | |
| 2172 /* r->fHasFallback remains FALSE here in ures_openDirect() */ | |
| 2173 r->fRes = r->fResData.rootRes; | |
| 2174 /*r->fParent = RES_BOGUS;*/ | |
| 2175 r->fSize = res_countArrayItems(&(r->fResData), r->fRes); | |
| 2176 r->fResPath = NULL; | |
| 2177 r->fResPathLen = 0; | |
| 2178 /*r->fParentRes = NULL;*/ | |
| 2179 r->fTopLevelData = r->fData; | |
| 2180 | |
| 2181 return r; | |
| 2182 } | 2174 } |
| 2183 | 2175 |
| 2184 /** | 2176 /** |
| 2177 * API: This function is used to open a resource bundle |
| 2178 * proper fallback chaining is executed while initialization. |
| 2179 * The result is stored in cache for later fallback search. |
| 2180 */ |
| 2181 U_CAPI void U_EXPORT2 |
| 2182 ures_openFillIn(UResourceBundle *r, const char* path, |
| 2183 const char* localeID, UErrorCode* status) { |
| 2184 if(U_SUCCESS(*status) && r == NULL) { |
| 2185 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 2186 return; |
| 2187 } |
| 2188 ures_openWithType(r, path, localeID, URES_OPEN_LOCALE_DEFAULT_ROOT, status); |
| 2189 } |
| 2190 |
| 2191 /** |
| 2185 * API: Counts members. For arrays and tables, returns number of resources. | 2192 * API: Counts members. For arrays and tables, returns number of resources. |
| 2186 * For strings, returns 1. | 2193 * For strings, returns 1. |
| 2187 */ | 2194 */ |
| 2188 U_CAPI int32_t U_EXPORT2 | 2195 U_CAPI int32_t U_EXPORT2 |
| 2189 ures_countArrayItems(const UResourceBundle* resourceBundle, | 2196 ures_countArrayItems(const UResourceBundle* resourceBundle, |
| 2190 const char* resourceKey, | 2197 const char* resourceKey, |
| 2191 UErrorCode* status) | 2198 UErrorCode* status) |
| 2192 { | 2199 { |
| 2193 UResourceBundle resData; | 2200 UResourceBundle resData; |
| 2194 ures_initStackObject(&resData); | 2201 ures_initStackObject(&resData); |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2879 ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo v
er, UErrorCode *status) { | 2886 ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo v
er, UErrorCode *status) { |
| 2880 const UChar *str; | 2887 const UChar *str; |
| 2881 int32_t len; | 2888 int32_t len; |
| 2882 str = ures_getStringByKey(res, key, &len, status); | 2889 str = ures_getStringByKey(res, key, &len, status); |
| 2883 if(U_SUCCESS(*status)) { | 2890 if(U_SUCCESS(*status)) { |
| 2884 u_versionFromUString(ver, str); | 2891 u_versionFromUString(ver, str); |
| 2885 } | 2892 } |
| 2886 } | 2893 } |
| 2887 | 2894 |
| 2888 /* eof */ | 2895 /* eof */ |
| OLD | NEW |