PageRenderTime 90ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/external/icu4c/i18n/utrans.cpp

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
C++ | 495 lines | 355 code | 95 blank | 45 comment | 71 complexity | da9f7c74fc68fe0d02fc6eff9552771b MD5 | raw file
  1. /*
  2. *******************************************************************************
  3. * Copyright (C) 1997-2009, International Business Machines
  4. * Corporation and others. All Rights Reserved.
  5. *******************************************************************************
  6. * Date Name Description
  7. * 06/21/00 aliu Creation.
  8. *******************************************************************************
  9. */
  10. #include "unicode/utypes.h"
  11. #if !UCONFIG_NO_TRANSLITERATION
  12. #include "unicode/utrans.h"
  13. #include "unicode/putil.h"
  14. #include "unicode/rep.h"
  15. #include "unicode/translit.h"
  16. #include "unicode/unifilt.h"
  17. #include "unicode/uniset.h"
  18. #include "unicode/ustring.h"
  19. #include "unicode/uenum.h"
  20. #include "uenumimp.h"
  21. #include "cpputils.h"
  22. #include "rbt.h"
  23. // Following macro is to be followed by <return value>';' or just ';'
  24. #define utrans_ENTRY(s) if ((s)==NULL || U_FAILURE(*(s))) return
  25. /********************************************************************
  26. * Replaceable-UReplaceableCallbacks glue
  27. ********************************************************************/
  28. /**
  29. * Make a UReplaceable + UReplaceableCallbacks into a Replaceable object.
  30. */
  31. U_NAMESPACE_BEGIN
  32. class ReplaceableGlue : public Replaceable {
  33. UReplaceable *rep;
  34. UReplaceableCallbacks *func;
  35. public:
  36. ReplaceableGlue(UReplaceable *replaceable,
  37. UReplaceableCallbacks *funcCallback);
  38. virtual ~ReplaceableGlue();
  39. virtual void handleReplaceBetween(int32_t start,
  40. int32_t limit,
  41. const UnicodeString& text);
  42. virtual void extractBetween(int32_t start,
  43. int32_t limit,
  44. UnicodeString& target) const;
  45. virtual void copy(int32_t start, int32_t limit, int32_t dest);
  46. // virtual Replaceable *clone() const { return NULL; } same as default
  47. /**
  48. * ICU "poor man's RTTI", returns a UClassID for the actual class.
  49. *
  50. * @draft ICU 2.2
  51. */
  52. virtual UClassID getDynamicClassID() const;
  53. /**
  54. * ICU "poor man's RTTI", returns a UClassID for this class.
  55. *
  56. * @draft ICU 2.2
  57. */
  58. static UClassID U_EXPORT2 getStaticClassID();
  59. protected:
  60. virtual int32_t getLength() const;
  61. virtual UChar getCharAt(int32_t offset) const;
  62. virtual UChar32 getChar32At(int32_t offset) const;
  63. };
  64. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ReplaceableGlue)
  65. ReplaceableGlue::ReplaceableGlue(UReplaceable *replaceable,
  66. UReplaceableCallbacks *funcCallback)
  67. : Replaceable()
  68. {
  69. this->rep = replaceable;
  70. this->func = funcCallback;
  71. }
  72. ReplaceableGlue::~ReplaceableGlue() {}
  73. int32_t ReplaceableGlue::getLength() const {
  74. return (*func->length)(rep);
  75. }
  76. UChar ReplaceableGlue::getCharAt(int32_t offset) const {
  77. return (*func->charAt)(rep, offset);
  78. }
  79. UChar32 ReplaceableGlue::getChar32At(int32_t offset) const {
  80. return (*func->char32At)(rep, offset);
  81. }
  82. void ReplaceableGlue::handleReplaceBetween(int32_t start,
  83. int32_t limit,
  84. const UnicodeString& text) {
  85. (*func->replace)(rep, start, limit, text.getBuffer(), text.length());
  86. }
  87. void ReplaceableGlue::extractBetween(int32_t start,
  88. int32_t limit,
  89. UnicodeString& target) const {
  90. (*func->extract)(rep, start, limit, target.getBuffer(limit-start));
  91. target.releaseBuffer(limit-start);
  92. }
  93. void ReplaceableGlue::copy(int32_t start, int32_t limit, int32_t dest) {
  94. (*func->copy)(rep, start, limit, dest);
  95. }
  96. U_NAMESPACE_END
  97. /********************************************************************
  98. * General API
  99. ********************************************************************/
  100. U_NAMESPACE_USE
  101. U_CAPI UTransliterator* U_EXPORT2
  102. utrans_openU(const UChar *id,
  103. int32_t idLength,
  104. UTransDirection dir,
  105. const UChar *rules,
  106. int32_t rulesLength,
  107. UParseError *parseError,
  108. UErrorCode *status) {
  109. if(status==NULL || U_FAILURE(*status)) {
  110. return NULL;
  111. }
  112. if (id == NULL) {
  113. *status = U_ILLEGAL_ARGUMENT_ERROR;
  114. return NULL;
  115. }
  116. UParseError temp;
  117. if(parseError == NULL){
  118. parseError = &temp;
  119. }
  120. UnicodeString ID(idLength<0, id, idLength); // r-o alias
  121. if(rules==NULL){
  122. Transliterator *trans = NULL;
  123. trans = Transliterator::createInstance(ID, dir, *parseError, *status);
  124. if(U_FAILURE(*status)){
  125. return NULL;
  126. }
  127. return (UTransliterator*) trans;
  128. }else{
  129. UnicodeString ruleStr(rulesLength < 0,
  130. rules,
  131. rulesLength); // r-o alias
  132. Transliterator *trans = NULL;
  133. trans = Transliterator::createFromRules(ID, ruleStr, dir, *parseError, *status);
  134. if(U_FAILURE(*status)) {
  135. return NULL;
  136. }
  137. return (UTransliterator*) trans;
  138. }
  139. }
  140. U_CAPI UTransliterator* U_EXPORT2
  141. utrans_open(const char* id,
  142. UTransDirection dir,
  143. const UChar* rules, /* may be Null */
  144. int32_t rulesLength, /* -1 if null-terminated */
  145. UParseError* parseError, /* may be Null */
  146. UErrorCode* status) {
  147. UnicodeString ID(id, -1, US_INV); // use invariant converter
  148. return utrans_openU(ID.getBuffer(), ID.length(), dir,
  149. rules, rulesLength,
  150. parseError, status);
  151. }
  152. U_CAPI UTransliterator* U_EXPORT2
  153. utrans_openInverse(const UTransliterator* trans,
  154. UErrorCode* status) {
  155. utrans_ENTRY(status) NULL;
  156. UTransliterator* result =
  157. (UTransliterator*) ((Transliterator*) trans)->createInverse(*status);
  158. return result;
  159. }
  160. U_CAPI UTransliterator* U_EXPORT2
  161. utrans_clone(const UTransliterator* trans,
  162. UErrorCode* status) {
  163. utrans_ENTRY(status) NULL;
  164. if (trans == NULL) {
  165. *status = U_ILLEGAL_ARGUMENT_ERROR;
  166. return NULL;
  167. }
  168. Transliterator *t = ((Transliterator*) trans)->clone();
  169. if (t == NULL) {
  170. *status = U_MEMORY_ALLOCATION_ERROR;
  171. }
  172. return (UTransliterator*) t;
  173. }
  174. U_CAPI void U_EXPORT2
  175. utrans_close(UTransliterator* trans) {
  176. delete (Transliterator*) trans;
  177. }
  178. U_CAPI const UChar * U_EXPORT2
  179. utrans_getUnicodeID(const UTransliterator *trans,
  180. int32_t *resultLength) {
  181. // Transliterator keeps its ID NUL-terminated
  182. const UnicodeString &ID=((Transliterator*) trans)->getID();
  183. if(resultLength!=NULL) {
  184. *resultLength=ID.length();
  185. }
  186. return ID.getBuffer();
  187. }
  188. U_CAPI int32_t U_EXPORT2
  189. utrans_getID(const UTransliterator* trans,
  190. char* buf,
  191. int32_t bufCapacity) {
  192. return ((Transliterator*) trans)->getID().extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
  193. }
  194. U_CAPI void U_EXPORT2
  195. utrans_register(UTransliterator* adoptedTrans,
  196. UErrorCode* status) {
  197. utrans_ENTRY(status);
  198. // status currently ignored; may remove later
  199. Transliterator::registerInstance((Transliterator*) adoptedTrans);
  200. }
  201. U_CAPI void U_EXPORT2
  202. utrans_unregisterID(const UChar* id, int32_t idLength) {
  203. UnicodeString ID(idLength<0, id, idLength); // r-o alias
  204. Transliterator::unregister(ID);
  205. }
  206. U_CAPI void U_EXPORT2
  207. utrans_unregister(const char* id) {
  208. UnicodeString ID(id, -1, US_INV); // use invariant converter
  209. Transliterator::unregister(ID);
  210. }
  211. U_CAPI void U_EXPORT2
  212. utrans_setFilter(UTransliterator* trans,
  213. const UChar* filterPattern,
  214. int32_t filterPatternLen,
  215. UErrorCode* status) {
  216. utrans_ENTRY(status);
  217. UnicodeFilter* filter = NULL;
  218. if (filterPattern != NULL && *filterPattern != 0) {
  219. // Create read only alias of filterPattern:
  220. UnicodeString pat(filterPatternLen < 0, filterPattern, filterPatternLen);
  221. filter = new UnicodeSet(pat, *status);
  222. /* test for NULL */
  223. if (filter == NULL) {
  224. *status = U_MEMORY_ALLOCATION_ERROR;
  225. return;
  226. }
  227. if (U_FAILURE(*status)) {
  228. delete filter;
  229. filter = NULL;
  230. }
  231. }
  232. ((Transliterator*) trans)->adoptFilter(filter);
  233. }
  234. U_CAPI int32_t U_EXPORT2
  235. utrans_countAvailableIDs(void) {
  236. return Transliterator::countAvailableIDs();
  237. }
  238. U_CAPI int32_t U_EXPORT2
  239. utrans_getAvailableID(int32_t index,
  240. char* buf, // may be NULL
  241. int32_t bufCapacity) {
  242. return Transliterator::getAvailableID(index).extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
  243. }
  244. /* Transliterator UEnumeration ---------------------------------------------- */
  245. typedef struct UTransEnumeration {
  246. UEnumeration uenum;
  247. int32_t index, count;
  248. } UTransEnumeration;
  249. U_CDECL_BEGIN
  250. static int32_t U_CALLCONV
  251. utrans_enum_count(UEnumeration *uenum, UErrorCode *pErrorCode) {
  252. if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
  253. return 0;
  254. }
  255. return ((UTransEnumeration *)uenum)->count;
  256. }
  257. static const UChar* U_CALLCONV
  258. utrans_enum_unext(UEnumeration *uenum,
  259. int32_t* resultLength,
  260. UErrorCode *pErrorCode) {
  261. if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
  262. return 0;
  263. }
  264. UTransEnumeration *ute=(UTransEnumeration *)uenum;
  265. int32_t index=ute->index;
  266. if(index<ute->count) {
  267. const UnicodeString &ID=Transliterator::getAvailableID(index);
  268. ute->index=index+1;
  269. if(resultLength!=NULL) {
  270. *resultLength=ID.length();
  271. }
  272. // Transliterator keeps its ID NUL-terminated
  273. return ID.getBuffer();
  274. }
  275. if(resultLength!=NULL) {
  276. *resultLength=0;
  277. }
  278. return NULL;
  279. }
  280. static void U_CALLCONV
  281. utrans_enum_reset(UEnumeration *uenum, UErrorCode *pErrorCode) {
  282. if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
  283. return;
  284. }
  285. UTransEnumeration *ute=(UTransEnumeration *)uenum;
  286. ute->index=0;
  287. ute->count=Transliterator::countAvailableIDs();
  288. }
  289. static void U_CALLCONV
  290. utrans_enum_close(UEnumeration *uenum) {
  291. uprv_free(uenum);
  292. }
  293. U_CDECL_END
  294. static const UEnumeration utransEnumeration={
  295. NULL,
  296. NULL,
  297. utrans_enum_close,
  298. utrans_enum_count,
  299. utrans_enum_unext,
  300. uenum_nextDefault,
  301. utrans_enum_reset
  302. };
  303. U_CAPI UEnumeration * U_EXPORT2
  304. utrans_openIDs(UErrorCode *pErrorCode) {
  305. UTransEnumeration *ute;
  306. if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
  307. return NULL;
  308. }
  309. ute=(UTransEnumeration *)uprv_malloc(sizeof(UTransEnumeration));
  310. if(ute==NULL) {
  311. *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
  312. return NULL;
  313. }
  314. ute->uenum=utransEnumeration;
  315. ute->index=0;
  316. ute->count=Transliterator::countAvailableIDs();
  317. return (UEnumeration *)ute;
  318. }
  319. /********************************************************************
  320. * Transliteration API
  321. ********************************************************************/
  322. U_CAPI void U_EXPORT2
  323. utrans_trans(const UTransliterator* trans,
  324. UReplaceable* rep,
  325. UReplaceableCallbacks* repFunc,
  326. int32_t start,
  327. int32_t* limit,
  328. UErrorCode* status) {
  329. utrans_ENTRY(status);
  330. if (trans == 0 || rep == 0 || repFunc == 0 || limit == 0) {
  331. *status = U_ILLEGAL_ARGUMENT_ERROR;
  332. return;
  333. }
  334. ReplaceableGlue r(rep, repFunc);
  335. *limit = ((Transliterator*) trans)->transliterate(r, start, *limit);
  336. }
  337. U_CAPI void U_EXPORT2
  338. utrans_transIncremental(const UTransliterator* trans,
  339. UReplaceable* rep,
  340. UReplaceableCallbacks* repFunc,
  341. UTransPosition* pos,
  342. UErrorCode* status) {
  343. utrans_ENTRY(status);
  344. if (trans == 0 || rep == 0 || repFunc == 0 || pos == 0) {
  345. *status = U_ILLEGAL_ARGUMENT_ERROR;
  346. return;
  347. }
  348. ReplaceableGlue r(rep, repFunc);
  349. ((Transliterator*) trans)->transliterate(r, *pos, *status);
  350. }
  351. U_CAPI void U_EXPORT2
  352. utrans_transUChars(const UTransliterator* trans,
  353. UChar* text,
  354. int32_t* textLength,
  355. int32_t textCapacity,
  356. int32_t start,
  357. int32_t* limit,
  358. UErrorCode* status) {
  359. utrans_ENTRY(status);
  360. if (trans == 0 || text == 0 || limit == 0) {
  361. *status = U_ILLEGAL_ARGUMENT_ERROR;
  362. return;
  363. }
  364. int32_t textLen = (textLength == NULL || *textLength < 0)
  365. ? u_strlen(text) : *textLength;
  366. // writeable alias: for this ct, len CANNOT be -1 (why?)
  367. UnicodeString str(text, textLen, textCapacity);
  368. *limit = ((Transliterator*) trans)->transliterate(str, start, *limit);
  369. // Copy the string buffer back to text (only if necessary)
  370. // and fill in *neededCapacity (if neededCapacity != NULL).
  371. textLen = str.extract(text, textCapacity, *status);
  372. if(textLength != NULL) {
  373. *textLength = textLen;
  374. }
  375. }
  376. U_CAPI void U_EXPORT2
  377. utrans_transIncrementalUChars(const UTransliterator* trans,
  378. UChar* text,
  379. int32_t* textLength,
  380. int32_t textCapacity,
  381. UTransPosition* pos,
  382. UErrorCode* status) {
  383. utrans_ENTRY(status);
  384. if (trans == 0 || text == 0 || pos == 0) {
  385. *status = U_ILLEGAL_ARGUMENT_ERROR;
  386. return;
  387. }
  388. int32_t textLen = (textLength == NULL || *textLength < 0)
  389. ? u_strlen(text) : *textLength;
  390. // writeable alias: for this ct, len CANNOT be -1 (why?)
  391. UnicodeString str(text, textLen, textCapacity);
  392. ((Transliterator*) trans)->transliterate(str, *pos, *status);
  393. // Copy the string buffer back to text (only if necessary)
  394. // and fill in *neededCapacity (if neededCapacity != NULL).
  395. textLen = str.extract(text, textCapacity, *status);
  396. if(textLength != NULL) {
  397. *textLength = textLen;
  398. }
  399. }
  400. #endif /* #if !UCONFIG_NO_TRANSLITERATION */