From 7673b76970dd9ca15eac076c4995195522f48f00 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Fri, 21 Nov 2003 18:35:16 +0000 Subject: [PATCH] ICU-2235 make udata_open() work with opposite-endian data X-SVN-Rev: 13813 --- icu4c/source/common/ucmndata.c | 31 +++++++++++++++++++++++++++++-- icu4c/source/common/ucmndata.h | 19 ++++++++++++++++++- icu4c/source/common/udata.c | 15 ++++++++++----- icu4c/source/common/udatamem.c | 4 ++-- 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/icu4c/source/common/ucmndata.c b/icu4c/source/common/ucmndata.c index 0ac16c554fb..caa2d2c9483 100644 --- a/icu4c/source/common/ucmndata.c +++ b/icu4c/source/common/ucmndata.c @@ -26,6 +26,33 @@ #include "ucmndata.h" #include "udatamem.h" +U_CFUNC uint16_t +udata_getHeaderSize(const DataHeader *udh) { + if(udh==NULL) { + return 0; + } else if(udh->info.isBigEndian==U_IS_BIG_ENDIAN) { + /* same endianness */ + return udh->dataHeader.headerSize; + } else { + /* opposite endianness */ + uint16_t x=udh->dataHeader.headerSize; + return (uint16_t)((x<<8)|(x>>8)); + } +} + +U_CFUNC uint16_t +udata_getInfoSize(const UDataInfo *info) { + if(info==NULL) { + return 0; + } else if(info->isBigEndian==U_IS_BIG_ENDIAN) { + /* same endianness */ + return info->size; + } else { + /* opposite endianness */ + uint16_t x=info->size; + return (uint16_t)((x<<8)|(x>>8)); + } +} /*----------------------------------------------------------------------------------* * * @@ -199,7 +226,7 @@ void udata_checkCommonData(UDataMemory *udm, UErrorCode *err) { ) { /* dataFormat="CmnD" */ udm->vFuncs = &CmnDFuncs; - udm->toc=(const char *)udm->pHeader+udm->pHeader->dataHeader.headerSize; + udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else if(udm->pHeader->info.dataFormat[0]==0x54 && udm->pHeader->info.dataFormat[1]==0x6f && @@ -209,7 +236,7 @@ void udata_checkCommonData(UDataMemory *udm, UErrorCode *err) { ) { /* dataFormat="ToCP" */ udm->vFuncs = &ToCPFuncs; - udm->toc=(const char *)udm->pHeader+udm->pHeader->dataHeader.headerSize; + udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else { /* dataFormat not recognized */ diff --git a/icu4c/source/common/ucmndata.h b/icu4c/source/common/ucmndata.h index 886ef32055b..9634ed840f6 100644 --- a/icu4c/source/common/ucmndata.h +++ b/icu4c/source/common/ucmndata.h @@ -50,9 +50,26 @@ typedef struct { typedef struct { uint32_t count; - UDataOffsetTOCEntry entry[2]; /* Acutal size of array is from count. */ + UDataOffsetTOCEntry entry[2]; /* Actual size of array is from count. */ } UDataOffsetTOC; +/** + * Get the header size from a const DataHeader *udh. + * Handles opposite-endian data. + * + * @internal + */ +U_CFUNC uint16_t +udata_getHeaderSize(const DataHeader *udh); + +/** + * Get the UDataInfo.size from a const UDataInfo *info. + * Handles opposite-endian data. + * + * @internal + */ +U_CFUNC uint16_t +udata_getInfoSize(const UDataInfo *info); /* * "Virtual" functions for data lookup. diff --git a/icu4c/source/common/udata.c b/icu4c/source/common/udata.c index e95dc8378c1..67f0bf5e7e3 100644 --- a/icu4c/source/common/udata.c +++ b/icu4c/source/common/udata.c @@ -874,9 +874,8 @@ checkDataItem if(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 && - pHeader->info.isBigEndian==U_IS_BIG_ENDIAN && (isAcceptable==NULL || isAcceptable(context, type, name, &pHeader->info)) - ) { + ) { rDataMem=UDataMemory_createNewInstance(fatalErr); if (U_FAILURE(*fatalErr)) { return NULL; @@ -1165,10 +1164,16 @@ udata_getInfo(UDataMemory *pData, UDataInfo *pInfo) { if(pInfo!=NULL) { if(pData!=NULL && pData->pHeader!=NULL) { const UDataInfo *info=&pData->pHeader->info; - if(pInfo->size>info->size) { - pInfo->size=info->size; + uint16_t dataInfoSize=udata_getInfoSize(info); + if(pInfo->size>dataInfoSize) { + pInfo->size=dataInfoSize; + } + uprv_memcpy((uint16_t *)pInfo+1, (const uint16_t *)info+1, pInfo->size-2); + if(info->isBigEndian!=U_IS_BIG_ENDIAN) { + /* opposite endianness */ + uint16_t x=info->reservedWord; + pInfo->reservedWord=(uint16_t)((x<<8)|(x>>8)); } - uprv_memcpy((uint16_t *)pInfo+1, (uint16_t *)info+1, pInfo->size-2); } else { pInfo->size=0; } diff --git a/icu4c/source/common/udatamem.c b/icu4c/source/common/udatamem.c index 06a5308745b..220ee5a3124 100644 --- a/icu4c/source/common/udatamem.c +++ b/icu4c/source/common/udatamem.c @@ -101,7 +101,7 @@ udata_close(UDataMemory *pData) { U_CAPI const void * U_EXPORT2 udata_getMemory(UDataMemory *pData) { if(pData!=NULL && pData->pHeader!=NULL) { - return (char *)(pData->pHeader)+pData->pHeader->dataHeader.headerSize; + return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader); } else { return NULL; } @@ -134,7 +134,7 @@ udata_getLength(UDataMemory *pData) { * subtract the header size, * return only the size of the actual data starting at udata_getMemory() */ - return pData->length-pData->pHeader->dataHeader.headerSize; + return pData->length-udata_getHeaderSize(pData->pHeader); } else { return -1; }