/*----------------------------------------------------------------------* * * * checkCommonData Validate the format of a common data file. * * Fill in the virtual function ptr based on TOC type * * If the data is invalid, close the UDataMemory * * and set the appropriate error code. * * * *----------------------------------------------------------------------*/ U_CFUNC void udata_checkCommonData(UDataMemory *udm, UErrorCode *err) { if (U_FAILURE(*err)) { return; } if(udm==NULL || udm->pHeader==NULL) { *err=U_INVALID_FORMAT_ERROR; } else if(!(udm->pHeader->dataHeader.magic1==0xda && udm->pHeader->dataHeader.magic2==0x27 && udm->pHeader->info.isBigEndian==U_IS_BIG_ENDIAN && udm->pHeader->info.charsetFamily==U_CHARSET_FAMILY) ) { /* header not valid */ *err=U_INVALID_FORMAT_ERROR; } else if (udm->pHeader->info.dataFormat[0]==0x43 && udm->pHeader->info.dataFormat[1]==0x6d && udm->pHeader->info.dataFormat[2]==0x6e && udm->pHeader->info.dataFormat[3]==0x44 && udm->pHeader->info.formatVersion[0]==1 ) { /* dataFormat="CmnD" */ udm->vFuncs = &CmnDFuncs; udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else if(udm->pHeader->info.dataFormat[0]==0x54 && udm->pHeader->info.dataFormat[1]==0x6f && udm->pHeader->info.dataFormat[2]==0x43 && udm->pHeader->info.dataFormat[3]==0x50 && udm->pHeader->info.formatVersion[0]==1 ) { /* dataFormat="ToCP" */ udm->vFuncs = &ToCPFuncs; udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else { /* dataFormat not recognized */ *err=U_INVALID_FORMAT_ERROR; } if (U_FAILURE(*err)) { /* If the data is no good and we memory-mapped it ourselves, * close the memory mapping so it doesn't leak. Note that this has * no effect on non-memory mapped data, other than clearing fields in udm. */ udata_close(udm); } }
U_CAPI const void * U_EXPORT2 udata_getMemory(UDataMemory *pData) { if(pData!=NULL && pData->pHeader!=NULL) { return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader); } else { return NULL; } }
/** * Get the length of the data item if possible. * The length may be up to 15 bytes larger than the actual data. * * TODO Consider making this function public. * It would have to return the actual length in more cases. * For example, the length of the last item in a .dat package could be * computed from the size of the whole .dat package minus the offset of the * last item. * The size of a file that was directly memory-mapped could be determined * using some system API. * * In order to get perfect values for all data items, we may have to add a * length field to UDataInfo, but that complicates data generation * and may be overkill. * * @param pData The data item. * @return the length of the data item, or -1 if not known * @internal Currently used only in cintltst/udatatst.c */ U_CAPI int32_t U_EXPORT2 udata_getLength(const UDataMemory *pData) { if(pData!=NULL && pData->pHeader!=NULL && pData->length>=0) { /* * subtract the header size, * return only the size of the actual data starting at udata_getMemory() */ return pData->length-udata_getHeaderSize(pData->pHeader); } else { return -1; } }