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

Formattable * MessageFormat::parse ( const UnicodeString source,
ParsePosition pos,
int32_t &  count 
) const [virtual]

Parses the given string into an array of output arguments.

Parameters:
source String to be parsed.
pos On input, starting position for parse. On output, final position after parse. Unchanged if parse fails.
count Output parameter to receive the number of arguments parsed.
Returns:
an array of parsed arguments. The caller owns both the array and its contents. ICU 2.0

Definition at line 1315 of file msgfmt.cpp.

References UnicodeString::compare(), UnicodeString::extract(), ParsePosition::getIndex(), UnicodeString::indexOf(), isArgNumeric, UnicodeString::length(), NULL, Format::parseObject(), ParsePosition::setErrorIndex(), ParsePosition::setIndex(), Formattable::setString(), and subformats.

Referenced by parse(), parseObject(), TestMessageFormat::PatternTest(), and TestMessageFormat::TestRBNF().

{
    // Allocate at least one element.  Allocating an array of length
    // zero causes problems on some platforms (e.g. Win32).
    Formattable *resultArray = new Formattable[argTypeCount ? argTypeCount : 1];
    int32_t patternOffset = 0;
    int32_t sourceOffset = pos.getIndex();
    ParsePosition tempPos(0);
    count = 0; // {sfb} reset to zero
    int32_t len;
    // If resultArray could not be created, exit out.
    // Avoid crossing initialization of variables above.
    if (resultArray == NULL) {
        goto PARSE_ERROR;
    }
    for (int32_t i = 0; i < subformatCount; ++i) {
        // match up to format
        len = subformats[i].offset - patternOffset;
        if (len == 0 || 
            fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
            sourceOffset += len;
            patternOffset += len;
        } 
        else {
            goto PARSE_ERROR;
        }
        
        // now use format
        Format* fmt = subformats[i].format;
        int32_t argNum = subformats[i].argNum;
        if (fmt == NULL) {   // string format
            // if at end, use longest possible match
            // otherwise uses first match to intervening string
            // does NOT recursively try all possibilities
            int32_t tempLength = (i+1<subformatCount) ?
                subformats[i+1].offset : fPattern.length();
            
            int32_t next;
            if (patternOffset >= tempLength) {
                next = source.length();
            }
            else {
                UnicodeString buffer;
                fPattern.extract(patternOffset,tempLength - patternOffset, buffer);
                next = source.indexOf(buffer, sourceOffset);
            }
            
            if (next < 0) {
                goto PARSE_ERROR;
            } 
            else {
                UnicodeString buffer;
                source.extract(sourceOffset,next - sourceOffset, buffer);
                UnicodeString strValue = buffer;
                UnicodeString temp(LEFT_CURLY_BRACE);
                // {sfb} check this later
                if (isArgNumeric) {
                    itos(argNum, temp);
                }
                else {
                    temp+=(*subformats[i].argName);
                }
                temp += RIGHT_CURLY_BRACE;
                if (strValue != temp) {
                    source.extract(sourceOffset,next - sourceOffset, buffer);
                    resultArray[argNum].setString(buffer);
                    // {sfb} not sure about this
                    if ((argNum + 1) > count) {
                        count = argNum + 1;
                    }
                }
                sourceOffset = next;
            }
        } 
        else {
            tempPos.setIndex(sourceOffset);
            fmt->parseObject(source, resultArray[argNum], tempPos);
            if (tempPos.getIndex() == sourceOffset) {
                goto PARSE_ERROR;
            }
            
            if ((argNum + 1) > count) {
                count = argNum + 1;
            }
            sourceOffset = tempPos.getIndex(); // update
        }
    }
    len = fPattern.length() - patternOffset;
    if (len == 0 || 
        fPattern.compare(patternOffset, len, source, sourceOffset, len) == 0) {
        pos.setIndex(sourceOffset + len);
        return resultArray;
    }
    // else fall through...

 PARSE_ERROR:
    pos.setErrorIndex(sourceOffset);
    delete [] resultArray;
    count = 0;
    return NULL; // leave index as is to signal error
}


Generated by  Doxygen 1.6.0   Back to index