Update header about CQL grammar
[yaz-moved-to-github.git] / src / icu_casemap.c
index d0a7051..f06f64e 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2010 Index Data
+ * Copyright (C) 1995-2013 Index Data
  * See the file LICENSE for details.
  */
 
@@ -30,22 +30,22 @@ struct icu_casemap
     char action;
 };
 
-struct icu_casemap * icu_casemap_create(char action, UErrorCode *status)
-{    
-    struct icu_casemap * casemap
+struct icu_casemap *icu_casemap_create(char action, UErrorCode *status)
+{
+    struct icu_casemap *casemap
         = (struct icu_casemap *) xmalloc(sizeof(struct icu_casemap));
     casemap->action = action;
 
     switch (casemap->action)
     {
-    case 'l':   
-    case 'L':   
-    case 'u':   
-    case 'U':   
-    case 't':  
-    case 'T':  
-    case 'f':  
-    case 'F':  
+    case 'l':
+    case 'L':
+    case 'u':
+    case 'U':
+    case 't':
+    case 'T':
+    case 'f':
+    case 'F':
         break;
     default:
         icu_casemap_destroy(casemap);
@@ -54,26 +54,73 @@ struct icu_casemap * icu_casemap_create(char action, UErrorCode *status)
     return casemap;
 }
 
+struct icu_casemap *icu_casemap_clone(struct icu_casemap *old)
+{
+    struct icu_casemap * casemap
+        = (struct icu_casemap *) xmalloc(sizeof(struct icu_casemap));
+    casemap->action = old->action;
+    return casemap;
+}
+
 void icu_casemap_destroy(struct icu_casemap * casemap)
 {
     xfree(casemap);
 }
 
-int icu_casemap_casemap(struct icu_casemap * casemap,
-                        struct icu_buf_utf16 * dest16,
-                        struct icu_buf_utf16 * src16,
+int icu_casemap_casemap(struct icu_casemap *casemap,
+                        struct icu_buf_utf16 *dest16,
+                        struct icu_buf_utf16 *src16,
                         UErrorCode *status,
                         const char *locale)
 {
-    if(!casemap)
+    if (!casemap)
         return 0;
-    
+
     return icu_utf16_casemap(dest16, src16, locale,
                              casemap->action, status);
 }
 
-int icu_utf16_casemap(struct icu_buf_utf16 * dest16,
-                      struct icu_buf_utf16 * src16,
+
+static uint32_t icu_utf16_sub(struct icu_buf_utf16 *dest16,
+                          struct icu_buf_utf16 *src16,
+                          const char *locale, char action,
+                          UErrorCode *status)
+{
+    switch (action)
+    {
+    case 'l':
+    case 'L':
+        return u_strToLower(dest16->utf16, dest16->utf16_cap,
+                            src16->utf16, src16->utf16_len,
+                            locale, status);
+    case 'u':
+    case 'U':
+        return u_strToUpper(dest16->utf16, dest16->utf16_cap,
+                            src16->utf16, src16->utf16_len,
+                            locale, status);
+        break;
+    case 't':
+    case 'T':
+        return u_strToTitle(dest16->utf16, dest16->utf16_cap,
+                            src16->utf16, src16->utf16_len,
+                            0, locale, status);
+        break;
+    case 'f':
+    case 'F':
+        return u_strFoldCase(dest16->utf16, dest16->utf16_cap,
+                             src16->utf16, src16->utf16_len,
+                             U_FOLD_CASE_DEFAULT, status);
+        break;
+    default:
+        *status = U_UNSUPPORTED_ERROR;
+        break;
+    }
+    return 0;
+}
+
+
+int icu_utf16_casemap(struct icu_buf_utf16 *dest16,
+                      struct icu_buf_utf16 *src16,
                       const char *locale, char action,
                       UErrorCode *status)
 {
@@ -86,81 +133,20 @@ int icu_utf16_casemap(struct icu_buf_utf16 * dest16,
         dest16->utf16_len = 0;
         return U_ZERO_ERROR;
     }
-    
-    switch (action)
-    {
-    case 'l':    
-    case 'L':    
-        dest16_len = u_strToLower(dest16->utf16, dest16->utf16_cap,
-                                  src16->utf16, src16->utf16_len, 
-                                  locale, status);
-        break;
-    case 'u':    
-    case 'U':    
-        dest16_len = u_strToUpper(dest16->utf16, dest16->utf16_cap,
-                                  src16->utf16, src16->utf16_len, 
-                                  locale, status);
-        break;
-    case 't':    
-    case 'T':    
-        dest16_len = u_strToTitle(dest16->utf16, dest16->utf16_cap,
-                                  src16->utf16, src16->utf16_len,
-                                  0, locale, status);
-        break;
-    case 'f':    
-    case 'F':    
-        dest16_len = u_strFoldCase(dest16->utf16, dest16->utf16_cap,
-                                   src16->utf16, src16->utf16_len,
-                                   U_FOLD_CASE_DEFAULT, status);
-        break;
-        
-    default:
-        return U_UNSUPPORTED_ERROR;
-        break;
-    }
+
+    dest16_len = icu_utf16_sub(dest16, src16, locale, action, status);
 
     /* check for buffer overflow, resize and retry */
     if (*status == U_BUFFER_OVERFLOW_ERROR
-        && dest16 != src16        /* do not resize if in-place conversion */
-        )
+        && dest16 != src16)      /* do not resize if in-place conversion */
     {
         icu_buf_utf16_resize(dest16, dest16_len * 2);
         *status = U_ZERO_ERROR;
 
-        switch (action) {    
-        case 'l':    
-        case 'L':    
-            dest16_len = u_strToLower(dest16->utf16, dest16->utf16_cap,
-                                      src16->utf16, src16->utf16_len, 
-                                      locale, status);
-            break;
-        case 'u':    
-        case 'U':    
-            dest16_len = u_strToUpper(dest16->utf16, dest16->utf16_cap,
-                                      src16->utf16, src16->utf16_len, 
-                                      locale, status);
-            break;
-        case 't':    
-        case 'T':    
-            dest16_len = u_strToTitle(dest16->utf16, dest16->utf16_cap,
-                                      src16->utf16, src16->utf16_len,
-                                      0, locale, status);
-            break;
-        case 'f':    
-        case 'F':    
-            dest16_len = u_strFoldCase(dest16->utf16, dest16->utf16_cap,
-                                       src16->utf16, src16->utf16_len,
-                                       U_FOLD_CASE_DEFAULT, status);
-            break;
-        
-        default:
-            return U_UNSUPPORTED_ERROR;
-            break;
-        }
+        icu_utf16_sub(dest16, src16, locale, action, status);
     }
-    
-    if (U_SUCCESS(*status)
-        && dest16_len <= dest16->utf16_cap)
+
+    if (U_SUCCESS(*status) && dest16_len <= dest16->utf16_cap)
         dest16->utf16_len = dest16_len;
     else
     {
@@ -168,7 +154,7 @@ int icu_utf16_casemap(struct icu_buf_utf16 * dest16,
             dest16->utf16[0] = (UChar) 0;
         dest16->utf16_len = 0;
     }
-  
+
     return *status;
 }