19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Build resource files from raw assets. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h" 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <host/pseudolocalize.h> 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ByteOrder.h> 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_MS_C_RUNTIME 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define O_BINARY 0 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY_PARSE(x) //x 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/"; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"; 24d9fe8018ffbf94f18a840005e688ad1d712f0225Xavier Ducrohetconst char* const RESOURCES_AUTO_PACKAGE_NAMESPACE = "http://schemas.android.com/apk/res-auto"; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/"; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2"; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const ALLOWED_XLIFF_ELEMENTS[] = { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "bpt", 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ept", 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "it", 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ph", 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "g", 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "bx", 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ex", 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "x" 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool isWhitespace(const char16_t* str) 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*str != 0 && *str < 128 && isspace(*str)) { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str++; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return *str == 0; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE); 48e348909c1966c3d192841cc131a32be6ed90da18inazarukstatic const String16 RESOURCES_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE); 50f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohetstatic const String16 RESOURCES_TOOLS_NAMESPACE("http://schemas.android.com/tools"); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52e348909c1966c3d192841cc131a32be6ed90da18inazarukString16 getNamespaceResourcePackage(String16 appPackage, String16 namespaceUri, bool* outIsPublic) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("%s starts with %s?\n", String8(namespaceUri).string(), 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(RESOURCES_PREFIX).string()); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t prefixSize; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isPublic = true; 58e348909c1966c3d192841cc131a32be6ed90da18inazaruk if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) { 59e348909c1966c3d192841cc131a32be6ed90da18inazaruk NOISY(printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(), String8(appPackage).string())); 60e348909c1966c3d192841cc131a32be6ed90da18inazaruk isPublic = true; 61e348909c1966c3d192841cc131a32be6ed90da18inazaruk return appPackage; 62e348909c1966c3d192841cc131a32be6ed90da18inazaruk } else if (namespaceUri.startsWith(RESOURCES_PREFIX)) { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefixSize = RESOURCES_PREFIX.size(); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isPublic = false; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefixSize = RESOURCES_PRV_PREFIX.size(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outIsPublic) *outIsPublic = isPublic; // = true 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String16(); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("YES!\n"); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string()); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outIsPublic) *outIsPublic = isPublic; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7815fe2cb73b0770316db302f6502f568062d68e74Kenny Rootstatus_t hasSubstitutionErrors(const char* fileName, 7915fe2cb73b0770316db302f6502f568062d68e74Kenny Root ResXMLTree* inXml, 8015fe2cb73b0770316db302f6502f568062d68e74Kenny Root String16 str16) 8115fe2cb73b0770316db302f6502f568062d68e74Kenny Root{ 8215fe2cb73b0770316db302f6502f568062d68e74Kenny Root const char16_t* str = str16.string(); 8315fe2cb73b0770316db302f6502f568062d68e74Kenny Root const char16_t* p = str; 8415fe2cb73b0770316db302f6502f568062d68e74Kenny Root const char16_t* end = str + str16.size(); 8515fe2cb73b0770316db302f6502f568062d68e74Kenny Root 8615fe2cb73b0770316db302f6502f568062d68e74Kenny Root bool nonpositional = false; 8715fe2cb73b0770316db302f6502f568062d68e74Kenny Root int argCount = 0; 8815fe2cb73b0770316db302f6502f568062d68e74Kenny Root 8915fe2cb73b0770316db302f6502f568062d68e74Kenny Root while (p < end) { 9015fe2cb73b0770316db302f6502f568062d68e74Kenny Root /* 9115fe2cb73b0770316db302f6502f568062d68e74Kenny Root * Look for the start of a Java-style substitution sequence. 9215fe2cb73b0770316db302f6502f568062d68e74Kenny Root */ 9315fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (*p == '%' && p + 1 < end) { 9415fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 9515fe2cb73b0770316db302f6502f568062d68e74Kenny Root 9615fe2cb73b0770316db302f6502f568062d68e74Kenny Root // A literal percent sign represented by %% 9715fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (*p == '%') { 9815fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 9915fe2cb73b0770316db302f6502f568062d68e74Kenny Root continue; 10015fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 10115fe2cb73b0770316db302f6502f568062d68e74Kenny Root 10215fe2cb73b0770316db302f6502f568062d68e74Kenny Root argCount++; 10315fe2cb73b0770316db302f6502f568062d68e74Kenny Root 10415fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (*p >= '0' && *p <= '9') { 10515fe2cb73b0770316db302f6502f568062d68e74Kenny Root do { 10615fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 10715fe2cb73b0770316db302f6502f568062d68e74Kenny Root } while (*p >= '0' && *p <= '9'); 10815fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (*p != '$') { 10915fe2cb73b0770316db302f6502f568062d68e74Kenny Root // This must be a size specification instead of position. 11015fe2cb73b0770316db302f6502f568062d68e74Kenny Root nonpositional = true; 11115fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 11215fe2cb73b0770316db302f6502f568062d68e74Kenny Root } else if (*p == '<') { 11315fe2cb73b0770316db302f6502f568062d68e74Kenny Root // Reusing last argument; bad idea since it can be re-arranged. 11415fe2cb73b0770316db302f6502f568062d68e74Kenny Root nonpositional = true; 11515fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 11615fe2cb73b0770316db302f6502f568062d68e74Kenny Root 11715fe2cb73b0770316db302f6502f568062d68e74Kenny Root // Optionally '$' can be specified at the end. 11815fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (p < end && *p == '$') { 11915fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 12015fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 12115fe2cb73b0770316db302f6502f568062d68e74Kenny Root } else { 12215fe2cb73b0770316db302f6502f568062d68e74Kenny Root nonpositional = true; 12315fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 12415fe2cb73b0770316db302f6502f568062d68e74Kenny Root 12515fe2cb73b0770316db302f6502f568062d68e74Kenny Root // Ignore flags and widths 12615fe2cb73b0770316db302f6502f568062d68e74Kenny Root while (p < end && (*p == '-' || 12715fe2cb73b0770316db302f6502f568062d68e74Kenny Root *p == '#' || 12815fe2cb73b0770316db302f6502f568062d68e74Kenny Root *p == '+' || 12915fe2cb73b0770316db302f6502f568062d68e74Kenny Root *p == ' ' || 13015fe2cb73b0770316db302f6502f568062d68e74Kenny Root *p == ',' || 13115fe2cb73b0770316db302f6502f568062d68e74Kenny Root *p == '(' || 13215fe2cb73b0770316db302f6502f568062d68e74Kenny Root (*p >= '0' && *p <= '9'))) { 13315fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 13415fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 13515fe2cb73b0770316db302f6502f568062d68e74Kenny Root 13615fe2cb73b0770316db302f6502f568062d68e74Kenny Root /* 13715fe2cb73b0770316db302f6502f568062d68e74Kenny Root * This is a shortcut to detect strings that are going to Time.format() 13815fe2cb73b0770316db302f6502f568062d68e74Kenny Root * instead of String.format() 13915fe2cb73b0770316db302f6502f568062d68e74Kenny Root * 14015fe2cb73b0770316db302f6502f568062d68e74Kenny Root * Comparison of String.format() and Time.format() args: 14115fe2cb73b0770316db302f6502f568062d68e74Kenny Root * 14215fe2cb73b0770316db302f6502f568062d68e74Kenny Root * String: ABC E GH ST X abcdefgh nost x 14315fe2cb73b0770316db302f6502f568062d68e74Kenny Root * Time: DEFGHKMS W Za d hkm s w yz 14415fe2cb73b0770316db302f6502f568062d68e74Kenny Root * 14515fe2cb73b0770316db302f6502f568062d68e74Kenny Root * Therefore we know it's definitely Time if we have: 14615fe2cb73b0770316db302f6502f568062d68e74Kenny Root * DFKMWZkmwyz 14715fe2cb73b0770316db302f6502f568062d68e74Kenny Root */ 14815fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (p < end) { 14915fe2cb73b0770316db302f6502f568062d68e74Kenny Root switch (*p) { 15015fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'D': 15115fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'F': 15215fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'K': 15315fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'M': 15415fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'W': 15515fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'Z': 15615fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'k': 15715fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'm': 15815fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'w': 15915fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'y': 16015fe2cb73b0770316db302f6502f568062d68e74Kenny Root case 'z': 16115fe2cb73b0770316db302f6502f568062d68e74Kenny Root return NO_ERROR; 16215fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 16315fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 16415fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 16515fe2cb73b0770316db302f6502f568062d68e74Kenny Root 16615fe2cb73b0770316db302f6502f568062d68e74Kenny Root p++; 16715fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 16815fe2cb73b0770316db302f6502f568062d68e74Kenny Root 16915fe2cb73b0770316db302f6502f568062d68e74Kenny Root /* 17015fe2cb73b0770316db302f6502f568062d68e74Kenny Root * If we have more than one substitution in this string and any of them 17115fe2cb73b0770316db302f6502f568062d68e74Kenny Root * are not in positional form, give the user an error. 17215fe2cb73b0770316db302f6502f568062d68e74Kenny Root */ 17315fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (argCount > 1 && nonpositional) { 17415fe2cb73b0770316db302f6502f568062d68e74Kenny Root SourcePos(String8(fileName), inXml->getLineNumber()).error( 17515fe2cb73b0770316db302f6502f568062d68e74Kenny Root "Multiple substitutions specified in non-positional format; " 17698ee11ddb7996b332d5e31f8bdff69631c8d3725Eric Fischer "did you mean to add the formatted=\"false\" attribute?\n"); 17715fe2cb73b0770316db302f6502f568062d68e74Kenny Root return NOT_ENOUGH_DATA; 17815fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 17915fe2cb73b0770316db302f6502f568062d68e74Kenny Root 18015fe2cb73b0770316db302f6502f568062d68e74Kenny Root return NO_ERROR; 18115fe2cb73b0770316db302f6502f568062d68e74Kenny Root} 18215fe2cb73b0770316db302f6502f568062d68e74Kenny Root 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseStyledString(Bundle* bundle, 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* fileName, 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree* inXml, 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16& endTag, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outString, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<StringPool::entry_style_span>* outSpans, 18915fe2cb73b0770316db302f6502f568062d68e74Kenny Root bool isFormatted, 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool pseudolocalize) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<StringPool::entry_style_span> spanStack; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 curString; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 rawString; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* errorMsg; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int xliffDepth = 0; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool firstTime = true; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::TEXT) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 text(inXml->getText(&len)); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstTime && text.size() > 0) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstTime = false; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (text.string()[0] == '@') { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is a resource reference, don't do the pseudoloc. 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pseudolocalize = false; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xliffDepth == 0 && pseudolocalize) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project std::string orig(String8(text).string()); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project std::string pseudo = pseudolocalize_string(orig); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString.append(String16(String8(pseudo.c_str()))); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 21715fe2cb73b0770316db302f6502f568062d68e74Kenny Root if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) { 21815fe2cb73b0770316db302f6502f568062d68e74Kenny Root return UNKNOWN_ERROR; 21915fe2cb73b0770316db302f6502f568062d68e74Kenny Root } else { 22015fe2cb73b0770316db302f6502f568062d68e74Kenny Root curString.append(text); 22115fe2cb73b0770316db302f6502f568062d68e74Kenny Root } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::START_TAG) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16 element16(inXml->getElementName(&len)); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String8 element8(element16); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t nslen; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* ns = inXml->getElementNamespace(&nslen); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns == NULL) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns = (const uint16_t*)"\0\0"; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nslen = 0; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String8 nspace(String16(ns, nslen)); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nspace == XLIFF_XMLNS) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xliffDepth++; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in this case, treat it like it was just text, in other words, do nothing 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // here and silently drop this element 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto moveon; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Found unsupported XLIFF tag <%s>\n", 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project element8.string()); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmoveon: 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpans == NULL) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Found style tag <%s> where styles are not allowed\n", element8.string()); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ResTable::collectString(outString, curString.string(), 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString.size(), false, &errorMsg, true)) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errorMsg, String8(curString).string()); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rawString.append(curString); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString = String16(); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringPool::entry_style_span span; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.name = element16; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.name.append(String16(";")); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* str = inXml->getAttributeName(ai, &len); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.name.append(str, len); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.name.append(String16("=")); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str = inXml->getAttributeStringValue(ai, &len); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.name.append(str, len); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Span: %s\n", String8(span.name).string()); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.span.firstChar = span.span.lastChar = outString->size(); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spanStack.push(span); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::END_TAG) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t nslen; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* ns = inXml->getElementNamespace(&nslen); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns == NULL) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns = (const uint16_t*)"\0\0"; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nslen = 0; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String8 nspace(String16(ns, nslen)); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nspace == XLIFF_XMLNS) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xliffDepth--; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ResTable::collectString(outString, curString.string(), 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString.size(), false, &errorMsg, true)) { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errorMsg, String8(curString).string()); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rawString.append(curString); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString = String16(); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (spanStack.size() == 0) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Found tag %s where <%s> close is expected\n", 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(inXml->getElementName(&len)).string(), 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(endTag).string()); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringPool::entry_style_span span = spanStack.top(); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 spanTag; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t semi = span.name.findFirst(';'); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (semi >= 0) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spanTag.setTo(span.name.string(), semi); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spanTag.setTo(span.name); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Found close tag %s where close tag %s is expected\n", 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(inXml->getElementName(&len)).string(), 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(spanTag).string()); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool empty = true; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outString->size() > 0) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.span.lastChar = outString->size()-1; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (span.span.lastChar >= span.span.firstChar) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project empty = false; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outSpans->add(span); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spanStack.pop(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer /* 340c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * This warning seems to be just an irritation to most people, 341c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * since it is typically introduced by translators who then never 342c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * see the warning. 343c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer */ 344c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer if (0 && empty) { 345dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n", 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fileName, inXml->getLineNumber(), 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(spanTag).string(), String8(*outString).string()); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::START_NAMESPACE) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::BAD_DOCUMENT) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Error parsing XML\n"); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpans != NULL && outSpans->size() > 0) { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curString.size() > 0) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ResTable::collectString(outString, curString.string(), 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curString.size(), false, &errorMsg, true)) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(String8(fileName), inXml->getLineNumber()).error( 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "%s (in %s)\n", 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errorMsg, String8(curString).string()); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is no style information, so string processing will happen 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // later as part of the overall type conversion. Return to the 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // client the raw unprocessed text. 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rawString.append(curString); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->setTo(rawString); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct namespace_entry { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 prefix; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 uri; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 make_prefix(int depth) 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 prefix; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<depth; i++) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix.append(" "); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return prefix; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 build_namespace(const Vector<namespace_entry>& namespaces, 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* ns) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 str; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns != NULL) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str = String8(ns); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = namespaces.size(); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const namespace_entry& ne = namespaces.itemAt(i); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ne.uri == str) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str = ne.prefix; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str.append(":"); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid printXMLBlock(ResXMLTree* block) 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project block->restart(); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<namespace_entry> namespaces; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree::event_code_t code; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth = 0; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 prefix = make_prefix(depth); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (code == ResXMLTree::START_TAG) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* ns16 = block->getElementNamespace(&len); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 elemNs = build_namespace(namespaces, ns16); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* com16 = block->getComment(&len); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (com16) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string()); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(), 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(block->getElementName(&len)).string(), 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project block->getLineNumber()); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = block->getAttributeCount(); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix = make_prefix(depth); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<N; i++) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t res = block->getAttributeNameResID(i); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns16 = block->getAttributeNamespace(i, &len); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 ns = build_namespace(namespaces, ns16); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 name(block->getAttributeName(i, &len)); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%sA: ", prefix.string()); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s%s(0x%08x)", ns.string(), name.string(), res); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s%s", ns.string(), name.string()); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_value value; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project block->getAttributeValue(i, &value); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.dataType == Res_value::TYPE_NULL) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=(null)"); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (value.dataType == Res_value::TYPE_REFERENCE) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=@0x%x", (int)value.data); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=?0x%x", (int)value.data); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (value.dataType == Res_value::TYPE_STRING) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=\"%s\"", 4619872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i, 4629872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh &len)).string()).string()); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* val = block->getAttributeStringValue(i, &len); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (val != NULL) { 4689872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).string()). 4699872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh string()); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::END_TAG) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::START_NAMESPACE) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project namespace_entry ns; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* prefix16 = block->getNamespacePrefix(&len); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (prefix16) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns.prefix = String8(prefix16); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns.prefix = "<DEF>"; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns.uri = String8(block->getNamespaceUri(&len)); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project namespaces.push(ns); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(), 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ns.uri.string()); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth++; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::END_NAMESPACE) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project depth--; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const namespace_entry& ns = namespaces.top(); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t* prefix16 = block->getNamespacePrefix(&len); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 pr; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (prefix16) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pr = String8(prefix16); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pr = "<DEF>"; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns.prefix != pr) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix = make_prefix(depth); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n", 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix.string(), pr.string(), ns.prefix.string()); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 uri = String8(block->getNamespaceUri(&len)); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns.uri != uri) { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix = make_prefix(depth); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s *** BAD END NS URI: found=%s, expected=%s\n", 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix.string(), uri.string(), ns.uri.string()); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project namespaces.pop(); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (code == ResXMLTree::TEXT) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 514429dad687bcb5f00587e8b91b3a614502907aaa1Shachar Shemesh printf("%sC: \"%s\"\n", prefix.string(), 515429dad687bcb5f00587e8b91b3a614502907aaa1Shachar Shemesh ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string()); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project block->restart(); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree, 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool stripAll, bool keepComments, 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char** cDataTags) 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> root = XMLNode::parse(file); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root == NULL) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root->removeWhitespace(stripAll, cDataTags); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Input XML from %s:\n", (const char*)file->getPrintableSource())); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(root->print()); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8()); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = root->flatten(rsc, !keepComments, false); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = outTree->setTo(rsc->getData(), rsc->getSize(), true); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Output XML:\n")); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printXMLBlock(outTree)); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<XMLNode> XMLNode::parse(const sp<AaptFile>& file) 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[16384]; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s", 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strerror(errno)); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_Parser parser = XML_ParserCreateNS(NULL, 1); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState state; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.filename = file->getPrintableSource(); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project state.parser = parser; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_SetUserData(parser, &state); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_SetElementHandler(parser, startElement, endElement); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_SetCharacterDataHandler(parser, characterData); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_SetCommentHandler(parser, commentData); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t len; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool done; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = read(fd, buf, sizeof(buf)); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project done = len < (ssize_t)sizeof(buf); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len < 0) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(file->getSourceFile(), -1).error("Error reading file: %s\n", strerror(errno)); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error( 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser))); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (!done); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_ParserFree(parser); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.root == NULL) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(file->getSourceFile(), -1).error("No XML data generated when parsing"); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return state.root; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace) 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mNextAttributeIndex(0x80000000) 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mFilename(filename) 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mStartLineNumber(0) 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mEndLineNumber(0) 60119138468caf7050d482dc15f35a344eab11bb756Kenny Root , mUTF8(false) 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isNamespace) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNamespacePrefix = s1; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNamespaceUri = s2; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNamespaceUri = s1; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mElementName = s2; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::XMLNode(const String8& filename) 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mFilename(filename) 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6156a1fadea851db236331b3dfe1f3c1e482556057fMarco Nelissen memset(&mCharsValue, 0, sizeof(mCharsValue)); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::type XMLNode::getType() const 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mElementName.size() != 0) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TYPE_ELEMENT; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNamespaceUri.size() != 0) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TYPE_NAMESPACE; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TYPE_CDATA; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getNamespacePrefix() const 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNamespacePrefix; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getNamespaceUri() const 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNamespaceUri; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getElementNamespace() const 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNamespaceUri; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getElementName() const 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mElementName; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst Vector<sp<XMLNode> >& XMLNode::getChildren() const 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChildren; 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 65462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackbornconst String8& XMLNode::getFilename() const 65562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn{ 65662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return mFilename; 65762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn} 65862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst Vector<XMLNode::attribute_entry>& 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLNode::getAttributes() const 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAttributes; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 66562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackbornconst XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns, 66662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn const String16& name) const 66762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn{ 66862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn for (size_t i=0; i<mAttributes.size(); i++) { 66962da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn const attribute_entry& ae(mAttributes.itemAt(i)); 67062da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn if (ae.ns == ns && ae.name == name) { 67162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return &ae; 67262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 67362da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 67462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 67562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return NULL; 67662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn} 67762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 6782fee0ed6eb99b211efa06f095a41268a2021214aJeff HamiltonXMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns, 6792fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton const String16& name) 6802fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton{ 6812fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton for (size_t i=0; i<mAttributes.size(); i++) { 6822fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton attribute_entry * ae = &mAttributes.editItemAt(i); 6832fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton if (ae->ns == ns && ae->name == name) { 6842fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton return ae; 6852fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton } 6862fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton } 6872fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton 6882fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton return NULL; 6892fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton} 6902fee0ed6eb99b211efa06f095a41268a2021214aJeff Hamilton 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getCData() const 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChars; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst String16& XMLNode::getComment() const 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mComment; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t XMLNode::getStartLineNumber() const 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStartLineNumber; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t XMLNode::getEndLineNumber() const 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEndLineNumber; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackbornsp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName) 71262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn{ 71362da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn if (getType() == XMLNode::TYPE_ELEMENT 71462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn && mNamespaceUri == tagNamespace 71562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn && mElementName == tagName) { 71662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return this; 71762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 71862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 71962da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn for (size_t i=0; i<mChildren.size(); i++) { 72062da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName); 72162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn if (found != NULL) { 72262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return found; 72362da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 72462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 72562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 72662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return NULL; 72762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn} 72862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 72962da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackbornsp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName) 73062da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn{ 73162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn for (size_t i=0; i<mChildren.size(); i++) { 73262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn sp<XMLNode> child = mChildren.itemAt(i); 73362da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn if (child->getType() == XMLNode::TYPE_ELEMENT 73462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn && child->mNamespaceUri == tagNamespace 73562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn && child->mElementName == tagName) { 73662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return child; 73762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 73862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 73962da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 74062da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return NULL; 74162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn} 74262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::addChild(const sp<XMLNode>& child) 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() == TYPE_CDATA) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node."); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Adding child %p to parent %p\n", child.get(), this); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.add(child); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackbornstatus_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index) 75562da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn{ 75662da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn if (getType() == TYPE_CDATA) { 75762da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node."); 75862da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return UNKNOWN_ERROR; 75962da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn } 76062da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn //printf("Adding child %p to parent %p\n", child.get(), this); 76162da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn mChildren.insertAt(child, index); 76262da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn return NO_ERROR; 76362da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn} 76462da8461ed5317fe78ae5e3793662694e7fc99a3Dianne Hackborn 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::addAttribute(const String16& ns, const String16& name, 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16& value) 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() == TYPE_CDATA) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(mFilename, getStartLineNumber()).error("Child to CDATA node."); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 772f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet 773f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (ns != RESOURCES_TOOLS_NAMESPACE) { 774f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet attribute_entry e; 775f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet e.index = mNextAttributeIndex++; 776f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet e.ns = ns; 777f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet e.name = name; 778f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet e.string = value; 779f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet mAttributes.add(e); 780f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet mAttributeOrder.add(e.index, mAttributes.size()-1); 781f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId) 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attribute_entry& e = mAttributes.editItemAt(attrIdx); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e.nameResId) { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttributeOrder.removeItem(e.nameResId); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttributeOrder.removeItem(e.index); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Elem %s %s=\"%s\": set res id = 0x%08x\n", 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(getElementName()).string(), 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(mAttributes.itemAt(attrIdx).name).string(), 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(mAttributes.itemAt(attrIdx).string).string(), 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resId)); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttributes.editItemAt(attrIdx).nameResId = resId; 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAttributeOrder.add(resId, attrIdx); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::appendChars(const String16& chars) 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() != TYPE_CDATA) { 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(mFilename, getStartLineNumber()).error("Adding characters to element node."); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChars.append(chars); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::appendComment(const String16& comment) 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mComment.size() > 0) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComment.append(String16("\n")); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComment.append(comment); 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLNode::setStartLineNumber(int32_t line) 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStartLineNumber = line; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLNode::setEndLineNumber(int32_t line) 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEndLineNumber = line; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLNode::removeWhitespace(bool stripAll, const char** cDataTags) 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Removing whitespace in %s\n", String8(mElementName).string()); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = mChildren.size(); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cDataTags) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 tag(mElementName); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char** p = cDataTags; 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*p) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tag == *p) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stripAll = false; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = mChildren.itemAt(i); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (node->getType() == TYPE_CDATA) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a CDATA node... 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = node->mChars.string(); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*p != 0 && *p < 128 && isspace(*p)) { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Space ends at %d in \"%s\"\n", 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (int)(p-node->mChars.string()), 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(node->mChars).string()); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == 0) { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stripAll) { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove this node! 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.removeAt(i); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N--; 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->mChars = String16(" "); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Compact leading/trailing whitespace. 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* e = node->mChars.string()+node->mChars.size()-1; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (e > p && *e < 128 && isspace(*e)) { 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e--; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p > node->mChars.string()) { 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p--; 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e < (node->mChars.string()+node->mChars.size()-1)) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e++; 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p > node->mChars.string() || 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e < (node->mChars.string()+node->mChars.size()-1)) { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 tmp(p, e-p+1); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->mChars = tmp; 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->removeWhitespace(stripAll, cDataTags); 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::parseValues(const sp<AaptAssets>& assets, 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResourceTable* table) 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasErrors = false; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() == TYPE_ELEMENT) { 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = mAttributes.size(); 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 defPackage(assets->getPackage()); 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attribute_entry& e = mAttributes.editItemAt(i); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name), 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.string)); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber())); 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!assets->getIncludedResources() 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .stringToValue(&e.value, &e.string, 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.string.string(), e.string.size(), true, true, 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.nameResId, NULL, &defPackage, table, &ac)) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasErrors = true; 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Attr %s: type=0x%x, str=%s\n", 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.name).string(), e.value.dataType, 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.string).string())); 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = mChildren.size(); 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = mChildren.itemAt(i)->parseValues(assets, table); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasErrors = true; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets, 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResourceTable* table) 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasErrors = false; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() == TYPE_ELEMENT) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 attr("attr"); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* errorMsg; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = mAttributes.size(); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& e = mAttributes.itemAt(i); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e.ns.size() <= 0) continue; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool nsIsPublic; 936e348909c1966c3d192841cc131a32be6ed90da18inazaruk String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic)); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n", 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(getElementName()).string(), 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.name).string(), 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.string).string(), 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.ns).string(), 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (nsIsPublic) ? "public" : "private", 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(pkg).string())); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pkg.size() <= 0) continue; 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t res = table != NULL 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic) 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : assets->getIncludedResources(). 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project identifierForName(e.name.string(), e.name.size(), 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.string(), attr.size(), 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pkg.string(), pkg.size()); 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res != 0) { 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("XML attribute name %s: resid=0x%08x\n", 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.name).string(), res)); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setAttributeResID(i, res); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SourcePos(mFilename, getStartLineNumber()).error( 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "No resource identifier found for attribute '%s' in package '%s'\n", 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(e.name).string(), String8(pkg).string()); 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasErrors = true; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = mChildren.size(); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasErrors = true; 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::flatten(const sp<AaptFile>& dest, 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool stripComments, bool stripRawValues) const 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 977345b7eb8749d6954942fd4e961fff9f2f854934cJeff Brown StringPool strings(mUTF8); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<uint32_t> resids; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First collect just the strings for attribute names that have a 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // resource ID assigned to them. This ensures that the resource ID 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // array is compact, and makes it easier to deal with attribute names 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in different namespaces (and thus with different resource IDs). 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collect_resid_strings(&strings, &resids); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Next collect all remainibng strings. 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collect_strings(&strings, &resids, stripComments, stripRawValues); 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 // No longer compiles 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Found strings:\n"); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = strings.size(); 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s\n", String8(strings.entryAt(i).string).string()); 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<AaptFile> stringPool = strings.createStringBlock(); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(aout << "String pool:" 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << HexDump(stringPool->getData(), stringPool->getSize()) << endl); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_header header; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&header, 0, sizeof(header)); 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header.header.type = htods(RES_XML_TYPE); 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header.header.headerSize = htods(sizeof(header)); 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t basePos = dest->getSize(); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->writeData(&header, sizeof(header)); 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->writeData(stringPool->getData(), stringPool->getSize()); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we have resource IDs, write them. 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resids.size() > 0) { 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t resIdsPos = dest->getSize(); 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t resIdsSize = 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size()); 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResChunk_header* idsHeader = (ResChunk_header*) 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE); 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idsHeader->headerSize = htods(sizeof(*idsHeader)); 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idsHeader->size = htodl(resIdsSize); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* ids = (uint32_t*)(idsHeader+1); 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<resids.size(); i++) { 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *ids++ = htodl(resids[i]); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flatten_node(strings, dest, stripComments, stripRawValues); 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* data = dest->editData(); 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos); 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size = dest->getSize()-basePos; 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hd->header.size = htodl(dest->getSize()-basePos); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(aout << "XML resource:" 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << HexDump(dest->getData(), dest->getSize()) << endl); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if PRINT_STRING_METRICS 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "**** total xml size: %d / %d%% strings (in %s)\n", 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->getSize(), (stringPool->getSize()*100)/dest->getSize(), 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->getPath().string()); 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLNode::print(int indent) 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 prefix; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<indent; i++) { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prefix.append(" "); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getType() == TYPE_ELEMENT) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 elemNs(getNamespaceUri()); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (elemNs.size() > 0) { 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project elemNs.append(":"); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s E: %s%s", prefix.string(), 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project elemNs.string(), String8(getElementName()).string()); 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mAttributes.size(); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<N; i++) { 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = mAttributeOrder.valueAt(i); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == 0) { 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" / "); 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(", "); 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& attr = mAttributes.itemAt(idx); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 attrNs(attr.ns); 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attrNs.size() > 0) { 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrNs.append(":"); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attr.nameResId) { 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s%s(0x%08x)", attrNs.string(), 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(attr.name).string(), attr.nameResId); 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s%s", attrNs.string(), String8(attr.name).string()); 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("=%s", String8(attr.string).string()); 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (getType() == TYPE_NAMESPACE) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s N: %s=%s\n", prefix.string(), 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getNamespacePrefix().size() > 0 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? String8(getNamespacePrefix()).string() : "<DEF>", 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(getNamespaceUri()).string()); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string()); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mChildren.size(); 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<N; i++) { 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.itemAt(i)->print(indent+1); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void splitName(const char* name, String16* outNs, String16* outName) 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* p = name; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*p != 0 && *p != 1) { 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == 0) { 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outNs = String16(); 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outName = String16(name); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outNs = String16(name, (p-name)); 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outName = String16(p+1); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::startNamespace(void *userData, const char *prefix, const char *uri) 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("Start Namespace: %s %s\n", prefix, uri)); 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = XMLNode::newNamespace(st->filename, 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16(prefix != NULL ? prefix : ""), String16(uri)); 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->stack.size() > 0) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.itemAt(st->stack.size()-1)->addChild(node); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->root = node; 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.push(node); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::startElement(void *userData, const char *name, const char **atts) 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("Start Element: %s\n", name)); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 ns16, name16; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project splitName(name, &ns16, &name16); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16); 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->pendingComment.size() > 0) { 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->appendComment(st->pendingComment); 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->pendingComment = String16(); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->stack.size() > 0) { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.itemAt(st->stack.size()-1)->addChild(node); 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->root = node; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.push(node); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; atts[i]; i += 2) { 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project splitName(atts[i], &ns16, &name16); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->addAttribute(ns16, name16, String16(atts[i+1])); 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::characterData(void *userData, const XML_Char *s, int len) 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("CDATA: \"%s\"\n", String8(s, len).string())); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = NULL; 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->stack.size() == 0) { 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1); 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parent != NULL && parent->getChildren().size() > 0) { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node = parent->getChildren()[parent->getChildren().size()-1]; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (node->getType() != TYPE_CDATA) { 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last node is not CDATA, need to make a new node. 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node = NULL; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (node == NULL) { 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node = XMLNode::newCData(st->filename); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser)); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent->addChild(node); 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->appendChars(String16(s, len)); 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::endElement(void *userData, const char *name) 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("End Element: %s\n", name)); 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1); 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser)); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->pendingComment.size() > 0) { 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->appendComment(st->pendingComment); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->pendingComment = String16(); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 ns16, name16; 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project splitName(name, &ns16, &name16); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || node->getElementName() != name16, 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Bad end element %s", name); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.pop(); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::endNamespace(void *userData, const char *prefix) 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* nonNullPrefix = prefix != NULL ? prefix : ""; 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("End Namespace: %s\n", prefix)); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser)); 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix), 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Bad end namespace %s", prefix); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->stack.pop(); 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid XMLCALL 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectXMLNode::commentData(void *userData, const char *comment) 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY_PARSE(printf("Comment: %s\n", comment)); 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParseState* st = (ParseState*)userData; 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st->pendingComment.size() > 0) { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->pendingComment.append(String16("\n")); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st->pendingComment.append(String16(comment)); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds, 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool stripComments, bool stripRawValues) const 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collect_attr_strings(dest, outResIds, true); 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 1229f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) { 1230f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (mNamespacePrefix.size() > 0) { 1231f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->add(mNamespacePrefix, true); 1232f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 1233f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (mNamespaceUri.size() > 0) { 1234f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->add(mNamespaceUri, true); 1235f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mElementName.size() > 0) { 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(mElementName, true); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!stripComments && mComment.size() > 0) { 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(mComment, true); 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int NA = mAttributes.size(); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<NA; i++) { 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& ae = mAttributes.itemAt(i); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.ns.size() > 0) { 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(ae.ns, true); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!stripRawValues || ae.needStringValue()) { 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(ae.string, true); 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.value.dataType == Res_value::TYPE_NULL 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || ae.value.dataType == Res_value::TYPE_STRING) { 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(ae.string, true); 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mElementName.size() == 0) { 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If not an element, include the CDATA, even if it is empty. 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->add(mChars, true); 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int NC = mChildren.size(); 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<NC; i++) { 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.itemAt(i)->collect_strings(dest, outResIds, 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stripComments, stripRawValues); 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::collect_attr_strings(StringPool* outPool, 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<uint32_t>* outResIds, bool allAttrs) const { 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int NA = mAttributes.size(); 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<NA; i++) { 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& attr = mAttributes.itemAt(i); 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t id = attr.nameResId; 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id || allAttrs) { 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See if we have already assigned this resource ID to a pooled 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // string... 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Vector<size_t>* indices = outPool->offsetsForString(attr.name); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = -1; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (indices != NULL) { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int NJ = indices->size(); 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NR = outResIds->size(); 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0; j<NJ; j++) { 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t strIdx = indices->itemAt(j); 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strIdx >= NR) { 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We don't need to assign a resource ID for this one. 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx = strIdx; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Just ignore strings that are out of range of 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the currently assigned resource IDs... we add 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // strings as we assign the first ID. 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (outResIds->itemAt(strIdx) == id) { 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx = strIdx; 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < 0) { 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx = outPool->add(attr.name); 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("Adding attr %s (resid 0x%08x) to pool: idx=%d\n", 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(attr.name).string(), id, idx)); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id != 0) { 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((ssize_t)outResIds->size() <= idx) { 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outResIds->add(0); 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outResIds->replaceAt(id, idx); 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.namePoolIdx = idx; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NOISY(printf("String %s offset=0x%08x\n", 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(attr.name).string(), idx)); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::collect_resid_strings(StringPool* outPool, 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<uint32_t>* outResIds) const 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collect_attr_strings(outPool, outResIds, false); 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int NC = mChildren.size(); 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<NC; i++) { 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds); 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest, 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool stripComments, bool stripRawValues) const 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_node node; 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_cdataExt cdataExt; 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_namespaceExt namespaceExt; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_attrExt attrExt; 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* extData = NULL; 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t extSize = 0; 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_attribute attr; 1354f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet bool writeCurrentNode = true; 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NA = mAttributes.size(); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NC = mChildren.size(); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i; 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), "Attributes messed up!"); 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16 id16("id"); 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16 class16("class"); 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16 style16("style"); 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const type type = getType(); 1367f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&node, 0, sizeof(node)); 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&attr, 0, sizeof(attr)); 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.headerSize = htods(sizeof(node)); 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.lineNumber = htodl(getStartLineNumber()); 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!stripComments) { 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.comment.index = htodl( 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComment.size() > 0 ? strings.offsetForString(mComment) : -1); 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //if (mComment.size() > 0) { 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // printf("Flattening comment: %s\n", String8(mComment).string()); 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //} 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.comment.index = htodl((uint32_t)-1); 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == TYPE_ELEMENT) { 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.type = htods(RES_XML_START_ELEMENT_TYPE); 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extData = &attrExt; 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extSize = sizeof(attrExt); 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&attrExt, 0, sizeof(attrExt)); 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNamespaceUri.size() > 0) { 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri)); 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.ns.index = htodl((uint32_t)-1); 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.name.index = htodl(strings.offsetForString(mElementName)); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.attributeStart = htods(sizeof(attrExt)); 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.attributeSize = htods(sizeof(attr)); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.attributeCount = htods(NA); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.idIndex = htods(0); 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.classIndex = htods(0); 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.styleIndex = htods(0); 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<NA; i++) { 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = mAttributeOrder.valueAt(i); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& ae = mAttributes.itemAt(idx); 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.ns.size() == 0) { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.name == id16) { 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.idIndex = htods(i+1); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ae.name == class16) { 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.classIndex = htods(i+1); 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ae.name == style16) { 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrExt.styleIndex = htods(i+1); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == TYPE_NAMESPACE) { 1412f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (mNamespaceUri == RESOURCES_TOOLS_NAMESPACE) { 1413f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet writeCurrentNode = false; 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1415f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet node.header.type = htods(RES_XML_START_NAMESPACE_TYPE); 1416f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet extData = &namespaceExt; 1417f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet extSize = sizeof(namespaceExt); 1418f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet memset(&namespaceExt, 0, sizeof(namespaceExt)); 1419f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (mNamespacePrefix.size() > 0) { 1420f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix)); 1421f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } else { 1422f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet namespaceExt.prefix.index = htodl((uint32_t)-1); 1423f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 1424f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix)); 1425f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri)); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(NA != 0, "Namespace nodes can't have attributes!"); 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == TYPE_CDATA) { 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.type = htods(RES_XML_CDATA_TYPE); 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extData = &cdataExt; 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extSize = sizeof(cdataExt); 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&cdataExt, 0, sizeof(cdataExt)); 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cdataExt.data.index = htodl(strings.offsetForString(mChars)); 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cdataExt.typedData.size = htods(sizeof(cdataExt.typedData)); 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cdataExt.typedData.res0 = 0; 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cdataExt.typedData.dataType = mCharsValue.dataType; 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cdataExt.typedData.data = htodl(mCharsValue.data); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(NA != 0, "CDATA nodes can't have attributes!"); 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA)); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1443f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (writeCurrentNode) { 1444f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->writeData(&node, sizeof(node)); 1445f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (extSize > 0) { 1446f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->writeData(extData, extSize); 1447f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<NA; i++) { 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t idx = mAttributeOrder.valueAt(i); 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const attribute_entry& ae = mAttributes.itemAt(idx); 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.ns.size() > 0) { 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.ns.index = htodl(strings.offsetForString(ae.ns)); 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.ns.index = htodl((uint32_t)-1); 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.name.index = htodl(ae.namePoolIdx); 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!stripRawValues || ae.needStringValue()) { 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.rawValue.index = htodl(strings.offsetForString(ae.string)); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.rawValue.index = htodl((uint32_t)-1); 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.size = htods(sizeof(attr.typedValue)); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ae.value.dataType == Res_value::TYPE_NULL 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || ae.value.dataType == Res_value::TYPE_STRING) { 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.res0 = 0; 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.dataType = Res_value::TYPE_STRING; 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.data = htodl(strings.offsetForString(ae.string)); 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.res0 = 0; 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.dataType = ae.value.dataType; 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attr.typedValue.data = htodl(ae.value.data); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->writeData(&attr, sizeof(attr)); 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<NC; i++) { 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = mChildren.itemAt(i)->flatten_node(strings, dest, 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stripComments, stripRawValues); 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == TYPE_ELEMENT) { 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResXMLTree_endElementExt endElementExt; 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&endElementExt, 0, sizeof(endElementExt)); 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.type = htods(RES_XML_END_ELEMENT_TYPE); 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.header.size = htodl(sizeof(node)+sizeof(endElementExt)); 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.lineNumber = htodl(getEndLineNumber()); 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.comment.index = htodl((uint32_t)-1); 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endElementExt.ns.index = attrExt.ns.index; 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endElementExt.name.index = attrExt.name.index; 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->writeData(&node, sizeof(node)); 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest->writeData(&endElementExt, sizeof(endElementExt)); 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == TYPE_NAMESPACE) { 1499f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet if (writeCurrentNode) { 1500f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet node.header.type = htods(RES_XML_END_NAMESPACE_TYPE); 1501f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet node.lineNumber = htodl(getEndLineNumber()); 1502f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet node.comment.index = htodl((uint32_t)-1); 1503f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet node.header.size = htodl(sizeof(node)+extSize); 1504f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->writeData(&node, sizeof(node)); 1505f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet dest->writeData(extData, extSize); 1506f8aea99385df8373b6edd6d5dd1d15b7b36b525bXavier Ducrohet } 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1511