]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/ucol_cnt.cpp
ICU-491.11.1.tar.gz
[apple/icu.git] / icuSources / i18n / ucol_cnt.cpp
index 5f9bfb325044426aa6f6ae60ac0de908758bc846..7c274b763e9ce3d31d9142bc59ee056922d4d05b 100644 (file)
@@ -1,22 +1,22 @@
 /*
-*******************************************************************************
-*
-*   Copyright (C) 2001, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*
-*******************************************************************************
-*   file name:  ucol_cnt.cpp
-*   encoding:   US-ASCII
-*   tab size:   8 (not used)
-*   indentation:4
-*
-*   created 02/22/2001
-*   created by: Vladimir Weinstein
-*
-* This module maintains a contraction table structure in expanded form
-* and provides means to flatten this structure
-* 
-*/
+ *******************************************************************************
+ *
+ *   Copyright (C) 2001-2008, International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ *
+ *******************************************************************************
+ *   file name:  ucol_cnt.cpp
+ *   encoding:   US-ASCII
+ *   tab size:   8 (not used)
+ *   indentation:4
+ *
+ *   created 02/22/2001
+ *   created by: Vladimir Weinstein
+ *
+ * This module maintains a contraction table structure in expanded form
+ * and provides means to flatten this structure
+ 
+ */
 
 #include "unicode/utypes.h"
 
@@ -26,9 +26,7 @@
 #include "ucol_cnt.h"
 #include "cmemory.h"
 
