]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/utrans.cpp
ICU-531.48.tar.gz
[apple/icu.git] / icuSources / i18n / utrans.cpp
index ff1a3637067377a4bb56a47a48c6200fa991c61e..f4f86d521c05f4f6d1d0499b23982bfa19e2cbcb 100644 (file)
@@ -1,12 +1,12 @@
 /*
-*******************************************************************************
-*   Copyright (C) 1997-2003, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*******************************************************************************
-*   Date        Name        Description
-*   06/21/00    aliu        Creation.
-*******************************************************************************
-*/
+ *******************************************************************************
+ *   Copyright (C) 1997-2009,2014 International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ *******************************************************************************
+ *   Date        Name        Description
+ *   06/21/00    aliu        Creation.
+ *******************************************************************************
+ */
 
 #include "unicode/utypes.h"
 
@@ -19,6 +19,9 @@
 #include "unicode/unifilt.h"
 #include "unicode/uniset.h"
 #include "unicode/ustring.h"
+#include "unicode/uenum.h"
+#include "unicode/uset.h"
+#include "uenumimp.h"
 #include "cpputils.h"
 #include "rbt.h"
 
@@ -38,12 +41,6 @@ class ReplaceableGlue : public Replaceable {
     UReplaceable *rep;
     UReplaceableCallbacks *func;
 
-    /**
-     * The address of this static class variable serves as this class's ID
-     * for ICU "poor man's RTTI".
-     */
-    static const char fgClassID;
-
 public:
 
     ReplaceableGlue(UReplaceable *replaceable,
@@ -68,14 +65,14 @@ public:
      *
      * @draft ICU 2.2
      */
-    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
+    virtual UClassID getDynamicClassID() const;
 
     /**
      * ICU "poor man's RTTI", returns a UClassID for this class.
      *
      * @draft ICU 2.2
      */
-    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
+    static UClassID U_EXPORT2 getStaticClassID();
 
 protected:
 
@@ -86,8 +83,7 @@ protected:
     virtual UChar32 getChar32At(int32_t offset) const;
 };
 
-
-const char ReplaceableGlue::fgClassID=0;
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ReplaceableGlue)
 
 ReplaceableGlue::ReplaceableGlue(UReplaceable *replaceable,
                                  UReplaceableCallbacks *funcCallback)
@@ -132,84 +128,18 @@ U_NAMESPACE_END
  * General API
  ********************************************************************/
 U_NAMESPACE_USE
