]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/tools/makeconv/gencnvex.c
ICU-531.48.tar.gz
[apple/icu.git] / icuSources / tools / makeconv / gencnvex.c
index c5fc7d464c3d479d3b70ce2089af4d19814d1013..10a0571c6b9e36e9b773b62f1322b8b7d07cdeca 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2003-2006, International Business Machines
+*   Copyright (C) 2003-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -76,16 +76,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;
 }
 
@@ -98,6 +100,7 @@ CnvExtClose(NewConverter *cnvData) {
         utm_close(extData->fromUTableUChars);
         utm_close(extData->fromUTableValues);
         utm_close(extData->fromUBytes);
+        uprv_free(extData);
     }
 }
 
@@ -128,7 +131,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;
@@ -136,7 +139,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);
     }
 
@@ -287,8 +290,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) {
@@ -345,7 +350,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)<<UCNV_EXT_TO_U_LENGTH_SHIFT)|
+            (((uint32_t)u16Length+UCNV_EXT_TO_U_LENGTH_OFFSET)<<UCNV_EXT_TO_U_LENGTH_SHIFT)|
             ((uint32_t)utm_countItems(extData->toUUChars));
         u=utm_allocN(extData->toUUChars, u16Length);
 
@@ -439,17 +444,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);
 
@@ -563,6 +575,7 @@ makeToUTable(CnvExtData *extData, UCMTable *table) {
 /*
  * Remove toUnicode fallbacks and non-<subchar1> 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
@@ -589,7 +602,11 @@ prepareFromUMappings(UCMTable *table) {
 
     for(i=j=0; i<count; ++m, ++i) {
         flag=m->f;
-        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) {
@@ -655,6 +672,8 @@ getFromUBytesValue(CnvExtData *extData, UCMTable *table, UCMapping *m) {
     value|=(uint32_t)m->bLen<<UCNV_EXT_FROM_U_LENGTH_SHIFT;
     if(m->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()) */
@@ -1058,4 +1077,3 @@ CnvExtAddTable(NewConverter *cnvData, UCMTable *table, UConverterStaticData *sta
         makeToUTable(extData, table) &&
         makeFromUTable(extData, table);
 }
-