/* ******************************************************************************* * * Copyright (C) 2000, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: ushape.c * encoding: US-ASCII * tab size: 8 (not used) * indentation:4 * * created on: 2000jun29 * created by: Markus W. Scherer */ #include "unicode/utypes.h" #include "unicode/uchar.h" #include "unicode/ustring.h" #include "cmemory.h" #include "unicode/ushape.h" #if UTF_SIZE<16 /* * This implementation assumes that the internal encoding is UTF-16 * or UTF-32, not UTF-8. * The main assumption is that the Arabic characters and their * presentation forms each fit into a single UChar. * With UTF-8, they occupy 2 or 3 bytes, and more than the ASCII * characters. */ # error This implementation assumes UTF-16 or UTF-32 (check UTF_SIZE) #endif /* * This function shapes European digits to Arabic-Indic digits * in-place, writing over the input characters. * Since we know that we are only looking for BMP code points, * we can safely just work with code units (again, at least UTF-16). */ static void _shapeToArabicDigitsWithContext(UChar *s, int32_t length, UChar digitBase, UBool isLogical, UBool lastStrongWasAL) { int32_t i; UChar c; digitBase-=0x30; /* the iteration direction depends on the type of input */ if(isLogical) { for(i=0; i0; /* pre-decrement in the body */) { c=s[--i]; switch(u_charDirection(c)) { case U_LEFT_TO_RIGHT: /* L */ case U_RIGHT_TO_LEFT: /* R */ lastStrongWasAL=FALSE; break; case U_RIGHT_TO_LEFT_ARABIC: /* AL */ lastStrongWasAL=TRUE; break; case U_EUROPEAN_NUMBER: /* EN */ if(lastStrongWasAL && (uint32_t)(c-0x30)<10) { s[i]=(UChar)(digitBase+c); /* digitBase+(c-0x30) - digitBase was modified above */ } break; default : break; } } } } U_CAPI int32_t U_EXPORT2 u_shapeArabic(const UChar *source, int32_t sourceLength, UChar *dest, int32_t destSize, uint32_t options, UErrorCode *pErrorCode) { /* usual error checking */ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } /* make sure that no reserved options values are used; allow dest==NULL only for preflighting */ if( source==NULL || sourceLength<-1 || (dest==NULL && destSize!=0) || destSize<0 || options>=U_SHAPE_DIGIT_TYPE_RESERVED || (options&U_SHAPE_LENGTH_MASK)==U_SHAPE_LENGTH_RESERVED || (options&U_SHAPE_LETTERS_MASK)==U_SHAPE_LETTERS_RESERVED || (options&U_SHAPE_DIGITS_MASK)>=U_SHAPE_DIGITS_RESERVED ) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } /* determine the source length */ if(sourceLength==-1) { sourceLength=u_strlen(source); } if(sourceLength==0) { return 0; } /* check that source and destination do not overlap */ if( dest!=NULL && ((source<=dest && dest