-U_NAMESPACE_BEGIN
-
-void uprv_growTable(ContractionTable *tbl, UErrorCode *status) {
+static void uprv_growTable(ContractionTable *tbl, UErrorCode *status) {
     if(tbl->position == tbl->size) {
         uint32_t *newData = (uint32_t *)uprv_realloc(tbl->CEs, 2*tbl->size*sizeof(uint32_t));
         if(newData == NULL) {
@@ -55,15 +53,15 @@ uprv_cnttab_open(UNewTrie *mapping, UErrorCode *status) {
     }
     CntTable *tbl = (CntTable *)uprv_malloc(sizeof(CntTable));
     if(tbl == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      return NULL;
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
     }
     tbl->mapping = mapping;
     tbl->elements = (ContractionTable **)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *));
     if(tbl->elements == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      uprv_free(tbl);
-      return NULL;
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        uprv_free(tbl);
+        return NULL;
     }
     tbl->capacity = INIT_EXP_TABLE_SIZE;
     uprv_memset(tbl->elements, 0, INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *));
@@ -79,22 +77,17 @@ uprv_cnttab_open(UNewTrie *mapping, UErrorCode *status) {
 static ContractionTable *addATableElement(CntTable *table, uint32_t *key, UErrorCode *status) {
     ContractionTable *el = (ContractionTable *)uprv_malloc(sizeof(ContractionTable));
     if(el == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      return NULL;
+        goto outOfMemory;
     }
     el->CEs = (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(uint32_t));
     if(el->CEs == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      uprv_free(el);
-      return NULL;
+        goto outOfMemory;
     }
 
     el->codePoints = (UChar *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(UChar));
     if(el->codePoints == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      uprv_free(el->CEs);
-      uprv_free(el);
-      return NULL;
+        uprv_free(el->CEs);
+        goto outOfMemory;
     }
 
     el->position = 0;
@@ -111,24 +104,26 @@ static ContractionTable *addATableElement(CntTable *table, uint32_t *key, UError
     if(table->size == table->capacity) {
         ContractionTable **newElements = (ContractionTable **)uprv_malloc(table->capacity*2*sizeof(ContractionTable *));
         // do realloc
-/*        table->elements = (ContractionTable **)realloc(table->elements, table->capacity*2*sizeof(ContractionTable *));*/
+        /*        table->elements = (ContractionTable **)realloc(table->elements, table->capacity*2*sizeof(ContractionTable *));*/
         if(newElements == NULL) {
-          *status = U_MEMORY_ALLOCATION_ERROR;
-          uprv_free(el->codePoints);
-          uprv_free(el->CEs);
-          uprv_free(el);
-          return NULL;
-        } else {
-          ContractionTable **oldElements = table->elements;
-          uprv_memcpy(newElements, oldElements, table->capacity*sizeof(ContractionTable *));
-          uprv_memset(newElements+table->capacity, 0, table->capacity*sizeof(ContractionTable *));
-          table->capacity *= 2;
-          table->elements = newElements;
-          uprv_free(oldElements);
+            uprv_free(el->codePoints);
+            uprv_free(el->CEs);
+            goto outOfMemory;
         }
+        ContractionTable **oldElements = table->elements;
+        uprv_memcpy(newElements, oldElements, table->capacity*sizeof(ContractionTable *));
+        uprv_memset(newElements+table->capacity, 0, table->capacity*sizeof(ContractionTable *));
+        table->capacity *= 2;
+        table->elements = newElements;
+        uprv_free(oldElements);
     }
 
     return el;
+
+outOfMemory:
+    *status = U_MEMORY_ALLOCATION_ERROR;
+    if (el) uprv_free(el);
+    return NULL;
 }
 
 U_CAPI int32_t  U_EXPORT2
@@ -145,8 +140,8 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
     }
     table->offsets = (int32_t *)uprv_malloc(table->size*sizeof(int32_t));
     if(table->offsets == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      return 0;
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
     }
 
 
@@ -162,10 +157,10 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
     }
     table->CEs = (uint32_t *)uprv_malloc(table->position*sizeof(uint32_t));
     if(table->CEs == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      uprv_free(table->offsets);
-      table->offsets = NULL;
-      return 0;
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        uprv_free(table->offsets);
+        table->offsets = NULL;
+        return 0;
     }
     uprv_memset(table->CEs, '?', table->position*sizeof(uint32_t));
 
@@ -174,12 +169,12 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
     }
     table->codePoints = (UChar *)uprv_malloc(table->position*sizeof(UChar));
     if(table->codePoints == NULL) {
-      *status = U_MEMORY_ALLOCATION_ERROR;
-      uprv_free(table->offsets);
-      table->offsets = NULL;
-      uprv_free(table->CEs);
-      table->CEs = NULL;
-      return 0;
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        uprv_free(table->offsets);
+        table->offsets = NULL;
+        uprv_free(table->CEs);
+        table->CEs = NULL;
+        return 0;
     }
     uprv_memset(table->codePoints, '?', table->position*sizeof(UChar));
 
@@ -191,14 +186,14 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
         int32_t size = table->elements[i]->position;
         uint8_t ccMax = 0, ccMin = 255, cc = 0;
         for(j = 1; j<size; j++) {
-          cc = u_getCombiningClass(table->elements[i]->codePoints[j]);
-          if(cc>ccMax) {
-            ccMax = cc;
-          }
-          if(cc<ccMin) {
-            ccMin = cc;
-          }
-          *(cpPointer+j) = table->elements[i]->codePoints[j];
+            cc = u_getCombiningClass(table->elements[i]->codePoints[j]);
+            if(cc>ccMax) {
+                ccMax = cc;
+            }
+            if(cc<ccMin) {
+                ccMin = cc;
+            }
+            *(cpPointer+j) = table->elements[i]->codePoints[j];
         }
         *cpPointer = ((ccMin==ccMax)?1:0 << 8) | ccMax;
 
@@ -212,7 +207,11 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
         CEPointer += size;
     }
 
-
+    // TODO: this one apparently updates the contraction CEs to point to a real address (relative to the 
+    // start of the flat file). However, what is done below is just wrong and it affects building of 
+    // tailorings that have constructions in a bad way. At least, one should enumerate the trie. Also,
+    // keeping a list of code points that are contractions might be smart, although I'm not sure if it's
+    // feasible.
     uint32_t CE;
     for(i = 0; i<=0x10FFFF; i++) {
         /*CE = ucmpe32_get(table->mapping, i);*/
@@ -228,98 +227,108 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta
     return table->position;
 }
 