-#if 0
-
-U_CAPI UTransliterator*
-utrans_open(const char* id,
-            UTransDirection dir,
-            UParseError* parseError,
-            UErrorCode* status) {
-
-    utrans_ENTRY(status) NULL;
-
-    if (id == NULL) {
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
-        return NULL;
-    }
-
-    UnicodeString ID(id, ""); // use invariant converter
-    Transliterator *trans = NULL;
-
-    trans = Transliterator::createInstance(ID, dir, *parseError, *status);
-
-    if (trans == NULL) {
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
-    }
-    return (UTransliterator*) trans;
-}
-
-U_CAPI UTransliterator*
-utrans_openRules(const char* id,
-                 const UChar* rules,
-                 int32_t rulesLength, /* -1 if null-terminated */
-                 UTransDirection dir,
-                 UParseError* parseErr, /* may be NULL */
-                 UErrorCode* status) {
 
-    utrans_ENTRY(status) NULL;
-
-    if (id == NULL || rules == NULL) {
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
+U_CAPI UTransliterator* U_EXPORT2
+utrans_openU(const UChar *id,
+             int32_t idLength,
+             UTransDirection dir,
+             const UChar *rules,
+             int32_t rulesLength,
+             UParseError *parseError,
+             UErrorCode *status) {
+    if(status==NULL || U_FAILURE(*status)) {
         return NULL;
     }
-
-    UnicodeString ID(id, ""); // use invariant converter
-    UnicodeString ruleStr(rulesLength < 0,
-                          rules,
-                          rulesLength); // r-o alias
-
-    RuleBasedTransliterator *trans = NULL;
-
-    // Use if() to avoid construction of ParseError object on stack
-    // unless it is called for by user.
-    if (parseErr != NULL) {
-        trans = new RuleBasedTransliterator(ID, ruleStr, dir,
-                                            NULL, *parseErr, *status);
-    } else {
-        trans = new RuleBasedTransliterator(ID, ruleStr, dir,
-                                            NULL, *status);
-    }
-
-    if (trans == NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-    } else if (U_FAILURE(*status)) {
-        delete trans;
-        trans = NULL;
-    }
-    return (UTransliterator*) trans;
-}
-#endif
-
-U_CAPI UTransliterator* U_EXPORT2
-utrans_open(const char* id,
-            UTransDirection dir,
-            const UChar* rules,         /* may be Null */
-            int32_t rulesLength,        /* -1 if null-terminated */ 
-            UParseError* parseError,    /* may be Null */
-            UErrorCode* status) {
-
-    utrans_ENTRY(status) NULL;
-
     if (id == NULL) {
         *status = U_ILLEGAL_ARGUMENT_ERROR;
         return NULL;
@@ -220,7 +150,7 @@ utrans_open(const char* id,
         parseError = &temp;
     }
     
-    UnicodeString ID(id, ""); // use invariant converter
+    UnicodeString ID(idLength<0, id, idLength); // r-o alias
 
     if(rules==NULL){
 
@@ -237,19 +167,29 @@ utrans_open(const char* id,
                               rules,
                               rulesLength); // r-o alias
 
-        RuleBasedTransliterator *trans = NULL;
-        trans = new RuleBasedTransliterator(ID, ruleStr, dir,
-                                            NULL, *parseError, *status);
-        if (trans == NULL) {
-            *status = U_MEMORY_ALLOCATION_ERROR;
-        } else if (U_FAILURE(*status)) {
-            delete trans;
-            trans = NULL;
+        Transliterator *trans = NULL;
+        trans = Transliterator::createFromRules(ID, ruleStr, dir, *parseError, *status); 
+        if(U_FAILURE(*status)) { 
+            return NULL;
         }
+
         return (UTransliterator*) trans;
     }
 }
 
+U_CAPI UTransliterator* U_EXPORT2
+utrans_open(const char* id,
+            UTransDirection dir,
+            const UChar* rules,         /* may be Null */
+            int32_t rulesLength,        /* -1 if null-terminated */ 
+            UParseError* parseError,    /* may be Null */
+            UErrorCode* status) {
+    UnicodeString ID(id, -1, US_INV); // use invariant converter
+    return utrans_openU(ID.getBuffer(), ID.length(), dir,
+                        rules, rulesLength,
+                        parseError, status);
+}
+
 U_CAPI UTransliterator* U_EXPORT2
 utrans_openInverse(const UTransliterator* trans,
                    UErrorCode* status) {
@@ -285,11 +225,22 @@ utrans_close(UTransliterator* trans) {
     delete (Transliterator*) trans;
 }
 
+U_CAPI const UChar * U_EXPORT2
+utrans_getUnicodeID(const UTransliterator *trans,
+                    int32_t *resultLength) {
+    // Transliterator keeps its ID NUL-terminated
+    const UnicodeString &ID=((Transliterator*) trans)->getID();
+    if(resultLength!=NULL) {
+        *resultLength=ID.length();
+    }
+    return ID.getBuffer();
+}
+
 U_CAPI int32_t U_EXPORT2
 utrans_getID(const UTransliterator* trans,
              char* buf,
              int32_t bufCapacity) {
-    return ((Transliterator*) trans)->getID().extract(0, 0x7fffffff, buf, bufCapacity, "");
+    return ((Transliterator*) trans)->getID().extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
 }
 
 U_CAPI void U_EXPORT2
@@ -300,9 +251,15 @@ utrans_register(UTransliterator* adoptedTrans,
     Transliterator::registerInstance((Transliterator*) adoptedTrans);
 }
 
+U_CAPI void U_EXPORT2
+utrans_unregisterID(const UChar* id, int32_t idLength) {
+    UnicodeString ID(idLength<0, id, idLength); // r-o alias
+    Transliterator::unregister(ID);
+}
+
 U_CAPI void U_EXPORT2
 utrans_unregister(const char* id) {
-    UnicodeString ID(id, ""); // use invariant converter
+    UnicodeString ID(id, -1, US_INV); // use invariant converter
     Transliterator::unregister(ID);
 }
 
@@ -340,7 +297,96 @@ U_CAPI int32_t U_EXPORT2
 utrans_getAvailableID(int32_t index,
                       char* buf, // may be NULL
                       int32_t bufCapacity) {
-    return Transliterator::getAvailableID(index).extract(0, 0x7fffffff, buf, bufCapacity, "");
+    return Transliterator::getAvailableID(index).extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
+}
+
+/* Transliterator UEnumeration ---------------------------------------------- */
+
+typedef struct UTransEnumeration {
+    UEnumeration uenum;
+    int32_t index, count;
+} UTransEnumeration;
+
+U_CDECL_BEGIN
+static int32_t U_CALLCONV
+utrans_enum_count(UEnumeration *uenum, UErrorCode *pErrorCode) {
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    return ((UTransEnumeration *)uenum)->count;
+}
+
+static const UChar* U_CALLCONV
+utrans_enum_unext(UEnumeration *uenum,
+                  int32_t* resultLength,
+                  UErrorCode *pErrorCode) {
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    UTransEnumeration *ute=(UTransEnumeration *)uenum;
+    int32_t index=ute->index;
+    if(index<ute->count) {
+        const UnicodeString &ID=Transliterator::getAvailableID(index);
+        ute->index=index+1;
+        if(resultLength!=NULL) {
+            *resultLength=ID.length();
+        }
+        // Transliterator keeps its ID NUL-terminated
+        return ID.getBuffer();
+    }
+
+    if(resultLength!=NULL) {
+        *resultLength=0;
+    }
+    return NULL;
+}
+
+static void U_CALLCONV
+utrans_enum_reset(UEnumeration *uenum, UErrorCode *pErrorCode) {
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    UTransEnumeration *ute=(UTransEnumeration *)uenum;
+    ute->index=0;
+    ute->count=Transliterator::countAvailableIDs();
+}
+
+static void U_CALLCONV
+utrans_enum_close(UEnumeration *uenum) {
+    uprv_free(uenum);
+}
+U_CDECL_END
+
+static const UEnumeration utransEnumeration={
+    NULL,
+    NULL,
+    utrans_enum_close,
+    utrans_enum_count,
+    utrans_enum_unext,
+    uenum_nextDefault,
+    utrans_enum_reset
+};
+
+U_CAPI UEnumeration * U_EXPORT2
+utrans_openIDs(UErrorCode *pErrorCode) {
+    UTransEnumeration *ute;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    ute=(UTransEnumeration *)uprv_malloc(sizeof(UTransEnumeration));
+    if(ute==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+
+    ute->uenum=utransEnumeration;
+    ute->index=0;
+    ute->count=Transliterator::countAvailableIDs();
+    return (UEnumeration *)ute;
 }
 
 /********************************************************************
@@ -447,4 +493,39 @@ utrans_transIncrementalUChars(const UTransliterator* trans,
     }
 }
 
+U_CAPI int32_t U_EXPORT2
+utrans_toRules(     const UTransliterator* trans,
+                    UBool escapeUnprintable,
+                    UChar* result, int32_t resultLength,
+                    UErrorCode* status) {
+    utrans_ENTRY(status) 0;
+    if ( (result==NULL)? resultLength!=0: resultLength<0 ) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    UnicodeString res;
+    res.setTo(result, 0, resultLength);
+    ((Transliterator*) trans)->toRules(res, escapeUnprintable);
+    return res.extract(result, resultLength, *status);
+}
+
+U_CAPI USet* U_EXPORT2
+utrans_getSourceSet(const UTransliterator* trans,
+                    UBool ignoreFilter,
+                    USet* fillIn,
+                    UErrorCode* status) {
+    utrans_ENTRY(status) fillIn;
+
+    if (fillIn == NULL) {
+        fillIn = uset_openEmpty();
+    }
+    if (ignoreFilter) {
+        ((Transliterator*) trans)->handleGetSourceSet(*((UnicodeSet*)fillIn));
+    } else {
+        ((Transliterator*) trans)->getSourceSet(*((UnicodeSet*)fillIn));
+    }
+    return fillIn;
+}
+
 #endif /* #if !UCONFIG_NO_TRANSLITERATION */