mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-2235 make udata_open() work with opposite-endian data
X-SVN-Rev: 13813
This commit is contained in:
parent
4cc4e9ed10
commit
7673b76970
4 changed files with 59 additions and 10 deletions
icu4c/source/common
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue