Logo Search packages:      
Sourcecode: icu version File versions  Download package

TransliteratorIDParser::SingleID * TransliteratorIDParser::parseSingleID ( const UnicodeString id,
int32_t &  pos,
int32_t  dir,
UErrorCode status 
) [static]

Parse a single ID, that is, an ID of the general form "[f1] s1-t1/v1 ([f2] s2-t3/v2)", with the parenthesized element optional, the filters optional, and the variants optional.

Parameters:
id the id to be parsed
pos INPUT-OUTPUT parameter. On input, the position of the first character to parse. On output, the position after the last character parsed.
dir the direction. If the direction is REVERSE then the SingleID is constructed for the reverse direction.
Returns:
a SingleID object or null
Parse a single ID, that is, an ID of the general form "[f1] s1-t1/v1 ([f2] s2-t3/v2)", with the parenthesized element optional, the filters optional, and the variants optional.
Parameters:
id the id to be parsed
pos INPUT-OUTPUT parameter. On input, the position of the first character to parse. On output, the position after the last character parsed.
dir the direction. If the direction is REVERSE then the SingleID is constructed for the reverse direction.
Returns:
a SingleID object or NULL

Definition at line 107 of file tridpars.cpp.

References UnicodeString::append(), TransliteratorIDParser::SingleID::canonID, FALSE, TransliteratorIDParser::Specs::filter, TransliteratorIDParser::SingleID::filter, NULL, parseFilterID(), specsToID(), specsToSpecialInverse(), TRUE, and U_MEMORY_ALLOCATION_ERROR.

Referenced by parseCompoundID().

                                                                       {

    int32_t start = pos;

    // The ID will be of the form A, A(), A(B), or (B), where
    // A and B are filter IDs.
    Specs* specsA = NULL;
    Specs* specsB = NULL;
    UBool sawParen = FALSE;

    // On the first pass, look for (B) or ().  If this fails, then
    // on the second pass, look for A, A(B), or A().
    for (int32_t pass=1; pass<=2; ++pass) {
        if (pass == 2) {
            specsA = parseFilterID(id, pos, TRUE);
            if (specsA == NULL) {
                pos = start;
                return NULL;
            }
        }
        if (ICU_Utility::parseChar(id, pos, OPEN_REV)) {
            sawParen = TRUE;
            if (!ICU_Utility::parseChar(id, pos, CLOSE_REV)) {
                specsB = parseFilterID(id, pos, TRUE);
                // Must close with a ')'
                if (specsB == NULL || !ICU_Utility::parseChar(id, pos, CLOSE_REV)) {
                    delete specsA;
                    pos = start;
                    return NULL;
                }
            }
            break;
        }
    }

    // Assemble return results
    SingleID* single;
    if (sawParen) {
        if (dir == FORWARD) {
            SingleID* b = specsToID(specsB, FORWARD);
            single = specsToID(specsA, FORWARD);
            // Null pointers check
            if (b == NULL || single == NULL) {
                  delete b;
                  delete single;
                  status = U_MEMORY_ALLOCATION_ERROR;
                  return NULL;
            }
            single->canonID.append(OPEN_REV)
                .append(b->canonID).append(CLOSE_REV);
            if (specsA != NULL) {
                single->filter = specsA->filter;
            }
            delete b;
        } else {
            SingleID* a = specsToID(specsA, FORWARD);
            single = specsToID(specsB, FORWARD);
            // Check for null pointer.
            if (a == NULL || single == NULL) {
                  delete a;
                  delete single;
                  status = U_MEMORY_ALLOCATION_ERROR;
                  return NULL;
            }
            single->canonID.append(OPEN_REV)
                .append(a->canonID).append(CLOSE_REV);
            if (specsB != NULL) {
                single->filter = specsB->filter;
            }
            delete a;
        }
    } else {
        // assert(specsA != NULL);
        if (dir == FORWARD) {
            single = specsToID(specsA, FORWARD);
        } else {
            single = specsToSpecialInverse(*specsA, status);
            if (single == NULL) {
                single = specsToID(specsA, REVERSE);
            }
        }
        // Check for NULL pointer
        if (single == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        single->filter = specsA->filter;
    }

    delete specsA;
    delete specsB;

    return single;
}


Generated by  Doxygen 1.6.0   Back to index