X-Git-Url: https://git.saurik.com/android/aapt.git/blobdiff_plain/dadd9c1fc18bd05c84a357b56e945b5829b3bd95..4fd67e1daa2d896637d9236e81da77dccaab844e:/XMLNode.cpp diff --git a/XMLNode.cpp b/XMLNode.cpp index 8f45959..4c59288 100644 --- a/XMLNode.cpp +++ b/XMLNode.cpp @@ -21,6 +21,7 @@ const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/"; const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"; +const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/"; const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2"; const char* const ALLOWED_XLIFF_ELEMENTS[] = { @@ -43,15 +44,27 @@ bool isWhitespace(const char16_t* str) } static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE); +static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE); -String16 getNamespaceResourcePackage(String16 namespaceUri) +String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic) { //printf("%s starts with %s?\n", String8(namespaceUri).string(), // String8(RESOURCES_PREFIX).string()); - if (!namespaceUri.startsWith(RESOURCES_PREFIX)) return String16(); + size_t prefixSize; + bool isPublic = true; + if (namespaceUri.startsWith(RESOURCES_PREFIX)) { + prefixSize = RESOURCES_PREFIX.size(); + } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) { + isPublic = false; + prefixSize = RESOURCES_PRV_PREFIX.size(); + } else { + if (outIsPublic) *outIsPublic = isPublic; // = true + return String16(); + } + //printf("YES!\n"); - const size_t prefixSize = RESOURCES_PREFIX.size(); //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string()); + if (outIsPublic) *outIsPublic = isPublic; return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize); } @@ -206,10 +219,15 @@ moveon: } spanStack.pop(); - if (empty) { - fprintf(stderr, "%s:%d: WARNING: empty '%s' span found for at text '%s'\n", + /* + * 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(*outString).string(), String8(spanTag).string()); + String8(spanTag).string(), String8(*outString).string()); } } else if (code == ResXMLTree::START_NAMESPACE) { @@ -460,6 +478,7 @@ XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2 , mFilename(filename) , mStartLineNumber(0) , mEndLineNumber(0) + , mUTF8(false) { if (isNamespace) { mNamespacePrefix = s1; @@ -473,6 +492,7 @@ XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2 XMLNode::XMLNode(const String8& filename) : mFilename(filename) { + memset(&mCharsValue, 0, sizeof(mCharsValue)); } XMLNode::type XMLNode::getType() const @@ -511,12 +531,43 @@ const Vector >& XMLNode::getChildren() const return mChildren; } +const String8& XMLNode::getFilename() const +{ + return mFilename; +} + const Vector& XMLNode::getAttributes() const { return mAttributes; } +const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns, + const String16& name) const +{ + for (size_t i=0; ins == ns && ae->name == name) { + return ae; + } + } + + return NULL; +} + const String16& XMLNode::getCData() const { return mChars; @@ -537,6 +588,38 @@ int32_t XMLNode::getEndLineNumber() const return mEndLineNumber; } +sp XMLNode::searchElement(const String16& tagNamespace, const String16& tagName) +{ + if (getType() == XMLNode::TYPE_ELEMENT + && mNamespaceUri == tagNamespace + && mElementName == tagName) { + return this; + } + + for (size_t i=0; i found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName); + if (found != NULL) { + return found; + } + } + + return NULL; +} + +sp XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName) +{ + for (size_t i=0; i child = mChildren.itemAt(i); + if (child->getType() == XMLNode::TYPE_ELEMENT + && child->mNamespaceUri == tagNamespace + && child->mElementName == tagName) { + return child; + } + } + + return NULL; +} + status_t XMLNode::addChild(const sp& child) { if (getType() == TYPE_CDATA) { @@ -548,6 +631,17 @@ status_t XMLNode::addChild(const sp& child) return NO_ERROR; } +status_t XMLNode::insertChildAt(const sp& child, size_t index) +{ + if (getType() == TYPE_CDATA) { + SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node."); + return UNKNOWN_ERROR; + } + //printf("Adding child %p to parent %p\n", child.get(), this); + mChildren.insertAt(child, index); + return NO_ERROR; +} + status_t XMLNode::addAttribute(const String16& ns, const String16& name, const String16& value) { @@ -715,15 +809,18 @@ status_t XMLNode::assignResourceIds(const sp& assets, for (size_t i=0; i %s\n", + bool nsIsPublic; + String16 pkg(getNamespaceResourcePackage(e.ns, &nsIsPublic)); + NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n", String8(getElementName()).string(), String8(e.name).string(), String8(e.string).string(), - String8(e.ns).string(), String8(pkg).string())); + String8(e.ns).string(), + (nsIsPublic) ? "public" : "private", + String8(pkg).string())); if (pkg.size() <= 0) continue; uint32_t res = table != NULL - ? table->getResId(e.name, &attr, &pkg, &errorMsg) + ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic) : assets->getIncludedResources(). identifierForName(e.name.string(), e.name.size(), attr.string(), attr.size(), @@ -754,7 +851,7 @@ status_t XMLNode::assignResourceIds(const sp& assets, status_t XMLNode::flatten(const sp& dest, bool stripComments, bool stripRawValues) const { - StringPool strings; + StringPool strings = StringPool(false, mUTF8); Vector resids; // First collect just the strings for attribute names that have a