Index: icu46/source/i18n/utrans.cpp |
=================================================================== |
--- icu46/source/i18n/utrans.cpp (revision 0) |
+++ icu46/source/i18n/utrans.cpp (revision 0) |
@@ -0,0 +1,495 @@ |
+/* |
+ ******************************************************************************* |
+ * Copyright (C) 1997-2009, International Business Machines |
+ * Corporation and others. All Rights Reserved. |
+ ******************************************************************************* |
+ * Date Name Description |
+ * 06/21/00 aliu Creation. |
+ ******************************************************************************* |
+ */ |
+ |
+#include "unicode/utypes.h" |
+ |
+#if !UCONFIG_NO_TRANSLITERATION |
+ |
+#include "unicode/utrans.h" |
+#include "unicode/putil.h" |
+#include "unicode/rep.h" |
+#include "unicode/translit.h" |
+#include "unicode/unifilt.h" |
+#include "unicode/uniset.h" |
+#include "unicode/ustring.h" |
+#include "unicode/uenum.h" |
+#include "uenumimp.h" |
+#include "cpputils.h" |
+#include "rbt.h" |
+ |
+// Following macro is to be followed by <return value>';' or just ';' |
+#define utrans_ENTRY(s) if ((s)==NULL || U_FAILURE(*(s))) return |
+ |
+/******************************************************************** |
+ * Replaceable-UReplaceableCallbacks glue |
+ ********************************************************************/ |
+ |
+/** |
+ * Make a UReplaceable + UReplaceableCallbacks into a Replaceable object. |
+ */ |
+U_NAMESPACE_BEGIN |
+class ReplaceableGlue : public Replaceable { |
+ |
+ UReplaceable *rep; |
+ UReplaceableCallbacks *func; |
+ |
+public: |
+ |
+ ReplaceableGlue(UReplaceable *replaceable, |
+ UReplaceableCallbacks *funcCallback); |
+ |
+ virtual ~ReplaceableGlue(); |
+ |
+ virtual void handleReplaceBetween(int32_t start, |
+ int32_t limit, |
+ const UnicodeString& text); |
+ |
+ virtual void extractBetween(int32_t start, |
+ int32_t limit, |
+ UnicodeString& target) const; |
+ |
+ virtual void copy(int32_t start, int32_t limit, int32_t dest); |
+ |
+ // virtual Replaceable *clone() const { return NULL; } same as default |
+ |
+ /** |
+ * ICU "poor man's RTTI", returns a UClassID for the actual class. |
+ * |
+ * @draft ICU 2.2 |
+ */ |
+ virtual UClassID getDynamicClassID() const; |
+ |
+ /** |
+ * ICU "poor man's RTTI", returns a UClassID for this class. |
+ * |
+ * @draft ICU 2.2 |
+ */ |
+ static UClassID U_EXPORT2 getStaticClassID(); |
+ |
+protected: |
+ |
+ virtual int32_t getLength() const; |
+ |
+ virtual UChar getCharAt(int32_t offset) const; |
+ |
+ virtual UChar32 getChar32At(int32_t offset) const; |
+}; |
+ |
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ReplaceableGlue) |
+ |
+ReplaceableGlue::ReplaceableGlue(UReplaceable *replaceable, |
+ UReplaceableCallbacks *funcCallback) |
+ : Replaceable() |
+{ |
+ this->rep = replaceable; |
+ this->func = funcCallback; |
+} |
+ |
+ReplaceableGlue::~ReplaceableGlue() {} |
+ |
+int32_t ReplaceableGlue::getLength() const { |
+ return (*func->length)(rep); |
+} |
+ |
+UChar ReplaceableGlue::getCharAt(int32_t offset) const { |
+ return (*func->charAt)(rep, offset); |
+} |
+ |
+UChar32 ReplaceableGlue::getChar32At(int32_t offset) const { |
+ return (*func->char32At)(rep, offset); |
+} |
+ |
+void ReplaceableGlue::handleReplaceBetween(int32_t start, |
+ int32_t limit, |
+ const UnicodeString& text) { |
+ (*func->replace)(rep, start, limit, text.getBuffer(), text.length()); |
+} |
+ |
+void ReplaceableGlue::extractBetween(int32_t start, |
+ int32_t limit, |
+ UnicodeString& target) const { |
+ (*func->extract)(rep, start, limit, target.getBuffer(limit-start)); |
+ target.releaseBuffer(limit-start); |
+} |
+ |
+void ReplaceableGlue::copy(int32_t start, int32_t limit, int32_t dest) { |
+ (*func->copy)(rep, start, limit, dest); |
+} |
+U_NAMESPACE_END |
+/******************************************************************** |
+ * General API |
+ ********************************************************************/ |
+U_NAMESPACE_USE |
+ |
+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; |
+ } |
+ if (id == NULL) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return NULL; |
+ } |
+ UParseError temp; |
+ |
+ if(parseError == NULL){ |
+ parseError = &temp; |
+ } |
+ |
+ UnicodeString ID(idLength<0, id, idLength); // r-o alias |
+ |
+ if(rules==NULL){ |
+ |
+ Transliterator *trans = NULL; |
+ |
+ trans = Transliterator::createInstance(ID, dir, *parseError, *status); |
+ |
+ if(U_FAILURE(*status)){ |
+ return NULL; |
+ } |
+ return (UTransliterator*) trans; |
+ }else{ |
+ UnicodeString ruleStr(rulesLength < 0, |
+ rules, |
+ rulesLength); // r-o alias |
+ |
+ 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) { |
+ |
+ utrans_ENTRY(status) NULL; |
+ |
+ UTransliterator* result = |
+ (UTransliterator*) ((Transliterator*) trans)->createInverse(*status); |
+ |
+ return result; |
+} |
+ |
+U_CAPI UTransliterator* U_EXPORT2 |
+utrans_clone(const UTransliterator* trans, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status) NULL; |
+ |
+ if (trans == NULL) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return NULL; |
+ } |
+ |
+ Transliterator *t = ((Transliterator*) trans)->clone(); |
+ if (t == NULL) { |
+ *status = U_MEMORY_ALLOCATION_ERROR; |
+ } |
+ return (UTransliterator*) t; |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+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, US_INV); |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_register(UTransliterator* adoptedTrans, |
+ UErrorCode* status) { |
+ utrans_ENTRY(status); |
+ // status currently ignored; may remove later |
+ 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, -1, US_INV); // use invariant converter |
+ Transliterator::unregister(ID); |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_setFilter(UTransliterator* trans, |
+ const UChar* filterPattern, |
+ int32_t filterPatternLen, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status); |
+ UnicodeFilter* filter = NULL; |
+ if (filterPattern != NULL && *filterPattern != 0) { |
+ // Create read only alias of filterPattern: |
+ UnicodeString pat(filterPatternLen < 0, filterPattern, filterPatternLen); |
+ filter = new UnicodeSet(pat, *status); |
+ /* test for NULL */ |
+ if (filter == NULL) { |
+ *status = U_MEMORY_ALLOCATION_ERROR; |
+ return; |
+ } |
+ if (U_FAILURE(*status)) { |
+ delete filter; |
+ filter = NULL; |
+ } |
+ } |
+ ((Transliterator*) trans)->adoptFilter(filter); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+utrans_countAvailableIDs(void) { |
+ return Transliterator::countAvailableIDs(); |
+} |
+ |
+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, 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; |
+} |
+ |
+/******************************************************************** |
+ * Transliteration API |
+ ********************************************************************/ |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_trans(const UTransliterator* trans, |
+ UReplaceable* rep, |
+ UReplaceableCallbacks* repFunc, |
+ int32_t start, |
+ int32_t* limit, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status); |
+ |
+ if (trans == 0 || rep == 0 || repFunc == 0 || limit == 0) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return; |
+ } |
+ |
+ ReplaceableGlue r(rep, repFunc); |
+ |
+ *limit = ((Transliterator*) trans)->transliterate(r, start, *limit); |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_transIncremental(const UTransliterator* trans, |
+ UReplaceable* rep, |
+ UReplaceableCallbacks* repFunc, |
+ UTransPosition* pos, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status); |
+ |
+ if (trans == 0 || rep == 0 || repFunc == 0 || pos == 0) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return; |
+ } |
+ |
+ ReplaceableGlue r(rep, repFunc); |
+ |
+ ((Transliterator*) trans)->transliterate(r, *pos, *status); |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_transUChars(const UTransliterator* trans, |
+ UChar* text, |
+ int32_t* textLength, |
+ int32_t textCapacity, |
+ int32_t start, |
+ int32_t* limit, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status); |
+ |
+ if (trans == 0 || text == 0 || limit == 0) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return; |
+ } |
+ |
+ int32_t textLen = (textLength == NULL || *textLength < 0) |
+ ? u_strlen(text) : *textLength; |
+ // writeable alias: for this ct, len CANNOT be -1 (why?) |
+ UnicodeString str(text, textLen, textCapacity); |
+ |
+ *limit = ((Transliterator*) trans)->transliterate(str, start, *limit); |
+ |
+ // Copy the string buffer back to text (only if necessary) |
+ // and fill in *neededCapacity (if neededCapacity != NULL). |
+ textLen = str.extract(text, textCapacity, *status); |
+ if(textLength != NULL) { |
+ *textLength = textLen; |
+ } |
+} |
+ |
+U_CAPI void U_EXPORT2 |
+utrans_transIncrementalUChars(const UTransliterator* trans, |
+ UChar* text, |
+ int32_t* textLength, |
+ int32_t textCapacity, |
+ UTransPosition* pos, |
+ UErrorCode* status) { |
+ |
+ utrans_ENTRY(status); |
+ |
+ if (trans == 0 || text == 0 || pos == 0) { |
+ *status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return; |
+ } |
+ |
+ int32_t textLen = (textLength == NULL || *textLength < 0) |
+ ? u_strlen(text) : *textLength; |
+ // writeable alias: for this ct, len CANNOT be -1 (why?) |
+ UnicodeString str(text, textLen, textCapacity); |
+ |
+ ((Transliterator*) trans)->transliterate(str, *pos, *status); |
+ |
+ // Copy the string buffer back to text (only if necessary) |
+ // and fill in *neededCapacity (if neededCapacity != NULL). |
+ textLen = str.extract(text, textCapacity, *status); |
+ if(textLength != NULL) { |
+ *textLength = textLen; |
+ } |
+} |
+ |
+#endif /* #if !UCONFIG_NO_TRANSLITERATION */ |
Property changes on: icu46/source/i18n/utrans.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |