2 * Copyright (C) 2014 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <androidfw/ResourceTypes.h>
18 #include <utils/String8.h>
22 using namespace android;
26 static String8 getStringAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,
29 if (tree.getAttributeValue(attrIndex, &value) < 0) {
30 if (outError != NULL) {
31 *outError = "could not find attribute at index";
36 if (value.dataType != Res_value::TYPE_STRING) {
37 if (outError != NULL) {
38 *outError = "attribute is not a string value";
44 const char16_t* str = tree.getAttributeStringValue(attrIndex, &len);
45 return str ? String8(str, len) : String8();
48 static int32_t getIntegerAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,
49 int32_t defValue, String8* outError) {
51 if (tree.getAttributeValue(attrIndex, &value) < 0) {
52 if (outError != NULL) {
53 *outError = "could not find attribute at index";
58 if (value.dataType < Res_value::TYPE_FIRST_INT
59 || value.dataType > Res_value::TYPE_LAST_INT) {
60 if (outError != NULL) {
61 *outError = "attribute is not an integer value";
69 ssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) {
70 size_t attrCount = tree.getAttributeCount();
71 for (size_t i = 0; i < attrCount; i++) {
72 if (tree.getAttributeNameResID(i) == attrRes) {
79 String8 getAttribute(const ResXMLTree& tree, const char* ns,
80 const char* attr, String8* outError) {
81 ssize_t idx = tree.indexOfAttribute(ns, attr);
85 return getStringAttributeAtIndex(tree, idx, outError);
88 String8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) {
89 ssize_t idx = indexOfAttribute(tree, attrRes);
93 return getStringAttributeAtIndex(tree, idx, outError);
96 String8 getResolvedAttribute(const ResTable& resTable, const ResXMLTree& tree,
97 uint32_t attrRes, String8* outError) {
98 ssize_t idx = indexOfAttribute(tree, attrRes);
103 if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
104 if (value.dataType == Res_value::TYPE_STRING) {
106 const char16_t* str = tree.getAttributeStringValue(idx, &len);
107 return str ? String8(str, len) : String8();
109 resTable.resolveReference(&value, 0);
110 if (value.dataType != Res_value::TYPE_STRING) {
111 if (outError != NULL) {
112 *outError = "attribute is not a string value";
118 const Res_value* value2 = &value;
119 const char16_t* str = resTable.valueToString(value2, 0, NULL, &len);
120 return str ? String8(str, len) : String8();
123 int32_t getIntegerAttribute(const ResXMLTree& tree, const char* ns,
124 const char* attr, int32_t defValue, String8* outError) {
125 ssize_t idx = tree.indexOfAttribute(ns, attr);
129 return getIntegerAttributeAtIndex(tree, idx, defValue, outError);
132 int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, int32_t defValue,
134 ssize_t idx = indexOfAttribute(tree, attrRes);
138 return getIntegerAttributeAtIndex(tree, idx, defValue, outError);
141 int32_t getResolvedIntegerAttribute(const ResTable& resTable, const ResXMLTree& tree,
142 uint32_t attrRes, int32_t defValue, String8* outError) {
143 ssize_t idx = indexOfAttribute(tree, attrRes);
148 if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
149 if (value.dataType == Res_value::TYPE_REFERENCE) {
150 resTable.resolveReference(&value, 0);
152 if (value.dataType < Res_value::TYPE_FIRST_INT
153 || value.dataType > Res_value::TYPE_LAST_INT) {
154 if (outError != NULL) {
155 *outError = "attribute is not an integer value";
163 void getResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree,
164 uint32_t attrRes, Res_value* outValue, String8* outError) {
165 ssize_t idx = indexOfAttribute(tree, attrRes);
167 if (outError != NULL) {
168 *outError = "attribute could not be found";
172 if (tree.getAttributeValue(idx, outValue) != NO_ERROR) {
173 if (outValue->dataType == Res_value::TYPE_REFERENCE) {
174 resTable.resolveReference(outValue, 0);
176 // The attribute was found and was resolved if need be.
179 if (outError != NULL) {
180 *outError = "error getting resolved resource attribute";
184 } // namespace AaptXml