-ContractionTable *uprv_cnttab_cloneContraction(ContractionTable *t, UErrorCode *status) {
-  ContractionTable *r = (ContractionTable *)uprv_malloc(sizeof(ContractionTable));
-  if(r == NULL) {
-    *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
-  }
+static ContractionTable *uprv_cnttab_cloneContraction(ContractionTable *t, UErrorCode *status) {
+    ContractionTable *r = (ContractionTable *)uprv_malloc(sizeof(ContractionTable));
+    if(r == NULL) {
+        goto outOfMemory;
+    }
 
-  r->position = t->position;
-  r->size = t->size;
+    r->position = t->position;
+    r->size = t->size;
 
-  r->codePoints = (UChar *)uprv_malloc(sizeof(UChar)*t->size);
-  r->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->size);
-  
-  /* test for NULL */
-  if((r->codePoints == NULL) || (r->CEs == NULL)) {
-    *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
-  }
-  uprv_memcpy(r->codePoints, t->codePoints, sizeof(UChar)*t->size);
-  uprv_memcpy(r->CEs, t->CEs, sizeof(uint32_t)*t->size);
+    r->codePoints = (UChar *)uprv_malloc(sizeof(UChar)*t->size);
+    if(r->codePoints == NULL) {
+        goto outOfMemory;
+    }
+    r->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->size);
+    if(r->CEs == NULL) {
+        uprv_free(r->codePoints);
+        goto outOfMemory;
+    }
+    uprv_memcpy(r->codePoints, t->codePoints, sizeof(UChar)*t->size);
+    uprv_memcpy(r->CEs, t->CEs, sizeof(uint32_t)*t->size);
 
-  return r;
+    return r;
 
