ICU-2235 make udata_open() work with opposite-endian data

X-SVN-Rev: 13813
This commit is contained in:
Markus Scherer 2003-11-21 18:35:16 +00:00
parent 4cc4e9ed10
commit 7673b76970
4 changed files with 59 additions and 10 deletions

View file

@ -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 */

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}