Пример #1
0
//------------------------------------------------------------------------
bool StringListParameter::fromString (const TChar* string, ParamValue& _valueNormalized) const
{
	int32 index = 0;
	for (StringVector::const_iterator it = strings.begin (), end = strings.end (); it != end;
	     ++it, ++index)
	{
		if (strcmp16 (*it, string) == 0)
		{
			_valueNormalized = toNormalized ((ParamValue)index);
			return true;
		}
	}
	return false;
}
Пример #2
0
status_t parseStyledString(Bundle* bundle,
                           const char* fileName,
                           ResXMLTree* inXml,
                           const String16& endTag,
                           String16* outString,
                           Vector<StringPool::entry_style_span>* outSpans,
                           bool pseudolocalize)
{
    Vector<StringPool::entry_style_span> spanStack;
    String16 curString;
    String16 rawString;
    const char* errorMsg;
    int xliffDepth = 0;
    bool firstTime = true;

    size_t len;
    ResXMLTree::event_code_t code;
    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {

        if (code == ResXMLTree::TEXT) {
            String16 text(inXml->getText(&len));
            if (firstTime && text.size() > 0) {
                firstTime = false;
                if (text.string()[0] == '@') {
                    // If this is a resource reference, don't do the pseudoloc.
                    pseudolocalize = false;
                }
            }
            if (xliffDepth == 0 && pseudolocalize) {
                std::string orig(String8(text).string());
                std::string pseudo = pseudolocalize_string(orig);
                curString.append(String16(String8(pseudo.c_str())));
            } else {
                curString.append(text);
            }
        } else if (code == ResXMLTree::START_TAG) {
            const String16 element16(inXml->getElementName(&len));
            const String8 element8(element16);

            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);
                for (int i=0; i<N; i++) {
                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {
                        xliffDepth++;
                        // in this case, treat it like it was just text, in other words, do nothing
                        // here and silently drop this element
                        goto moveon;
                    }
                }
                {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found unsupported XLIFF tag <%s>\n",
                            element8.string());
                    return UNKNOWN_ERROR;
                }
moveon:
                continue;
            }

            if (outSpans == NULL) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found style tag <%s> where styles are not allowed\n", element8.string());
                return UNKNOWN_ERROR;
            }

            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            StringPool::entry_style_span span;
            span.name = element16;
            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {
                span.name.append(String16(";"));
                const char16_t* str = inXml->getAttributeName(ai, &len);
                span.name.append(str, len);
                span.name.append(String16("="));
                str = inXml->getAttributeStringValue(ai, &len);
                span.name.append(str, len);
            }
            //printf("Span: %s\n", String8(span.name).string());
            span.span.firstChar = span.span.lastChar = outString->size();
            spanStack.push(span);

        } else if (code == ResXMLTree::END_TAG) {
            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                xliffDepth--;
                continue;
            }
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            if (spanStack.size() == 0) {
                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found tag %s where <%s> close is expected\n",
                            String8(inXml->getElementName(&len)).string(),
                            String8(endTag).string());
                    return UNKNOWN_ERROR;
                }
                break;
            }
            StringPool::entry_style_span span = spanStack.top();
            String16 spanTag;
            ssize_t semi = span.name.findFirst(';');
            if (semi >= 0) {
                spanTag.setTo(span.name.string(), semi);
            } else {
                spanTag.setTo(span.name);
            }
            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found close tag %s where close tag %s is expected\n",
                        String8(inXml->getElementName(&len)).string(),
                        String8(spanTag).string());
                return UNKNOWN_ERROR;
            }
            bool empty = true;
            if (outString->size() > 0) {
                span.span.lastChar = outString->size()-1;
                if (span.span.lastChar >= span.span.firstChar) {
                    empty = false;
                    outSpans->add(span);
                }
            }
            spanStack.pop();

            /*
             * This warning seems to be just an irritation to most people,
             * since it is typically introduced by translators who then never
             * see the warning.
             */
            if (0 && empty) {
                fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
                        fileName, inXml->getLineNumber(),
                        String8(spanTag).string(), String8(*outString).string());

            }
        } else if (code == ResXMLTree::START_NAMESPACE) {
            // nothing
        }
    }

    if (code == ResXMLTree::BAD_DOCUMENT) {
            SourcePos(String8(fileName), inXml->getLineNumber()).error(
                    "Error parsing XML\n");
    }

    if (outSpans != NULL && outSpans->size() > 0) {
        if (curString.size() > 0) {
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
        }
    } else {
        // There is no style information, so string processing will happen
        // later as part of the overall type conversion.  Return to the
        // client the raw unprocessed text.
        rawString.append(curString);
        outString->setTo(rawString);
    }

    return NO_ERROR;
}