diff options
Diffstat (limited to 'deps/node/deps/icu-small/source/common/ubiditransform.cpp')
-rw-r--r-- | deps/node/deps/icu-small/source/common/ubiditransform.cpp | 530 |
1 files changed, 0 insertions, 530 deletions
diff --git a/deps/node/deps/icu-small/source/common/ubiditransform.cpp b/deps/node/deps/icu-small/source/common/ubiditransform.cpp deleted file mode 100644 index 394df609..00000000 --- a/deps/node/deps/icu-small/source/common/ubiditransform.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* -****************************************************************************** -* -* © 2016 and later: Unicode, Inc. and others. -* License & terms of use: http://www.unicode.org/copyright.html -* -****************************************************************************** -* file name: ubiditransform.c -* encoding: UTF-8 -* tab size: 8 (not used) -* indentation:4 -* -* created on: 2016jul24 -* created by: Lina Kemmel -* -*/ - -#include "cmemory.h" -#include "unicode/ubidi.h" -#include "unicode/ustring.h" -#include "unicode/ushape.h" -#include "unicode/utf16.h" -#include "ustr_imp.h" -#include "unicode/ubiditransform.h" - -/* Some convenience defines */ -#define LTR UBIDI_LTR -#define RTL UBIDI_RTL -#define LOGICAL UBIDI_LOGICAL -#define VISUAL UBIDI_VISUAL -#define SHAPE_LOGICAL U_SHAPE_TEXT_DIRECTION_LOGICAL -#define SHAPE_VISUAL U_SHAPE_TEXT_DIRECTION_VISUAL_LTR - -#define CHECK_LEN(STR, LEN, ERROR) { \ - if (LEN == 0) return 0; \ - if (LEN < -1) { *(ERROR) = U_ILLEGAL_ARGUMENT_ERROR; return 0; } \ - if (LEN == -1) LEN = u_strlen(STR); \ - } - -#define MAX_ACTIONS 7 - -/** - * Typedef for a pointer to a function, which performs some operation (such as - * reordering, setting "inverse" mode, character mirroring, etc.). Return value - * indicates whether the text was changed in the course of this operation or - * not. - */ -typedef UBool (*UBiDiAction)(UBiDiTransform *, UErrorCode *); - -/** - * Structure that holds a predefined reordering scheme, including the following - * information: - * <ul> - * <li>an input base direction,</li> - * <li>an input order,</li> - * <li>an output base direction,</li> - * <li>an output order,</li> - * <li>a digit shaping direction,</li> - * <li>a letter shaping direction,</li> - * <li>a base direction that should be applied when the reordering engine is - * invoked (which can not always be derived from the caller-defined - * options),</li> - * <li>an array of pointers to functions that accomplish the bidi layout - * transformation.</li> - * </ul> - */ -typedef struct { - UBiDiLevel inLevel; /* input level */ - UBiDiOrder inOrder; /* input order */ - UBiDiLevel outLevel; /* output level */ - UBiDiOrder outOrder; /* output order */ - uint32_t digitsDir; /* digit shaping direction */ - uint32_t lettersDir; /* letter shaping direction */ - UBiDiLevel baseLevel; /* paragraph level to be used with setPara */ - const UBiDiAction actions[MAX_ACTIONS]; /* array of pointers to functions carrying out the transformation */ -} ReorderingScheme; - -struct UBiDiTransform { - UBiDi *pBidi; /* pointer to a UBiDi object */ - const ReorderingScheme *pActiveScheme; /* effective reordering scheme */ - UChar *src; /* input text */ - UChar *dest; /* output text */ - uint32_t srcLength; /* input text length - not really needed as we are zero-terminated and can u_strlen */ - uint32_t srcSize; /* input text capacity excluding the trailing zero */ - uint32_t destSize; /* output text capacity */ - uint32_t *pDestLength; /* number of UChars written to dest */ - uint32_t reorderingOptions; /* reordering options - currently only suppot DO_MIRRORING */ - uint32_t digits; /* digit option for ArabicShaping */ - uint32_t letters; /* letter option for ArabicShaping */ -}; - -U_DRAFT UBiDiTransform* U_EXPORT2 -ubiditransform_open(UErrorCode *pErrorCode) -{ - UBiDiTransform *pBiDiTransform = NULL; - if (U_SUCCESS(*pErrorCode)) { - pBiDiTransform = (UBiDiTransform*) uprv_calloc(1, sizeof(UBiDiTransform)); - if (pBiDiTransform == NULL) { - *pErrorCode = U_MEMORY_ALLOCATION_ERROR; - } - } - return pBiDiTransform; -} - -U_DRAFT void U_EXPORT2 -ubiditransform_close(UBiDiTransform *pBiDiTransform) -{ - if (pBiDiTransform != NULL) { - if (pBiDiTransform->pBidi != NULL) { - ubidi_close(pBiDiTransform->pBidi); - } - if (pBiDiTransform->src != NULL) { - uprv_free(pBiDiTransform->src); - } - uprv_free(pBiDiTransform); - } -} - -/** - * Performs Bidi resolution of text. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_resolve(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - ubidi_setPara(pTransform->pBidi, pTransform->src, pTransform->srcLength, - pTransform->pActiveScheme->baseLevel, NULL, pErrorCode); - return FALSE; -} - -/** - * Performs basic reordering of text (Logical -> Visual LTR). - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_reorder(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - ubidi_writeReordered(pTransform->pBidi, pTransform->dest, pTransform->destSize, - static_cast<uint16_t>(pTransform->reorderingOptions), pErrorCode); - - *pTransform->pDestLength = pTransform->srcLength; - pTransform->reorderingOptions = UBIDI_REORDER_DEFAULT; - return TRUE; -} - -/** - * Sets "inverse" mode on the <code>UBiDi</code> object. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_setInverse(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - (void)pErrorCode; - ubidi_setInverse(pTransform->pBidi, TRUE); - ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT); - return FALSE; -} - -/** - * Sets "runs only" reordering mode indicating a Logical LTR <-> Logical RTL - * transformation. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_setRunsOnly(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - (void)pErrorCode; - ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_RUNS_ONLY); - return FALSE; -} - -/** - * Performs string reverse. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_reverse(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - ubidi_writeReverse(pTransform->src, pTransform->srcLength, - pTransform->dest, pTransform->destSize, - UBIDI_REORDER_DEFAULT, pErrorCode); - *pTransform->pDestLength = pTransform->srcLength; - return TRUE; -} - -/** - * Applies a new value to the text that serves as input at the current - * processing step. This value is identical to the original one when we begin - * the processing, but usually changes as the transformation progresses. - * - * @param pTransform A pointer to the <code>UBiDiTransform</code> structure. - * @param newSrc A pointer whose value is to be used as input text. - * @param newLength A length of the new text in <code>UChar</code>s. - * @param newSize A new source capacity in <code>UChar</code>s. - * @param pErrorCode Pointer to the error code value. - */ -static void -updateSrc(UBiDiTransform *pTransform, const UChar *newSrc, uint32_t newLength, - uint32_t newSize, UErrorCode *pErrorCode) -{ - if (newSize < newLength) { - *pErrorCode = U_BUFFER_OVERFLOW_ERROR; - return; - } - if (newSize > pTransform->srcSize) { - newSize += 50; // allocate slightly more than needed right now - if (pTransform->src != NULL) { - uprv_free(pTransform->src); - pTransform->src = NULL; - } - pTransform->src = (UChar *)uprv_malloc(newSize * sizeof(UChar)); - if (pTransform->src == NULL) { - *pErrorCode = U_MEMORY_ALLOCATION_ERROR; - //pTransform->srcLength = pTransform->srcSize = 0; - return; - } - pTransform->srcSize = newSize; - } - u_strncpy(pTransform->src, newSrc, newLength); - pTransform->srcLength = u_terminateUChars(pTransform->src, - pTransform->srcSize, newLength, pErrorCode); -} - -/** - * Calls a lower level shaping function. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param options Shaping options. - * @param pErrorCode Pointer to the error code value. - */ -static void -doShape(UBiDiTransform *pTransform, uint32_t options, UErrorCode *pErrorCode) -{ - *pTransform->pDestLength = u_shapeArabic(pTransform->src, - pTransform->srcLength, pTransform->dest, pTransform->destSize, - options, pErrorCode); -} - -/** - * Performs digit and letter shaping. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_shapeArabic(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - if ((pTransform->letters | pTransform->digits) == 0) { - return FALSE; - } - if (pTransform->pActiveScheme->lettersDir == pTransform->pActiveScheme->digitsDir) { - doShape(pTransform, pTransform->letters | pTransform->digits | pTransform->pActiveScheme->lettersDir, - pErrorCode); - } else { - doShape(pTransform, pTransform->digits | pTransform->pActiveScheme->digitsDir, pErrorCode); - if (U_SUCCESS(*pErrorCode)) { - updateSrc(pTransform, pTransform->dest, *pTransform->pDestLength, - *pTransform->pDestLength, pErrorCode); - doShape(pTransform, pTransform->letters | pTransform->pActiveScheme->lettersDir, - pErrorCode); - } - } - return TRUE; -} - -/** - * Performs character mirroring. - * - * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. - * @param pErrorCode Pointer to the error code value. - * - * @return Whether or not this function modifies the text. Besides the return - * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. - */ -static UBool -action_mirror(UBiDiTransform *pTransform, UErrorCode *pErrorCode) -{ - UChar32 c; - uint32_t i = 0, j = 0; - if (0 == (pTransform->reorderingOptions & UBIDI_DO_MIRRORING)) { - return FALSE; - } - if (pTransform->destSize < pTransform->srcLength) { - *pErrorCode = U_BUFFER_OVERFLOW_ERROR; - return FALSE; - } - do { - UBool isOdd = ubidi_getLevelAt(pTransform->pBidi, i) & 1; - U16_NEXT(pTransform->src, i, pTransform->srcLength, c); - U16_APPEND_UNSAFE(pTransform->dest, j, isOdd ? u_charMirror(c) : c); - } while (i < pTransform->srcLength); - - *pTransform->pDestLength = pTransform->srcLength; - pTransform->reorderingOptions = UBIDI_REORDER_DEFAULT; - return TRUE; -} - -/** - * All possible reordering schemes. - * - */ -static const ReorderingScheme Schemes[] = -{ - /* 0: Logical LTR => Visual LTR */ - {LTR, LOGICAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_shapeArabic, action_resolve, action_reorder, NULL}}, - /* 1: Logical RTL => Visual LTR */ - {RTL, LOGICAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL, - {action_resolve, action_reorder, action_shapeArabic, NULL}}, - /* 2: Logical LTR => Visual RTL */ - {LTR, LOGICAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_shapeArabic, action_resolve, action_reorder, action_reverse, NULL}}, - /* 3: Logical RTL => Visual RTL */ - {RTL, LOGICAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL, - {action_resolve, action_reorder, action_shapeArabic, action_reverse, NULL}}, - /* 4: Visual LTR => Logical RTL */ - {LTR, VISUAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL, - {action_shapeArabic, action_setInverse, action_resolve, action_reorder, NULL}}, - /* 5: Visual RTL => Logical RTL */ - {RTL, VISUAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL, - {action_reverse, action_shapeArabic, action_setInverse, action_resolve, action_reorder, NULL}}, - /* 6: Visual LTR => Logical LTR */ - {LTR, VISUAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_setInverse, action_resolve, action_reorder, action_shapeArabic, NULL}}, - /* 7: Visual RTL => Logical LTR */ - {RTL, VISUAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_reverse, action_setInverse, action_resolve, action_reorder, action_shapeArabic, NULL}}, - /* 8: Logical LTR => Logical RTL */ - {LTR, LOGICAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_shapeArabic, action_resolve, action_mirror, action_setRunsOnly, action_resolve, action_reorder, NULL}}, - /* 9: Logical RTL => Logical LTR */ - {RTL, LOGICAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, RTL, - {action_resolve, action_mirror, action_setRunsOnly, action_resolve, action_reorder, action_shapeArabic, NULL}}, - /* 10: Visual LTR => Visual RTL */ - {LTR, VISUAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR, - {action_shapeArabic, action_setInverse, action_resolve, action_mirror, action_reverse, NULL}}, - /* 11: Visual RTL => Visual LTR */ - {RTL, VISUAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR, - {action_reverse, action_shapeArabic, action_setInverse, action_resolve, action_mirror, NULL}}, - /* 12: Logical LTR => Logical LTR */ - {LTR, LOGICAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR, - {action_resolve, action_mirror, action_shapeArabic, NULL}}, - /* 13: Logical RTL => Logical RTL */ - {RTL, LOGICAL, RTL, LOGICAL, SHAPE_VISUAL, SHAPE_LOGICAL, RTL, - {action_resolve, action_mirror, action_shapeArabic, NULL}}, - /* 14: Visual LTR => Visual LTR */ - {LTR, VISUAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR, - {action_resolve, action_mirror, action_shapeArabic, NULL}}, - /* 15: Visual RTL => Visual RTL */ - {RTL, VISUAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR, - {action_reverse, action_resolve, action_mirror, action_shapeArabic, action_reverse, NULL}} -}; - -static const uint32_t nSchemes = sizeof(Schemes) / sizeof(*Schemes); - -/** - * When the direction option is <code>UBIDI_DEFAULT_LTR</code> or - * <code>UBIDI_DEFAULT_RTL</code>, resolve the base direction according to that - * of the first strong bidi character. - */ -static void -resolveBaseDirection(const UChar *text, uint32_t length, - UBiDiLevel *pInLevel, UBiDiLevel *pOutLevel) -{ - switch (*pInLevel) { - case UBIDI_DEFAULT_LTR: - case UBIDI_DEFAULT_RTL: { - UBiDiLevel level = static_cast<UBiDiLevel>(ubidi_getBaseDirection(text, length)); - *pInLevel = static_cast<UBiDiLevel>(level != UBIDI_NEUTRAL) ? level - : *pInLevel == UBIDI_DEFAULT_RTL ? static_cast<UBiDiLevel>(RTL) : static_cast<UBiDiLevel>(LTR); - break; - } - default: - *pInLevel &= 1; - break; - } - switch (*pOutLevel) { - case UBIDI_DEFAULT_LTR: - case UBIDI_DEFAULT_RTL: - *pOutLevel = *pInLevel; - break; - default: - *pOutLevel &= 1; - break; - } -} - -/** - * Finds a valid <code>ReorderingScheme</code> matching the - * caller-defined scheme. - * - * @return A valid <code>ReorderingScheme</code> object or NULL - */ -static const ReorderingScheme* -findMatchingScheme(UBiDiLevel inLevel, UBiDiLevel outLevel, - UBiDiOrder inOrder, UBiDiOrder outOrder) -{ - uint32_t i; - for (i = 0; i < nSchemes; i++) { - const ReorderingScheme *pScheme = Schemes + i; - if (inLevel == pScheme->inLevel && outLevel == pScheme->outLevel - && inOrder == pScheme->inOrder && outOrder == pScheme->outOrder) { - return pScheme; - } - } - return NULL; -} - -U_DRAFT uint32_t U_EXPORT2 -ubiditransform_transform(UBiDiTransform *pBiDiTransform, - const UChar *src, int32_t srcLength, - UChar *dest, int32_t destSize, - UBiDiLevel inParaLevel, UBiDiOrder inOrder, - UBiDiLevel outParaLevel, UBiDiOrder outOrder, - UBiDiMirroring doMirroring, uint32_t shapingOptions, - UErrorCode *pErrorCode) -{ - uint32_t destLength = 0; - UBool textChanged = FALSE; - const UBiDiTransform *pOrigTransform = pBiDiTransform; - const UBiDiAction *action = NULL; - - if (U_FAILURE(*pErrorCode)) { - return 0; - } - if (src == NULL || dest == NULL) { - *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; - return 0; - } - CHECK_LEN(src, srcLength, pErrorCode); - CHECK_LEN(dest, destSize, pErrorCode); - - if (pBiDiTransform == NULL) { - pBiDiTransform = ubiditransform_open(pErrorCode); - if (U_FAILURE(*pErrorCode)) { - return 0; - } - } - /* Current limitation: in multiple paragraphs will be resolved according - to the 1st paragraph */ - resolveBaseDirection(src, srcLength, &inParaLevel, &outParaLevel); - - pBiDiTransform->pActiveScheme = findMatchingScheme(inParaLevel, outParaLevel, - inOrder, outOrder); - if (pBiDiTransform->pActiveScheme == NULL) { - goto cleanup; - } - pBiDiTransform->reorderingOptions = doMirroring ? UBIDI_DO_MIRRORING - : UBIDI_REORDER_DEFAULT; - - /* Ignore TEXT_DIRECTION_* flags, as we apply our own depending on the text - scheme at the time shaping is invoked. */ - shapingOptions &= ~U_SHAPE_TEXT_DIRECTION_MASK; - pBiDiTransform->digits = shapingOptions & ~U_SHAPE_LETTERS_MASK; - pBiDiTransform->letters = shapingOptions & ~U_SHAPE_DIGITS_MASK; - - updateSrc(pBiDiTransform, src, srcLength, destSize > srcLength ? destSize : srcLength, pErrorCode); - if (U_FAILURE(*pErrorCode)) { - goto cleanup; - } - if (pBiDiTransform->pBidi == NULL) { - pBiDiTransform->pBidi = ubidi_openSized(0, 0, pErrorCode); - if (U_FAILURE(*pErrorCode)) { - goto cleanup; - } - } - pBiDiTransform->dest = dest; - pBiDiTransform->destSize = destSize; - pBiDiTransform->pDestLength = &destLength; - - /* Checking for U_SUCCESS() within the loop to bail out on first failure. */ - for (action = pBiDiTransform->pActiveScheme->actions; *action && U_SUCCESS(*pErrorCode); action++) { - if ((*action)(pBiDiTransform, pErrorCode)) { - if (action + 1) { - updateSrc(pBiDiTransform, pBiDiTransform->dest, *pBiDiTransform->pDestLength, - *pBiDiTransform->pDestLength, pErrorCode); - } - textChanged = TRUE; - } - } - ubidi_setInverse(pBiDiTransform->pBidi, FALSE); - - if (!textChanged && U_SUCCESS(*pErrorCode)) { - /* Text was not changed - just copy src to dest */ - if (destSize < srcLength) { - *pErrorCode = U_BUFFER_OVERFLOW_ERROR; - } else { - u_strncpy(dest, src, srcLength); - destLength = srcLength; - } - } -cleanup: - if (pOrigTransform != pBiDiTransform) { - ubiditransform_close(pBiDiTransform); - } else { - pBiDiTransform->dest = NULL; - pBiDiTransform->pDestLength = NULL; - pBiDiTransform->srcLength = 0; - pBiDiTransform->destSize = 0; - } - return U_FAILURE(*pErrorCode) ? 0 : destLength; -} |