X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..f59164e3d128c7675a4d3934206346a3384e53a5:/icuSources/tools/makeconv/gencnvex.c diff --git a/icuSources/tools/makeconv/gencnvex.c b/icuSources/tools/makeconv/gencnvex.c index 0ae6d4a1..6ea94418 100644 --- a/icuSources/tools/makeconv/gencnvex.c +++ b/icuSources/tools/makeconv/gencnvex.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2003-2004, International Business Machines +* Copyright (C) 2003-2014, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -27,8 +27,6 @@ #include "makeconv.h" #include "genmbcs.h" -#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) - static void CnvExtClose(NewConverter *cnvData); @@ -75,16 +73,18 @@ CnvExtOpen(UCMFile *ucm) { CnvExtData *extData; extData=(CnvExtData *)uprv_malloc(sizeof(CnvExtData)); - if(extData!=NULL) { - uprv_memset(extData, 0, sizeof(CnvExtData)); + if(extData==NULL) { + printf("out of memory\n"); + exit(U_MEMORY_ALLOCATION_ERROR); + } + uprv_memset(extData, 0, sizeof(CnvExtData)); - extData->ucm=ucm; /* aliased, not owned */ + extData->ucm=ucm; /* aliased, not owned */ - extData->newConverter.close=CnvExtClose; - extData->newConverter.isValid=CnvExtIsValid; - extData->newConverter.addTable=CnvExtAddTable; - extData->newConverter.write=CnvExtWrite; - } + extData->newConverter.close=CnvExtClose; + extData->newConverter.isValid=CnvExtIsValid; + extData->newConverter.addTable=CnvExtAddTable; + extData->newConverter.write=CnvExtWrite; return &extData->newConverter; } @@ -97,6 +97,7 @@ CnvExtClose(NewConverter *cnvData) { utm_close(extData->fromUTableUChars); utm_close(extData->fromUTableValues); utm_close(extData->fromUBytes); + uprv_free(extData); } } @@ -127,7 +128,7 @@ CnvExtWrite(NewConverter *cnvData, const UConverterStaticData *staticData, extData->ucm->baseName[length++]=0; } - headerSize=sizeof(header)+length; + headerSize=MBCS_HEADER_V4_LENGTH*4+length; /* fill the header */ header.version[0]=4; @@ -135,7 +136,7 @@ CnvExtWrite(NewConverter *cnvData, const UConverterStaticData *staticData, header.flags=(uint32_t)((headerSize<<8)|MBCS_OUTPUT_EXT_ONLY); /* write the header and the base table name */ - udata_writeBlock(pData, &header, sizeof(header)); + udata_writeBlock(pData, &header, MBCS_HEADER_V4_LENGTH*4); udata_writeBlock(pData, extData->ucm->baseName, length); } @@ -286,8 +287,10 @@ CnvExtWrite(NewConverter *cnvData, const UConverterStaticData *staticData, /* * Remove fromUnicode fallbacks and SUB mappings which are irrelevant for * the toUnicode table. + * This includes mappings with MBCS_FROM_U_EXT_FLAG which were suitable + * for the base toUnicode table but not for the base fromUnicode table. * The table must be sorted. - * Destroys previous data in the reverseMap. + * Modifies previous data in the reverseMap. */ static int32_t reduceToUMappings(UCMTable *table) { @@ -344,7 +347,7 @@ getToUnicodeValue(CnvExtData *extData, UCMTable *table, UCMapping *m) { /* allocate it and put its length and index into the value */ value= - (((uint32_t)m->uLen+UCNV_EXT_TO_U_LENGTH_OFFSET)<toUUChars)); u=utm_allocN(extData->toUUChars, u16Length); @@ -438,17 +441,24 @@ generateToUTable(CnvExtData *extData, UCMTable *table, /* step 2: allocate the section; set count, section */ count=(high-low)+1; - if(unitIndex==0 || uniqueCount>=(3*count)/4) { + if(count<0x100 && (unitIndex==0 || uniqueCount>=(3*count)/4)) { /* * for the root table and for fairly full tables: * allocate for direct, linear array access * by keeping count, to write an entry for each unit value * from low to high + * exception: use a compact table if count==0x100 because + * that cannot be encoded in the length byte */ } else { count=uniqueCount; } + if(count>=0x100) { + fprintf(stderr, "error: toUnicode extension table section overflow: %ld section entries\n", (long)count); + return FALSE; + } + /* allocate the section: 1 entry for the header + count for the items */ section=(uint32_t *)utm_allocN(extData->toUTable, 1+count); @@ -562,6 +572,7 @@ makeToUTable(CnvExtData *extData, UCMTable *table) { /* * Remove toUnicode fallbacks and non- SUB mappings * which are irrelevant for the fromUnicode extension table. + * Remove MBCS_FROM_U_EXT_FLAG bits. * Overwrite the reverseMap with an index array to the relevant mappings. * Modify the code point sequences to a generator-friendly format where * the first code points remains unchanged but the following are recoded @@ -588,7 +599,11 @@ prepareFromUMappings(UCMTable *table) { for(i=j=0; if; - if(flag==0 || flag==1 || (flag==2 && m->bLen==1)) { + if(flag>=0) { + flag&=MBCS_FROM_U_EXT_MASK; + m->f=flag; + } + if(flag==0 || flag==1 || (flag==2 && m->bLen==1) || flag==4) { map[j++]=i; if(m->uLen>1) { @@ -654,6 +669,8 @@ getFromUBytesValue(CnvExtData *extData, UCMTable *table, UCMapping *m) { value|=(uint32_t)m->bLen<f==0) { value|=UCNV_EXT_FROM_U_ROUNDTRIP_FLAG; + } else if(m->f==4) { + value|=UCNV_EXT_FROM_U_GOOD_ONE_WAY_FLAG; } /* calculate the real UTF-16 length (see recoding in prepareFromUMappings()) */ @@ -829,7 +846,7 @@ addFromUTrieEntry(CnvExtData *extData, UChar32 c, uint32_t value) { extData->stage1[i1]=(uint16_t)newBlock; extData->stage2Top=newBlock+MBCS_STAGE_2_BLOCK_SIZE; - if(extData->stage2Top>LENGTHOF(extData->stage2)) { + if(extData->stage2Top>UPRV_LENGTHOF(extData->stage2)) { fprintf(stderr, "error: too many stage 2 entries at U+%04x\n", (int)c); exit(U_MEMORY_ALLOCATION_ERROR); } @@ -851,7 +868,7 @@ addFromUTrieEntry(CnvExtData *extData, UChar32 c, uint32_t value) { extData->stage2[i2]=(uint16_t)(newBlock>>UCNV_EXT_STAGE_2_LEFT_SHIFT); extData->stage3Top=newBlock+MBCS_STAGE_3_BLOCK_SIZE; - if(extData->stage3Top>LENGTHOF(extData->stage3)) { + if(extData->stage3Top>UPRV_LENGTHOF(extData->stage3)) { fprintf(stderr, "error: too many stage 3 entries at U+%04x\n", (int)c); exit(U_MEMORY_ALLOCATION_ERROR); } @@ -895,7 +912,7 @@ addFromUTrieEntry(CnvExtData *extData, UChar32 c, uint32_t value) { } } } else { - if((i3b=extData->stage3bTop++)>=LENGTHOF(extData->stage3b)) { + if((i3b=extData->stage3bTop++)>=UPRV_LENGTHOF(extData->stage3b)) { fprintf(stderr, "error: too many stage 3b entries at U+%04x\n", (int)c); exit(U_MEMORY_ALLOCATION_ERROR); }