Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: source/common/uresdata.cpp

Issue 1621943002: ICU 56 step 4: Apply post-56 fixes for measure/date format (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@56goog
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/common/uresdata.c ('k') | source/common/uresimp.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * Copyright (C) 1999-2015, International Business Machines Corporation 3 * Copyright (C) 1999-2015, International Business Machines Corporation
4 * and others. All Rights Reserved. 4 * and others. All Rights Reserved.
5 ******************************************************************************* 5 *******************************************************************************
6 * file name: uresdata.c 6 * file name: uresdata.cpp
7 * encoding: US-ASCII 7 * encoding: US-ASCII
8 * tab size: 8 (not used) 8 * tab size: 8 (not used)
9 * indentation:4 9 * indentation:4
10 * 10 *
11 * created on: 1999dec08 11 * created on: 1999dec08
12 * created by: Markus W. Scherer 12 * created by: Markus W. Scherer
13 * Modification History: 13 * Modification History:
14 * 14 *
15 * Date Name Description 15 * Date Name Description
16 * 06/20/2000 helena OS/400 port changes; mostly typecast. 16 * 06/20/2000 helena OS/400 port changes; mostly typecast.
17 * 06/24/02 weiv Added support for resource sharing 17 * 06/24/02 weiv Added support for resource sharing
18 */ 18 */
19 19
20 #include "unicode/utypes.h" 20 #include "unicode/utypes.h"
21 #include "unicode/udata.h" 21 #include "unicode/udata.h"
22 #include "unicode/ustring.h" 22 #include "unicode/ustring.h"
23 #include "unicode/utf16.h" 23 #include "unicode/utf16.h"
24 #include "cmemory.h" 24 #include "cmemory.h"
25 #include "cstring.h" 25 #include "cstring.h"
26 #include "resource.h"
26 #include "uarrsort.h" 27 #include "uarrsort.h"
28 #include "uassert.h"
29 #include "ucol_swp.h"
27 #include "udataswp.h" 30 #include "udataswp.h"
28 #include "ucol_swp.h"
29 #include "uinvchar.h" 31 #include "uinvchar.h"
30 #include "uresdata.h" 32 #include "uresdata.h"
31 #include "uresimp.h" 33 #include "uresimp.h"
32 #include "uassert.h"
33 34
34 /* 35 /*
35 * Resource access helpers 36 * Resource access helpers
36 */ 37 */
37 38
38 /* get a const char* pointer to the key with the keyOffset byte offset from pRoo t */ 39 /* get a const char* pointer to the key with the keyOffset byte offset from pRoo t */
39 #define RES_GET_KEY16(pResData, keyOffset) \ 40 #define RES_GET_KEY16(pResData, keyOffset) \
40 ((keyOffset)<(pResData)->localKeyLimit ? \ 41 ((keyOffset)<(pResData)->localKeyLimit ? \
41 (const char *)(pResData)->pRoot+(keyOffset) : \ 42 (const char *)(pResData)->pRoot+(keyOffset) : \
42 (pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit) 43 (pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return mid; 127 return mid;
127 } 128 }
128 } 129 }
129 return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 130 return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */
130 } 131 }
131 132
132 /* helper for res_load() ---------------------------------------------------- */ 133 /* helper for res_load() ---------------------------------------------------- */
133 134
134 static UBool U_CALLCONV 135 static UBool U_CALLCONV
135 isAcceptable(void *context, 136 isAcceptable(void *context,
136 const char *type, const char *name, 137 const char * /*type*/, const char * /*name*/,
137 const UDataInfo *pInfo) { 138 const UDataInfo *pInfo) {
138 uprv_memcpy(context, pInfo->formatVersion, 4); 139 uprv_memcpy(context, pInfo->formatVersion, 4);
139 return (UBool)( 140 return (UBool)(
140 pInfo->size>=20 && 141 pInfo->size>=20 &&
141 pInfo->isBigEndian==U_IS_BIG_ENDIAN && 142 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
142 pInfo->charsetFamily==U_CHARSET_FAMILY && 143 pInfo->charsetFamily==U_CHARSET_FAMILY &&
143 pInfo->sizeofUChar==U_SIZEOF_UCHAR && 144 pInfo->sizeofUChar==U_SIZEOF_UCHAR &&
144 pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 145 pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */
145 pInfo->dataFormat[1]==0x65 && 146 pInfo->dataFormat[1]==0x65 &&
146 pInfo->dataFormat[2]==0x73 && 147 pInfo->dataFormat[2]==0x73 &&
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 return (UResType)gPublicTypes[RES_GET_TYPE(res)]; 304 return (UResType)gPublicTypes[RES_GET_TYPE(res)];
304 } 305 }
305 306
306 U_CAPI const UChar * U_EXPORT2 307 U_CAPI const UChar * U_EXPORT2
307 res_getString(const ResourceData *pResData, Resource res, int32_t *pLength) { 308 res_getString(const ResourceData *pResData, Resource res, int32_t *pLength) {
308 const UChar *p; 309 const UChar *p;
309 uint32_t offset=RES_GET_OFFSET(res); 310 uint32_t offset=RES_GET_OFFSET(res);
310 int32_t length; 311 int32_t length;
311 if(RES_GET_TYPE(res)==URES_STRING_V2) { 312 if(RES_GET_TYPE(res)==URES_STRING_V2) {
312 int32_t first; 313 int32_t first;
313 if(offset<pResData->poolStringIndexLimit) { 314 if((int32_t)offset<pResData->poolStringIndexLimit) {
314 p=(const UChar *)pResData->poolBundleStrings+offset; 315 p=(const UChar *)pResData->poolBundleStrings+offset;
315 } else { 316 } else {
316 p=(const UChar *)pResData->p16BitUnits+(offset-pResData->poolStringI ndexLimit); 317 p=(const UChar *)pResData->p16BitUnits+(offset-pResData->poolStringI ndexLimit);
317 } 318 }
318 first=*p; 319 first=*p;
319 if(!U16_IS_TRAIL(first)) { 320 if(!U16_IS_TRAIL(first)) {
320 length=u_strlen(p); 321 length=u_strlen(p);
321 } else if(first<0xdfef) { 322 } else if(first<0xdfef) {
322 length=first&0x3ff; 323 length=first&0x3ff;
323 ++p; 324 ++p;
(...skipping 11 matching lines...) Expand all
335 } else { 336 } else {
336 p=NULL; 337 p=NULL;
337 length=0; 338 length=0;
338 } 339 }
339 if(pLength) { 340 if(pLength) {
340 *pLength=length; 341 *pLength=length;
341 } 342 }
342 return p; 343 return p;
343 } 344 }
344 345
346 namespace {
347
348 /**
349 * CLDR string value (three empty-set symbols)=={2205, 2205, 2205}
350 * prevents fallback to the parent bundle.
351 * TODO: combine with other code that handles this marker, use EMPTY_SET constan t.
352 * TODO: maybe move to uresbund.cpp?
353 */
354 UBool isNoInheritanceMarker(const ResourceData *pResData, Resource res) {
355 uint32_t offset=RES_GET_OFFSET(res);
356 if (offset == 0) {
357 // empty string
358 } else if (res == offset) {
359 const int32_t *p32=pResData->pRoot+res;
360 int32_t length=*p32;
361 const UChar *p=(const UChar *)p32;
362 return length == 3 && p[2] == 0x2205 && p[3] == 0x2205 && p[4] == 0x2205 ;
363 } else if (RES_GET_TYPE(res) == URES_STRING_V2) {
364 const UChar *p;
365 if((int32_t)offset<pResData->poolStringIndexLimit) {
366 p=(const UChar *)pResData->poolBundleStrings+offset;
367 } else {
368 p=(const UChar *)pResData->p16BitUnits+(offset-pResData->poolStringI ndexLimit);
369 }
370 int32_t first=*p;
371 if (first == 0x2205) { // implicit length
372 return p[1] == 0x2205 && p[2] == 0x2205 && p[3] == 0;
373 } else if (first == 0xdc03) { // explicit length 3 (should not occur)
374 return p[1] == 0x2205 && p[2] == 0x2205 && p[3] == 0x2205;
375 } else {
376 // Assume that the string has not been stored with more length units than necessary.
377 return FALSE;
378 }
379 }
380 return FALSE;
381 }
382
383 } // namespace
384
345 U_CAPI const UChar * U_EXPORT2 385 U_CAPI const UChar * U_EXPORT2
346 res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) { 386 res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) {
347 const UChar *p; 387 const UChar *p;
348 uint32_t offset=RES_GET_OFFSET(res); 388 uint32_t offset=RES_GET_OFFSET(res);
349 int32_t length; 389 int32_t length;
350 if(RES_GET_TYPE(res)==URES_ALIAS) { 390 if(RES_GET_TYPE(res)==URES_ALIAS) {
351 const int32_t *p32= offset==0 ? &gEmptyString.length : pResData->pRoot+o ffset; 391 const int32_t *p32= offset==0 ? &gEmptyString.length : pResData->pRoot+o ffset;
352 length=*p32++; 392 length=*p32++;
353 p=(const UChar *)p32; 393 p=(const UChar *)p32;
354 } else { 394 } else {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 case URES_TABLE: 456 case URES_TABLE:
417 return offset==0 ? 0 : *((const uint16_t *)(pResData->pRoot+offset)); 457 return offset==0 ? 0 : *((const uint16_t *)(pResData->pRoot+offset));
418 case URES_ARRAY16: 458 case URES_ARRAY16:
419 case URES_TABLE16: 459 case URES_TABLE16:
420 return pResData->p16BitUnits[offset]; 460 return pResData->p16BitUnits[offset];
421 default: 461 default:
422 return 0; 462 return 0;
423 } 463 }
424 } 464 }
425 465
466 namespace {
467
468 int32_t getArrayLength(const ResourceData *pResData, Resource res) {
469 uint32_t offset=RES_GET_OFFSET(res);
470 if(offset == 0) {
471 return 0;
472 }
473 int32_t type = RES_GET_TYPE(res);
474 if(type == URES_ARRAY) {
475 return *(pResData->pRoot+offset);
476 } else if(type == URES_ARRAY16) {
477 return pResData->p16BitUnits[offset];
478 } else {
479 return 0;
480 }
481 }
482
483 int32_t getTableLength(const ResourceData *pResData, Resource res) {
484 uint32_t offset=RES_GET_OFFSET(res);
485 if(offset == 0) {
486 return 0;
487 }
488 int32_t type = RES_GET_TYPE(res);
489 if(type == URES_TABLE) {
490 return *((const uint16_t *)(pResData->pRoot+offset));
491 } else if(type == URES_TABLE16) {
492 return pResData->p16BitUnits[offset];
493 } else if(type == URES_TABLE32) {
494 return *(pResData->pRoot+offset);
495 } else {
496 return 0;
497 }
498 }
499
500 } // namespace
501
502 U_NAMESPACE_BEGIN
503
504 ResourceDataValue::~ResourceDataValue() {}
505
506 UResType ResourceDataValue::getType() const {
507 return res_getPublicType(res);
508 }
509
510 const UChar *ResourceDataValue::getString(int32_t &length, UErrorCode &errorCode ) const {
511 if(U_FAILURE(errorCode)) {
512 return NULL;
513 }
514 const UChar *s = res_getString(pResData, res, &length);
515 if(s == NULL) {
516 errorCode = U_RESOURCE_TYPE_MISMATCH;
517 }
518 return s;
519 }
520
521 const UChar *ResourceDataValue::getAliasString(int32_t &length, UErrorCode &erro rCode) const {
522 if(U_FAILURE(errorCode)) {
523 return NULL;
524 }
525 const UChar *s = res_getAlias(pResData, res, &length);
526 if(s == NULL) {
527 errorCode = U_RESOURCE_TYPE_MISMATCH;
528 }
529 return s;
530 }
531
532 int32_t ResourceDataValue::getInt(UErrorCode &errorCode) const {
533 if(U_FAILURE(errorCode)) {
534 return 0;
535 }
536 if(RES_GET_TYPE(res) != URES_INT) {
537 errorCode = U_RESOURCE_TYPE_MISMATCH;
538 }
539 return RES_GET_INT(res);
540 }
541
542 uint32_t ResourceDataValue::getUInt(UErrorCode &errorCode) const {
543 if(U_FAILURE(errorCode)) {
544 return 0;
545 }
546 if(RES_GET_TYPE(res) != URES_INT) {
547 errorCode = U_RESOURCE_TYPE_MISMATCH;
548 }
549 return RES_GET_UINT(res);
550 }
551
552 const int32_t *ResourceDataValue::getIntVector(int32_t &length, UErrorCode &erro rCode) const {
553 if(U_FAILURE(errorCode)) {
554 return NULL;
555 }
556 const int32_t *iv = res_getIntVector(pResData, res, &length);
557 if(iv == NULL) {
558 errorCode = U_RESOURCE_TYPE_MISMATCH;
559 }
560 return iv;
561 }
562
563 const uint8_t *ResourceDataValue::getBinary(int32_t &length, UErrorCode &errorCo de) const {
564 if(U_FAILURE(errorCode)) {
565 return NULL;
566 }
567 const uint8_t *b = res_getBinary(pResData, res, &length);
568 if(b == NULL) {
569 errorCode = U_RESOURCE_TYPE_MISMATCH;
570 }
571 return b;
572 }
573
574 U_NAMESPACE_END
575
426 static Resource 576 static Resource
427 makeResourceFrom16(const ResourceData *pResData, int32_t res16) { 577 makeResourceFrom16(const ResourceData *pResData, int32_t res16) {
428 if(res16<pResData->poolStringIndex16Limit) { 578 if(res16<pResData->poolStringIndex16Limit) {
429 // Pool string, nothing to do. 579 // Pool string, nothing to do.
430 } else { 580 } else {
431 // Local string, adjust the 16-bit offset to a regular one, 581 // Local string, adjust the 16-bit offset to a regular one,
432 // with a larger pool string index limit. 582 // with a larger pool string index limit.
433 res16=res16-pResData->poolStringIndex16Limit+pResData->poolStringIndexLi mit; 583 res16=res16-pResData->poolStringIndex16Limit+pResData->poolStringIndexLi mit;
434 } 584 }
435 return URES_MAKE_RESOURCE(URES_STRING_V2, res16); 585 return URES_MAKE_RESOURCE(URES_STRING_V2, res16);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 return RES_BOGUS; 684 return RES_BOGUS;
535 } 685 }
536 686
537 U_CAPI Resource U_EXPORT2 687 U_CAPI Resource U_EXPORT2
538 res_getResource(const ResourceData *pResData, const char *key) { 688 res_getResource(const ResourceData *pResData, const char *key) {
539 const char *realKey=key; 689 const char *realKey=key;
540 int32_t idx; 690 int32_t idx;
541 return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey); 691 return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey);
542 } 692 }
543 693
694 // TODO: Ported from Java, but enumerating at this low level may prevent us
695 // from doing necessary things, like resolving aliases,
696 // which need access to higher-level UResourceBundle code.
697 // Consider porting the low-level Container/Array/Table classes from Java,
698 // with getters for keys and values,
699 // and doing the enumeration in the higher-level code on top of those accessors.
700 U_CFUNC void
701 ures_getAllTableItems(const ResourceData *pResData, Resource table,
702 icu::ResourceDataValue &value, icu::ResourceTableSink &sin k,
703 UErrorCode &errorCode) {
704 if(U_FAILURE(errorCode)) { return; }
705 const uint16_t *keys16 = NULL;
706 const int32_t *keys32 = NULL;
707 const uint16_t *items16 = NULL;
708 const Resource *items32 = NULL;
709 uint32_t offset = RES_GET_OFFSET(table);
710 int32_t length = 0;
711 switch(RES_GET_TYPE(table)) {
712 case URES_TABLE: {
713 if (offset != 0) { /* empty if offset==0 */
714 keys16 = (const uint16_t *)(pResData->pRoot+offset);
715 length = *keys16++;
716 items32 = (const Resource *)(keys16+length+(~length&1));
717 }
718 break;
719 }
720 case URES_TABLE16: {
721 keys16 = pResData->p16BitUnits+offset;
722 length = *keys16++;
723 items16 = keys16 + length;
724 break;
725 }
726 case URES_TABLE32: {
727 if (offset != 0) { /* empty if offset==0 */
728 keys32 = pResData->pRoot+offset;
729 length = *keys32++;
730 items32 = (const Resource *)keys32 + length;
731 }
732 break;
733 }
734 default:
735 errorCode = U_RESOURCE_TYPE_MISMATCH;
736 return;
737 }
738
739 for (int32_t i = 0; i < length; ++i) {
740 const char *key;
741 if (keys16 != NULL) {
742 key=RES_GET_KEY16(pResData, keys16[i]);
743 } else {
744 key=RES_GET_KEY32(pResData, keys32[i]);
745 }
746 Resource res;
747 if (items16 != NULL) {
748 res = makeResourceFrom16(pResData, items16[i]);
749 } else {
750 res = items32[i];
751 }
752 int32_t type = RES_GET_TYPE(res);
753 if (URES_IS_ARRAY(type)) {
754 int32_t numItems = getArrayLength(pResData, res);
755 icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(key, num Items, errorCode);
756 if (subSink != NULL) {
757 ures_getAllArrayItems(pResData, res, value, *subSink, errorCode) ;
758 }
759 } else if (URES_IS_TABLE(type)) {
760 int32_t numItems = getTableLength(pResData, res);
761 icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(key, num Items, errorCode);
762 if (subSink != NULL) {
763 ures_getAllTableItems(pResData, res, value, *subSink, errorCode) ;
764 }
765 /* TODO: settle on how to deal with aliases, port to Java
766 } else if (type == URES_ALIAS) {
767 // aliases not handled in resource enumeration
768 errorCode = U_UNSUPPORTED_ERROR;
769 return; */
770 } else if (isNoInheritanceMarker(pResData, res)) {
771 sink.putNoFallback(key, errorCode);
772 } else {
773 value.setResource(res);
774 sink.put(key, value, errorCode);
775 }
776 if(U_FAILURE(errorCode)) { return; }
777 }
778 sink.leave(errorCode);
779 }
780
544 U_CAPI Resource U_EXPORT2 781 U_CAPI Resource U_EXPORT2
545 res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) { 782 res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) {
546 uint32_t offset=RES_GET_OFFSET(array); 783 uint32_t offset=RES_GET_OFFSET(array);
547 U_ASSERT(indexR>=0); /* to ensure the index is not negative */ 784 U_ASSERT(indexR>=0); /* to ensure the index is not negative */
548 switch(RES_GET_TYPE(array)) { 785 switch(RES_GET_TYPE(array)) {
549 case URES_ARRAY: { 786 case URES_ARRAY: {
550 if (offset!=0) { /* empty if offset==0 */ 787 if (offset!=0) { /* empty if offset==0 */
551 const int32_t *p= pResData->pRoot+offset; 788 const int32_t *p= pResData->pRoot+offset;
552 if(indexR<*p) { 789 if(indexR<*p) {
553 return (Resource)p[1+indexR]; 790 return (Resource)p[1+indexR];
554 } 791 }
555 } 792 }
556 break; 793 break;
557 } 794 }
558 case URES_ARRAY16: { 795 case URES_ARRAY16: {
559 const uint16_t *p=pResData->p16BitUnits+offset; 796 const uint16_t *p=pResData->p16BitUnits+offset;
560 if(indexR<*p) { 797 if(indexR<*p) {
561 return makeResourceFrom16(pResData, p[1+indexR]); 798 return makeResourceFrom16(pResData, p[1+indexR]);
562 } 799 }
563 break; 800 break;
564 } 801 }
565 default: 802 default:
566 break; 803 break;
567 } 804 }
568 return RES_BOGUS; 805 return RES_BOGUS;
569 } 806 }
570 807
808 U_CFUNC void
809 ures_getAllArrayItems(const ResourceData *pResData, Resource array,
810 icu::ResourceDataValue &value, icu::ResourceArraySink &sin k,
811 UErrorCode &errorCode) {
812 if(U_FAILURE(errorCode)) { return; }
813 const uint16_t *items16 = NULL;
814 const Resource *items32 = NULL;
815 uint32_t offset=RES_GET_OFFSET(array);
816 int32_t length = 0;
817 switch(RES_GET_TYPE(array)) {
818 case URES_ARRAY: {
819 if (offset!=0) { /* empty if offset==0 */
820 items32 = (const Resource *)pResData->pRoot+offset;
821 length = *items32++;
822 }
823 break;
824 }
825 case URES_ARRAY16: {
826 items16 = pResData->p16BitUnits+offset;
827 length = *items16++;
828 break;
829 }
830 default:
831 errorCode = U_RESOURCE_TYPE_MISMATCH;
832 return;
833 }
834
835 for (int32_t i = 0; i < length; ++i) {
836 Resource res;
837 if (items16 != NULL) {
838 res = makeResourceFrom16(pResData, items16[i]);
839 } else {
840 res = items32[i];
841 }
842 int32_t type = RES_GET_TYPE(res);
843 if (URES_IS_ARRAY(type)) {
844 int32_t numItems = getArrayLength(pResData, res);
845 icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(i, numIt ems, errorCode);
846 if (subSink != NULL) {
847 ures_getAllArrayItems(pResData, res, value, *subSink, errorCode) ;
848 }
849 } else if (URES_IS_TABLE(type)) {
850 int32_t numItems = getTableLength(pResData, res);
851 icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(i, numIt ems, errorCode);
852 if (subSink != NULL) {
853 ures_getAllTableItems(pResData, res, value, *subSink, errorCode) ;
854 }
855 /* TODO: settle on how to deal with aliases, port to Java
856 } else if (type == URES_ALIAS) {
857 // aliases not handled in resource enumeration
858 errorCode = U_UNSUPPORTED_ERROR;
859 return; */
860 } else {
861 value.setResource(res);
862 sink.put(i, value, errorCode);
863 }
864 if(U_FAILURE(errorCode)) { return; }
865 }
866 sink.leave(errorCode);
867 }
868
571 U_CFUNC Resource 869 U_CFUNC Resource
572 res_findResource(const ResourceData *pResData, Resource r, char** path, const ch ar** key) { 870 res_findResource(const ResourceData *pResData, Resource r, char** path, const ch ar** key) {
573 /* we pass in a path. CollationElements/Sequence or zoneStrings/3/2 etc.
574 * iterates over a path and stops when a scalar resource is found. This
575 * CAN be an alias. Path gets set to the part that has not yet been processed.
576 */
577
578 char *pathP = *path, *nextSepP = *path; 871 char *pathP = *path, *nextSepP = *path;
579 char *closeIndex = NULL; 872 char *closeIndex = NULL;
580 Resource t1 = r; 873 Resource t1 = r;
581 Resource t2; 874 Resource t2;
582 int32_t indexR = 0; 875 int32_t indexR = 0;
583 UResType type = (UResType)RES_GET_TYPE(t1); 876 UResType type = (UResType)RES_GET_TYPE(t1);
584 877
585 /* if you come in with an empty path, you'll be getting back the same resource */ 878 /* if you come in with an empty path, you'll be getting back the same resource */
586 if(!uprv_strlen(pathP)) { 879 if(!uprv_strlen(pathP)) {
587 return r; 880 return r;
588 } 881 }
589 882
590 /* one needs to have an aggregate resource in order to search in it */ 883 /* one needs to have an aggregate resource in order to search in it */
591 if(!URES_IS_CONTAINER(type)) { 884 if(!URES_IS_CONTAINER(type)) {
592 return RES_BOGUS; 885 return RES_BOGUS;
593 } 886 }
594 887
595 while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) { 888 while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) {
596 /* Iteration stops if: the path has been consumed, we found a non-existing 889 /* Iteration stops if: the path has been consumed, we found a non-existing
597 * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias ) 890 * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias )
598 */ 891 */
599 nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR); 892 nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR);
600 /* if there are more separators, terminate string 893 /* if there are more separators, terminate string
601 * and set path to the remaining part of the string 894 * and set path to the remaining part of the string
602 */ 895 */
603 if(nextSepP != NULL) { 896 if(nextSepP != NULL) {
897 if(nextSepP == pathP) {
898 // Empty key string.
899 return RES_BOGUS;
900 }
604 *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */ 901 *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */
605 *path = nextSepP+1; 902 *path = nextSepP+1;
606 } else { 903 } else {
607 *path = uprv_strchr(pathP, 0); 904 *path = uprv_strchr(pathP, 0);
608 } 905 }
609 906
610 /* if the resource is a table */ 907 /* if the resource is a table */
611 /* try the key based access */ 908 /* try the key based access */
612 if(URES_IS_TABLE(type)) { 909 if(URES_IS_TABLE(type)) {
613 *key = pathP; 910 *key = pathP;
614 t2 = res_getTableItemByKey(pResData, t1, &indexR, key); 911 t2 = res_getTableItemByKey(pResData, t1, &indexR, key);
615 if(t2 == RES_BOGUS) { 912 if(t2 == RES_BOGUS) {
616 /* if we fail to get the resource by key, maybe we got an index */ 913 /* if we fail to get the resource by key, maybe we got an index */
617 indexR = uprv_strtol(pathP, &closeIndex, 10); 914 indexR = uprv_strtol(pathP, &closeIndex, 10);
618 if(closeIndex != pathP) { 915 if(*closeIndex == 0) {
619 /* if we indeed have an index, try to get the item by index */ 916 /* if we indeed have an index, try to get the item by index */
620 t2 = res_getTableItemByIndex(pResData, t1, indexR, key); 917 t2 = res_getTableItemByIndex(pResData, t1, indexR, key);
621 } 918 }
622 } 919 }
623 } else if(URES_IS_ARRAY(type)) { 920 } else if(URES_IS_ARRAY(type)) {
624 indexR = uprv_strtol(pathP, &closeIndex, 10); 921 indexR = uprv_strtol(pathP, &closeIndex, 10);
625 if(closeIndex != pathP) { 922 if(*closeIndex == 0) {
626 t2 = res_getArrayItem(pResData, t1, indexR); 923 t2 = res_getArrayItem(pResData, t1, indexR);
627 } else { 924 } else {
628 t2 = RES_BOGUS; /* have an array, but don't have a valid index */ 925 t2 = RES_BOGUS; /* have an array, but don't have a valid index */
629 } 926 }
630 *key = NULL; 927 *key = NULL;
631 } else { /* can't do much here, except setting t2 to bogus */ 928 } else { /* can't do much here, except setting t2 to bogus */
632 t2 = RES_BOGUS; 929 t2 = RES_BOGUS;
633 } 930 }
634 t1 = t2; 931 t1 = t2;
635 type = (UResType)RES_GET_TYPE(t1); 932 type = (UResType)RES_GET_TYPE(t1);
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 /* 1384 /*
1088 * We need one bit per 4 resource bundle bytes so that we can track 1385 * We need one bit per 4 resource bundle bytes so that we can track
1089 * every possible Resource for whether we have swapped it already. 1386 * every possible Resource for whether we have swapped it already.
1090 * Multiple Resource words can refer to the same bundle offsets 1387 * Multiple Resource words can refer to the same bundle offsets
1091 * for sharing identical values. 1388 * for sharing identical values.
1092 * We could optimize this by allocating only for locations above 1389 * We could optimize this by allocating only for locations above
1093 * where Resource values are stored (above keys & strings). 1390 * where Resource values are stored (above keys & strings).
1094 */ 1391 */
1095 resFlagsLength=(length+31)>>5; /* number of bytes needed */ 1392 resFlagsLength=(length+31)>>5; /* number of bytes needed */
1096 resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint3 2_t */ 1393 resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint3 2_t */
1097 if(resFlagsLength<=sizeof(stackResFlags)) { 1394 if(resFlagsLength<=(int32_t)sizeof(stackResFlags)) {
1098 tempTable.resFlags=stackResFlags; 1395 tempTable.resFlags=stackResFlags;
1099 } else { 1396 } else {
1100 tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength); 1397 tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength);
1101 if(tempTable.resFlags==NULL) { 1398 if(tempTable.resFlags==NULL) {
1102 udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n"); 1399 udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n");
1103 *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1400 *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
1104 return 0; 1401 return 0;
1105 } 1402 }
1106 } 1403 }
1107 uprv_memset(tempTable.resFlags, 0, resFlagsLength); 1404 uprv_memset(tempTable.resFlags, 0, resFlagsLength);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 if(tempTable.resFlags!=stackResFlags) { 1457 if(tempTable.resFlags!=stackResFlags) {
1161 uprv_free(tempTable.resFlags); 1458 uprv_free(tempTable.resFlags);
1162 } 1459 }
1163 1460
1164 /* swap the root resource and indexes */ 1461 /* swap the root resource and indexes */
1165 ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode); 1462 ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode);
1166 } 1463 }
1167 1464
1168 return headerSize+4*top; 1465 return headerSize+4*top;
1169 } 1466 }
OLDNEW
« no previous file with comments | « source/common/uresdata.c ('k') | source/common/uresimp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698