diff --git a/icu4c/source/common/ucmndata.c b/icu4c/source/common/ucmndata.c index 6d1d65a7db..9f9a25987c 100644 --- a/icu4c/source/common/ucmndata.c +++ b/icu4c/source/common/ucmndata.c @@ -104,7 +104,8 @@ offsetTOCLookupFn(const UDataMemory *pData, const UDataOffsetTOC *toc = (UDataOffsetTOC *)pData->toc; if(toc!=NULL) { const char *base=(const char *)pData->toc; - uint32_t start, limit, number; + uint32_t start, limit, number, lastNumber; + int32_t strResult; /* perform a binary search for the data in the common data's table of contents */ #if defined (UDATA_DEBUG_DUMP) @@ -116,36 +117,40 @@ offsetTOCLookupFn(const UDataMemory *pData, start=0; limit=toc->count; /* number of names in this table of contents */ + lastNumber=limit; if (limit == 0) { /* Stub common data library used during build is empty. */ return NULL; } - while(startentry[number].nameOffset])<0) { + for (;;) { + number = (start+limit)/2; + if (lastNumber == number) { /* Have we moved? */ + break; /* We haven't moved, and it wasn't found. */ + } + lastNumber = number; + strResult = uprv_strcmp(tocEntryName, &base[toc->entry[number].nameOffset]); + if(strResult<0) { limit=number; - } else { + } else if (strResult>0) { start=number; } - } - - if(uprv_strcmp(tocEntryName, &base[toc->entry[start].nameOffset])==0) { - /* found it */ + else { + /* found it */ #ifdef UDATA_DEBUG - /* fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); */ - fprintf(stderr, "%s: Found.\n", tocEntryName); + /* fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); */ + fprintf(stderr, "%s: Found.\n", tocEntryName); #endif - if((start+1)count) { - *pLength=(int32_t)(toc->entry[start+1].dataOffset-toc->entry[start].dataOffset); - } else { - *pLength=-1; + if((number+1)count) { + *pLength=(int32_t)(toc->entry[number+1].dataOffset-toc->entry[number].dataOffset); + } else { + *pLength=-1; + } + return (const DataHeader *)&base[toc->entry[number].dataOffset]; } - return (const DataHeader *)&base[toc->entry[start].dataOffset]; - } else { -#ifdef UDATA_DEBUG - fprintf(stderr, "%s: Not found.\n", tocEntryName); -#endif - return NULL; } +#ifdef UDATA_DEBUG + fprintf(stderr, "%s: Not found.\n", tocEntryName); +#endif + return NULL; } else { #ifdef UDATA_DEBUG fprintf(stderr, "returning header\n"); diff --git a/icu4c/source/common/udata.c b/icu4c/source/common/udata.c index aecca1b75f..812be87c7e 100644 --- a/icu4c/source/common/udata.c +++ b/icu4c/source/common/udata.c @@ -371,7 +371,7 @@ static void TinyString_append(TinyString *This, const char *what) { } } if (newLen < This->fCapacity) { - uprv_strcat(This->s, what); + uprv_strcat(This->s+This->length, what); This->length = newLen; } } @@ -392,7 +392,7 @@ static void TinyString_appendn(TinyString *This, const char *what, int32_t n) { } } if (newLen < This->fCapacity) { - uprv_strncat(This->s, what, n); + uprv_strncat(This->s+This->length, what, n); This->length = newLen; } } @@ -1058,7 +1058,6 @@ doOpenChoice(const char *path, const char *type, const char *name, { UDataMemory *retVal = NULL; - UDataPathIterator iter; const char *pathBuffer; TinyString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */ @@ -1254,100 +1253,103 @@ doOpenChoice(const char *path, const char *type, const char *name, dataPath = u_getDataDirectory(); - /* #1a look in ind. files: package\nam.typ ========================= */ - /* init path iterator for individual files */ - udata_pathiter_init(&iter, dataPath, pkgName.s, path, tocEntryPathSuffix, FALSE); - - while((pathBuffer = udata_pathiter_next(&iter, NULL))) - { -#ifdef UDATA_DEBUG - fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); -#endif - if( uprv_mapFile(&dataMemory, pathBuffer) || - (inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename))) - { - pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode); - if (pEntryData != NULL) { - /* Data is good. - * Hand off ownership of the backing memory to the user's UDataMemory. - * and return it. */ - pEntryData->mapAddr = dataMemory.mapAddr; - pEntryData->map = dataMemory.map; - -#ifdef UDATA_DEBUG - fprintf(stderr, "** Mapped file: %s\n", pathBuffer); -#endif - udata_pathiter_dt(&iter); - retVal = pEntryData; - goto commonReturn; - } - - /* the data is not acceptable, or some error occured. Either way, unmap the memory */ - udata_close(&dataMemory); - - /* If we had a nasty error, bail out completely. */ - if (U_FAILURE(*pErrorCode)) { - udata_pathiter_dt(&iter); - retVal = NULL; - goto commonReturn; - } - - /* Otherwise remember that we found data but didn't like it for some reason */ - errorCode=U_INVALID_FORMAT_ERROR; - } -#ifdef UDATA_DEBUG - fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); -#endif - } - udata_pathiter_dt(&iter); + /* Check to make sure that there is a dataPath to iterate over */ + if (dataPath && *dataPath) { + UDataPathIterator iter; + /* #1a look in ind. files: package\nam.typ ========================= */ + /* init path iterator for individual files */ + udata_pathiter_init(&iter, dataPath, pkgName.s, path, tocEntryPathSuffix, FALSE); - /* #1b look in ind. files - with old naming (package_nam.typ not package\nam.typ) ==================== */ - /* init path iterator for individual files */ - udata_pathiter_init(&iter, dataPath, "", path, oldIndFileName.s, FALSE); - - while((pathBuffer = udata_pathiter_next(&iter, NULL))) - { -#ifdef UDATA_DEBUG - fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); -#endif - if( uprv_mapFile(&dataMemory, pathBuffer) || - (inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename))) + while((pathBuffer = udata_pathiter_next(&iter, NULL))) { - pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode); - if (pEntryData != NULL) { - /* Data is good. - * Hand off ownership of the backing memory to the user's UDataMemory. - * and return it. */ - pEntryData->mapAddr = dataMemory.mapAddr; - pEntryData->map = dataMemory.map; - #ifdef UDATA_DEBUG - fprintf(stderr, "** Mapped file: %s\n", pathBuffer); + fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); #endif - udata_pathiter_dt(&iter); - retVal = pEntryData; - goto commonReturn; - } - - /* the data is not acceptable, or some error occured. Either way, unmap the memory */ - udata_close(&dataMemory); - - /* If we had a nasty error, bail out completely. */ - if (U_FAILURE(*pErrorCode)) { - udata_pathiter_dt(&iter); - retVal = NULL; - goto commonReturn; - } - - /* Otherwise remember that we found data but didn't like it for some reason */ - errorCode=U_INVALID_FORMAT_ERROR; - } -#ifdef UDATA_DEBUG - fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); -#endif - } - udata_pathiter_dt(&iter); + if( uprv_mapFile(&dataMemory, pathBuffer) || + (inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename))) + { + pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode); + if (pEntryData != NULL) { + /* Data is good. + * Hand off ownership of the backing memory to the user's UDataMemory. + * and return it. */ + pEntryData->mapAddr = dataMemory.mapAddr; + pEntryData->map = dataMemory.map; +#ifdef UDATA_DEBUG + fprintf(stderr, "** Mapped file: %s\n", pathBuffer); +#endif + udata_pathiter_dt(&iter); + retVal = pEntryData; + goto commonReturn; + } + + /* the data is not acceptable, or some error occured. Either way, unmap the memory */ + udata_close(&dataMemory); + + /* If we had a nasty error, bail out completely. */ + if (U_FAILURE(*pErrorCode)) { + udata_pathiter_dt(&iter); + retVal = NULL; + goto commonReturn; + } + + /* Otherwise remember that we found data but didn't like it for some reason */ + errorCode=U_INVALID_FORMAT_ERROR; + } +#ifdef UDATA_DEBUG + fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); +#endif + } + udata_pathiter_dt(&iter); + + /* #1b look in ind. files - with old naming (package_nam.typ not package\nam.typ) ==================== */ + /* init path iterator for individual files */ + udata_pathiter_init(&iter, dataPath, "", path, oldIndFileName.s, FALSE); + + while((pathBuffer = udata_pathiter_next(&iter, NULL))) + { +#ifdef UDATA_DEBUG + fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); +#endif + if( uprv_mapFile(&dataMemory, pathBuffer) || + (inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename))) + { + pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode); + if (pEntryData != NULL) { + /* Data is good. + * Hand off ownership of the backing memory to the user's UDataMemory. + * and return it. */ + pEntryData->mapAddr = dataMemory.mapAddr; + pEntryData->map = dataMemory.map; + +#ifdef UDATA_DEBUG + fprintf(stderr, "** Mapped file: %s\n", pathBuffer); +#endif + udata_pathiter_dt(&iter); + retVal = pEntryData; + goto commonReturn; + } + + /* the data is not acceptable, or some error occured. Either way, unmap the memory */ + udata_close(&dataMemory); + + /* If we had a nasty error, bail out completely. */ + if (U_FAILURE(*pErrorCode)) { + udata_pathiter_dt(&iter); + retVal = NULL; + goto commonReturn; + } + + /* Otherwise remember that we found data but didn't like it for some reason */ + errorCode=U_INVALID_FORMAT_ERROR; + } +#ifdef UDATA_DEBUG + fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); +#endif + } + udata_pathiter_dt(&iter); + } /* #2 */ @@ -1372,17 +1374,17 @@ doOpenChoice(const char *path, const char *type, const char *name, fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName.s, pHeader, u_errorName(errorCode)); #endif if((pHeader == NULL) && !U_FAILURE(errorCode)) { - pHeader=pCommonData->vFuncs->Lookup(pCommonData, oldIndFileName.s, /* oldIndFileName is preceded by a slash */ + pHeader=pCommonData->vFuncs->Lookup(pCommonData, oldIndFileName.s, /* oldIndFileName is preceded by a slash */ &length, &errorCode); #ifdef UDATA_DEBUG - fprintf(stderr, "[OLD name] %s: pHeader=%p - %s\n", oldIndFileName.s, pHeader, u_errorName(errorCode)); + fprintf(stderr, "[OLD name] %s: pHeader=%p - %s\n", oldIndFileName.s, pHeader, u_errorName(errorCode)); #endif } if(pHeader!=NULL) { pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode); #ifdef UDATA_DEBUG - fprintf(stderr, "pEntryData=%p\n", pEntryData); + fprintf(stderr, "pEntryData=%p\n", pEntryData); #endif if (U_FAILURE(*pErrorCode)) { retVal = NULL;