+outOfMemory:
+    *status = U_MEMORY_ALLOCATION_ERROR;
+    if (r) uprv_free(r);
+    return NULL;
 }
 
 U_CAPI CntTable* U_EXPORT2
 uprv_cnttab_clone(CntTable *t, UErrorCode *status) {
-  if(U_FAILURE(*status)) {
-    return NULL;
-  }
-  int32_t i = 0;
-  CntTable *r = (CntTable *)uprv_malloc(sizeof(CntTable));
-  /* test for NULL */
-  if (r == NULL) {
-    *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
-  }
-  r->position = t->position;
-  r->size = t->size;
-  r->capacity = t->capacity;
+    if(U_FAILURE(*status)) {
+        return NULL;
+    }
+    int32_t i = 0;
+    CntTable *r = (CntTable *)uprv_malloc(sizeof(CntTable));
+    /* test for NULL */
+    if (r == NULL) {
+        goto outOfMemory;
+    }
+    r->position = t->position;
+    r->size = t->size;
+    r->capacity = t->capacity;
 
-  r->mapping = t->mapping;
+    r->mapping = t->mapping;
 
-  r->elements = (ContractionTable **)uprv_malloc(t->capacity*sizeof(ContractionTable *));
-  /* test for NULL */
-  if (r->elements == NULL) {
-    *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
-  }
-  //uprv_memcpy(r->elements, t->elements, t->capacity*sizeof(ContractionTable *));
+    r->elements = (ContractionTable **)uprv_malloc(t->capacity*sizeof(ContractionTable *));
+    /* test for NULL */
+    if (r->elements == NULL) {
+        goto outOfMemory;
+    }
+    //uprv_memcpy(r->elements, t->elements, t->capacity*sizeof(ContractionTable *));
 
-  for(i = 0; i<t->size; i++) {
-    r->elements[i] = uprv_cnttab_cloneContraction(t->elements[i], status);
-  }
+    for(i = 0; i<t->size; i++) {
+        r->elements[i] = uprv_cnttab_cloneContraction(t->elements[i], status);
+    }
 
-  if(t->CEs != NULL) {
-    r->CEs = (uint32_t *)uprv_malloc(t->position*sizeof(uint32_t));
-    /* test for NULL */
-    if (r->CEs == NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return NULL;
+    if(t->CEs != NULL) {
+        r->CEs = (uint32_t *)uprv_malloc(t->position*sizeof(uint32_t));
+        /* test for NULL */
+        if (r->CEs == NULL) {
+            uprv_free(r->elements);
+            goto outOfMemory;
+        }
+        uprv_memcpy(r->CEs, t->CEs, t->position*sizeof(uint32_t));
+    } else {
+        r->CEs = NULL;
     }
-    uprv_memcpy(r->CEs, t->CEs, t->position*sizeof(uint32_t));
-  } else {
-    r->CEs = NULL;
-  }
 
-  if(t->codePoints != NULL) {
-    r->codePoints = (UChar *)uprv_malloc(t->position*sizeof(UChar));
-    /* test for NULL */
-    if (r->codePoints == NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return NULL;
+    if(t->codePoints != NULL) {
+        r->codePoints = (UChar *)uprv_malloc(t->position*sizeof(UChar));
+        /* test for NULL */
+        if (r->codePoints == NULL) {
+            uprv_free(r->CEs);
+            uprv_free(r->elements);
+            goto outOfMemory;
+        }
+        uprv_memcpy(r->codePoints, t->codePoints, t->position*sizeof(UChar));
+    } else {
+        r->codePoints = NULL;
     }
-    uprv_memcpy(r->codePoints, t->codePoints, t->position*sizeof(UChar));
-  } else {
-    r->codePoints = NULL;
-  }
 
-  if(t->offsets != NULL) {
-    r->offsets = (int32_t *)uprv_malloc(t->size*sizeof(int32_t));
-    /* test for NULL */
-    if (r->offsets == NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return NULL;
+    if(t->offsets != NULL) {
+        r->offsets = (int32_t *)uprv_malloc(t->size*sizeof(int32_t));
+        /* test for NULL */
+        if (r->offsets == NULL) {
+            uprv_free(r->codePoints);
+            uprv_free(r->CEs);
+            uprv_free(r->elements);
+            goto outOfMemory;
+        }
+        uprv_memcpy(r->offsets, t->offsets, t->size*sizeof(int32_t));
+    } else {
+        r->offsets = NULL;
     }
-    uprv_memcpy(r->offsets, t->offsets, t->size*sizeof(int32_t));
-  } else {
-    r->offsets = NULL;
-  }
 
-  return r;
+    return r;
+
+outOfMemory:
+    *status = U_MEMORY_ALLOCATION_ERROR;
+    if (r) uprv_free(r);
+    return NULL;
 }
 
 U_CAPI void  U_EXPORT2
@@ -348,7 +357,7 @@ uprv_cnttab_changeLastCE(CntTable *table, uint32_t element, uint32_t value, UErr
     }
 
     if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
-      return 0;
+        return 0;
     }
 
     tbl->CEs[tbl->position-1] = value;
@@ -361,15 +370,18 @@ uprv_cnttab_changeLastCE(CntTable *table, uint32_t element, uint32_t value, UErr
 U_CAPI uint32_t  U_EXPORT2
 uprv_cnttab_insertContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t value, UErrorCode *status) {
 
-    element &= 0xFFFFFF;
     ContractionTable *tbl = NULL;
 
     if(U_FAILURE(*status)) {
         return 0;
     }
+    element &= 0xFFFFFF;
 
     if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
         tbl = addATableElement(table, &element, status);
+        if (U_FAILURE(*status)) {
+            return 0;
+        }
     }
 
     uprv_growTable(tbl, status);
@@ -410,6 +422,9 @@ uprv_cnttab_addContraction(CntTable *table, uint32_t element, UChar codePoint, u
 
     if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
         tbl = addATableElement(table, &element, status);
+        if (U_FAILURE(*status)) {
+            return 0;
+        }
     } 
 
     uprv_growTable(tbl, status);
@@ -435,6 +450,10 @@ uprv_cnttab_setContraction(CntTable *table, uint32_t element, uint32_t offset, U
 
     if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
         tbl = addATableElement(table, &element, status);
+        if (U_FAILURE(*status)) {
+            return 0;
+        }
+        
     }
 
     if(offset >= tbl->size) {
@@ -452,41 +471,40 @@ static ContractionTable *_cnttab_getContractionTable(CntTable *table, uint32_t e
     element &= 0xFFFFFF;
     ContractionTable *tbl = NULL;
 
-    if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
-      return NULL;
-    } else {
-      return tbl;
+    if(element != 0xFFFFFF) {
+        tbl = table->elements[element]; /* This could also return NULL */
     }
+    return tbl;
 }
 
 static int32_t _cnttab_findCP(ContractionTable *tbl, UChar codePoint) {
     uint32_t position = 0;
     if(tbl == NULL) {
-      return -1;
+        return -1;
     }
 
     while(codePoint > tbl->codePoints[position]) {
-      position++;
-      if(position > tbl->position) {
-        return -1;
-      }
+        position++;
+        if(position > tbl->position) {
+            return -1;
+        }
     }
     if (codePoint == tbl->codePoints[position]) {
-      return position;
+        return position;
     } else {
-      return -1;
+        return -1;
     }
 }
 
 static uint32_t _cnttab_getCE(ContractionTable *tbl, int32_t position) {
-  if(tbl == NULL) {
-    return UCOL_NOT_FOUND;
-  }
-  if((uint32_t)position > tbl->position || position == -1) {
-    return UCOL_NOT_FOUND;
-  } else {
-    return tbl->CEs[position];
-  }
+    if(tbl == NULL) {
+        return UCOL_NOT_FOUND;
+    }
+    if((uint32_t)position > tbl->position || position == -1) {
+        return UCOL_NOT_FOUND;
+    } else {
+        return tbl->CEs[position];
+    }
 }
 
 U_CAPI int32_t  U_EXPORT2
@@ -524,20 +542,16 @@ uprv_cnttab_isTailored(CntTable *table, uint32_t element, UChar *ztString, UErro
     }
 
     while(*(ztString)!=0) {
-      element = uprv_cnttab_findCE(table, element, *(ztString), status);
-      if(element == UCOL_NOT_FOUND) {
-        return FALSE;
-      }
-      if(!isCntTableElement(element)) {
-        return TRUE;
-      }
-      ztString++;
-    }
-    if(uprv_cnttab_getCE(table, element, 0, status) != UCOL_NOT_FOUND) {
-      return TRUE;
-    } else {
-      return FALSE; 
+        element = uprv_cnttab_findCE(table, element, *(ztString), status);
+        if(element == UCOL_NOT_FOUND) {
+            return FALSE;
+        }
+        if(!isCntTableElement(element)) {
+            return TRUE;
+        }
+        ztString++;
     }
+    return (UBool)(uprv_cnttab_getCE(table, element, 0, status) != UCOL_NOT_FOUND);
 }
 
 U_CAPI uint32_t  U_EXPORT2
@@ -551,25 +565,23 @@ uprv_cnttab_changeContraction(CntTable *table, uint32_t element, UChar codePoint
     }
 
     if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
-      return 0;
+        return 0;
     }
 
     uint32_t position = 0;
 
     while(codePoint > tbl->codePoints[position]) {
-      position++;
-      if(position > tbl->position) {
-        return UCOL_NOT_FOUND;
-      }
+        position++;
+        if(position > tbl->position) {
+            return UCOL_NOT_FOUND;
+        }
     }
     if (codePoint == tbl->codePoints[position]) {
-      tbl->CEs[position] = newCE;
-      return element;
+        tbl->CEs[position] = newCE;
+        return element;
     } else {
-      return UCOL_NOT_FOUND;
+        return UCOL_NOT_FOUND;
     }
 }
 
-U_NAMESPACE_END
-
 #endif /* #if !UCONFIG_NO_COLLATION */