16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "Resource.h"
18a587065721053ad54e34f484868142407d59512dAdam Lesinski#include "ResourceUtils.h"
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ResourceValues.h"
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ValueVisitor.h"
21355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski#include "io/File.h"
22e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski#include "util/Util.h"
23e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <androidfw/ResourceTypes.h>
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <limits>
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename Derived>
301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BaseValue<Derived>::accept(RawValueVisitor* visitor) {
311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    visitor->visit(static_cast<Derived*>(this));
321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename Derived>
351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BaseItem<Derived>::accept(RawValueVisitor* visitor) {
361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    visitor->visit(static_cast<Derived*>(this));
371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiRawString::RawString(const StringPool::Ref& ref) : value(ref) {
406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
42769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiRawString* RawString::clone(StringPool* newPool) const {
43b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    RawString* rs = new RawString(newPool->makeRef(*value));
44b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    rs->mComment = mComment;
45b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    rs->mSource = mSource;
46b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    return rs;
476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool RawString::flatten(android::Res_value* outValue) const {
5059e04c6f92da584b322c87072f18e6cab4de4c60Adam Lesinski    outValue->dataType = android::Res_value::TYPE_STRING;
511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid RawString::print(std::ostream* out) const {
561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(raw string) " << *value;
576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiReference::Reference() : referenceType(Reference::Type::kResource) {
606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiReference::Reference(const ResourceNameRef& n, Type t) :
636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        name(n.toResourceName()), referenceType(t) {
646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiReference::Reference(const ResourceId& i, Type type) : id(i), referenceType(type) {
676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool Reference::flatten(android::Res_value* outValue) const {
70467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    outValue->dataType = (referenceType == Reference::Type::kResource) ?
71467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski            android::Res_value::TYPE_REFERENCE : android::Res_value::TYPE_ATTRIBUTE;
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(id ? id.value().id : 0);
736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
76769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiReference* Reference::clone(StringPool* /*newPool*/) const {
77467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    return new Reference(*this);
786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Reference::print(std::ostream* out) const {
811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(reference) ";
826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (referenceType == Reference::Type::kResource) {
831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "@";
84467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski        if (privateReference) {
85467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski            *out << "*";
86467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski        }
876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else {
881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "?";
896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
911ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    if (name) {
921ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << name.value();
936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    if (id && !Res_INTERNALID(id.value().id)) {
961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << " " << id.value();
976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool Id::flatten(android::Res_value* out) const {
1011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
1021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    out->data = util::hostToDevice32(0);
1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
106769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiId* Id::clone(StringPool* /*newPool*/) const {
107467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    return new Id(*this);
1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Id::print(std::ostream* out) const {
1111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(id)";
1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
114393b5f0d6130d3848dd82075986a5cf40c09ce44Adam LesinskiString::String(const StringPool::Ref& ref) : value(ref), mTranslateable(true) {
115393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
116393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
117393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinskivoid String::setTranslateable(bool val) {
118393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    mTranslateable = val;
119393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
120393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
121393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinskibool String::isTranslateable() const {
122393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    return mTranslateable;
1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool String::flatten(android::Res_value* outValue) const {
1261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    // Verify that our StringPool index is within encode-able limits.
1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->dataType = android::Res_value::TYPE_STRING;
1321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
136769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiString* String::clone(StringPool* newPool) const {
137b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    String* str = new String(newPool->makeRef(*value));
138b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    str->mComment = mComment;
139b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    str->mSource = mSource;
140b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    return str;
1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid String::print(std::ostream* out) const {
1441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(string) \"" << *value << "\"";
1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
147393b5f0d6130d3848dd82075986a5cf40c09ce44Adam LesinskiStyledString::StyledString(const StringPool::StyleRef& ref) : value(ref), mTranslateable(true) {
148393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
149393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
150393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinskivoid StyledString::setTranslateable(bool val) {
151393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    mTranslateable = val;
152393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
153393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
154393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinskibool StyledString::isTranslateable() const {
155393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    return mTranslateable;
1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool StyledString::flatten(android::Res_value* outValue) const {
1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->dataType = android::Res_value::TYPE_STRING;
1641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
1666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
168769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiStyledString* StyledString::clone(StringPool* newPool) const {
169b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    StyledString* str = new StyledString(newPool->makeRef(value));
170b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    str->mComment = mComment;
171b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    str->mSource = mSource;
172b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    return str;
1736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid StyledString::print(std::ostream* out) const {
1761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(styled string) \"" << *value->str << "\"";
1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiFileReference::FileReference(const StringPool::Ref& _path) : path(_path) {
1806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool FileReference::flatten(android::Res_value* outValue) const {
1836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (path.getIndex() > std::numeric_limits<uint32_t>::max()) {
1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
1856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1871ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->dataType = android::Res_value::TYPE_STRING;
1881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(static_cast<uint32_t>(path.getIndex()));
1896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
1906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
192769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiFileReference* FileReference::clone(StringPool* newPool) const {
193b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    FileReference* fr = new FileReference(newPool->makeRef(*path));
194355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski    fr->file = file;
195b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    fr->mComment = mComment;
196b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    fr->mSource = mSource;
197b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    return fr;
1986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid FileReference::print(std::ostream* out) const {
2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(file) " << *path;
2026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiBinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {
2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2071ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiBinaryPrimitive::BinaryPrimitive(uint8_t dataType, uint32_t data) {
2081ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    value.dataType = dataType;
2091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    value.data = data;
2101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
2111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool BinaryPrimitive::flatten(android::Res_value* outValue) const {
2131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->dataType = value.dataType;
2141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    outValue->data = util::hostToDevice32(value.data);
2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
218769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiBinaryPrimitive* BinaryPrimitive::clone(StringPool* /*newPool*/) const {
219467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    return new BinaryPrimitive(*this);
2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BinaryPrimitive::print(std::ostream* out) const {
2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    switch (value.dataType) {
2246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_NULL:
2251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "(null)";
2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_DEC:
228a587065721053ad54e34f484868142407d59512dAdam Lesinski            *out << "(integer) " << static_cast<int32_t>(value.data);
2296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_HEX:
2311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "(integer) " << std::hex << value.data << std::dec;
2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_BOOLEAN:
2341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "(boolean) " << (value.data != 0 ? "true" : "false");
2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_COLOR_ARGB8:
2376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_COLOR_RGB8:
2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_COLOR_ARGB4:
2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        case android::Res_value::TYPE_INT_COLOR_RGB4:
2401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "(color) #" << std::hex << value.data << std::dec;
2416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        default:
2431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "(unknown 0x" << std::hex << (int) value.dataType << ") 0x"
2441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski                 << std::hex << value.data << std::dec;
2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            break;
2466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
249a587065721053ad54e34f484868142407d59512dAdam LesinskiAttribute::Attribute(bool w, uint32_t t) :
250393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski        typeMask(t),
251a587065721053ad54e34f484868142407d59512dAdam Lesinski        minInt(std::numeric_limits<int32_t>::min()),
252a587065721053ad54e34f484868142407d59512dAdam Lesinski        maxInt(std::numeric_limits<int32_t>::max()) {
253393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    mWeak = w;
2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
256769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiAttribute* Attribute::clone(StringPool* /*newPool*/) const {
257467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    return new Attribute(*this);
2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Attribute::printMask(std::ostream* out) const {
2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (typeMask == android::ResTable_map::TYPE_ANY) {
2621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "any";
2636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return;
2646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    bool set = false;
2676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) {
2686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
2711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
2731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "reference";
2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) {
2776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
2786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
2801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
2816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
2821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "string";
2836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) {
2866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
2876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
2886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
2891ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
2906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
2911ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "integer";
2926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
2956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
2966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
2976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
2981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
2996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "boolean";
3016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) {
3046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "color";
3106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) {
3136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "float";
3196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) {
3226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "dimension";
3286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) {
3316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "fraction";
3376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) {
3406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "enum";
3466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) {
3496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (!set) {
3506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            set = true;
3516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        } else {
3521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            *out << "|";
3536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
3541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << "flags";
3556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
356330edcdf1316ed599fe0eb16a64330821fd92f18Adam Lesinski}
357330edcdf1316ed599fe0eb16a64330821fd92f18Adam Lesinski
3581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Attribute::print(std::ostream* out) const {
3591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(attr) ";
360330edcdf1316ed599fe0eb16a64330821fd92f18Adam Lesinski    printMask(out);
3616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    if (!symbols.empty()) {
3631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << " ["
3641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            << util::joiner(symbols.begin(), symbols.end(), ", ")
3651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            << "]";
3661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
3676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
368393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski    if (isWeak()) {
3691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << " [weak]";
3706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
373a587065721053ad54e34f484868142407d59512dAdam Lesinskistatic void buildAttributeMismatchMessage(DiagMessage* msg, const Attribute* attr,
374a587065721053ad54e34f484868142407d59512dAdam Lesinski                                          const Item* value) {
375a587065721053ad54e34f484868142407d59512dAdam Lesinski    *msg << "expected";
376a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_BOOLEAN) {
377a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " boolean";
378a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
379a587065721053ad54e34f484868142407d59512dAdam Lesinski
380a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_COLOR) {
381a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " color";
382a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
383a587065721053ad54e34f484868142407d59512dAdam Lesinski
384a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_DIMENSION) {
385a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " dimension";
386a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
387a587065721053ad54e34f484868142407d59512dAdam Lesinski
388a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_ENUM) {
389a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " enum";
390a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
391a587065721053ad54e34f484868142407d59512dAdam Lesinski
392a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_FLAGS) {
393a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " flags";
394a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
395a587065721053ad54e34f484868142407d59512dAdam Lesinski
396a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_FLOAT) {
397a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " float";
398a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
399a587065721053ad54e34f484868142407d59512dAdam Lesinski
400a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_FRACTION) {
401a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " fraction";
402a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
403a587065721053ad54e34f484868142407d59512dAdam Lesinski
404a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_INTEGER) {
405a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " integer";
406a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
407a587065721053ad54e34f484868142407d59512dAdam Lesinski
408a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_REFERENCE) {
409a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " reference";
410a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
411a587065721053ad54e34f484868142407d59512dAdam Lesinski
412a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (attr->typeMask & android::ResTable_map::TYPE_STRING) {
413a587065721053ad54e34f484868142407d59512dAdam Lesinski        *msg << " string";
414a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
415a587065721053ad54e34f484868142407d59512dAdam Lesinski
416a587065721053ad54e34f484868142407d59512dAdam Lesinski    *msg << " but got " << *value;
417a587065721053ad54e34f484868142407d59512dAdam Lesinski}
418a587065721053ad54e34f484868142407d59512dAdam Lesinski
419a587065721053ad54e34f484868142407d59512dAdam Lesinskibool Attribute::matches(const Item* item, DiagMessage* outMsg) const {
420a587065721053ad54e34f484868142407d59512dAdam Lesinski    android::Res_value val = {};
421a587065721053ad54e34f484868142407d59512dAdam Lesinski    item->flatten(&val);
422a587065721053ad54e34f484868142407d59512dAdam Lesinski
423a587065721053ad54e34f484868142407d59512dAdam Lesinski    // Always allow references.
424a587065721053ad54e34f484868142407d59512dAdam Lesinski    const uint32_t mask = typeMask | android::ResTable_map::TYPE_REFERENCE;
425a587065721053ad54e34f484868142407d59512dAdam Lesinski    if (!(mask & ResourceUtils::androidTypeToAttributeTypeMask(val.dataType))) {
426a587065721053ad54e34f484868142407d59512dAdam Lesinski        if (outMsg) {
427a587065721053ad54e34f484868142407d59512dAdam Lesinski            buildAttributeMismatchMessage(outMsg, this, item);
428a587065721053ad54e34f484868142407d59512dAdam Lesinski        }
429a587065721053ad54e34f484868142407d59512dAdam Lesinski        return false;
430a587065721053ad54e34f484868142407d59512dAdam Lesinski
431a587065721053ad54e34f484868142407d59512dAdam Lesinski    } else if (ResourceUtils::androidTypeToAttributeTypeMask(val.dataType) &
432a587065721053ad54e34f484868142407d59512dAdam Lesinski            android::ResTable_map::TYPE_INTEGER) {
433a587065721053ad54e34f484868142407d59512dAdam Lesinski        if (static_cast<int32_t>(util::deviceToHost32(val.data)) < minInt) {
434a587065721053ad54e34f484868142407d59512dAdam Lesinski            if (outMsg) {
435a587065721053ad54e34f484868142407d59512dAdam Lesinski                *outMsg << *item << " is less than minimum integer " << minInt;
436a587065721053ad54e34f484868142407d59512dAdam Lesinski            }
437a587065721053ad54e34f484868142407d59512dAdam Lesinski            return false;
438a587065721053ad54e34f484868142407d59512dAdam Lesinski        } else if (static_cast<int32_t>(util::deviceToHost32(val.data)) > maxInt) {
439a587065721053ad54e34f484868142407d59512dAdam Lesinski            if (outMsg) {
440a587065721053ad54e34f484868142407d59512dAdam Lesinski                *outMsg << *item << " is greater than maximum integer " << maxInt;
441a587065721053ad54e34f484868142407d59512dAdam Lesinski            }
442a587065721053ad54e34f484868142407d59512dAdam Lesinski            return false;
443a587065721053ad54e34f484868142407d59512dAdam Lesinski        }
444a587065721053ad54e34f484868142407d59512dAdam Lesinski    }
445a587065721053ad54e34f484868142407d59512dAdam Lesinski    return true;
446a587065721053ad54e34f484868142407d59512dAdam Lesinski}
447a587065721053ad54e34f484868142407d59512dAdam Lesinski
448769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiStyle* Style::clone(StringPool* newPool) const {
449bdaa092a193d8ddccbd9ad8434be97878e6ded59Adam Lesinski    Style* style = new Style();
4506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    style->parent = parent;
451bdaa092a193d8ddccbd9ad8434be97878e6ded59Adam Lesinski    style->parentInferred = parentInferred;
452b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    style->mComment = mComment;
453b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    style->mSource = mSource;
4546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    for (auto& entry : entries) {
4556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        style->entries.push_back(Entry{
4566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                entry.key,
457769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski                std::unique_ptr<Item>(entry.value->clone(newPool))
4586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        });
4596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return style;
4616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Style::print(std::ostream* out) const {
4641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(style) ";
4651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    if (parent && parent.value().name) {
46624b8ff0faf7c59323d0171cdd825ca09e712aa1eAdam Lesinski        if (parent.value().privateReference) {
46724b8ff0faf7c59323d0171cdd825ca09e712aa1eAdam Lesinski            *out << "*";
46824b8ff0faf7c59323d0171cdd825ca09e712aa1eAdam Lesinski        }
4691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        *out << parent.value().name.value();
4706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << " ["
4726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << util::joiner(entries.begin(), entries.end(), ", ")
4736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << "]";
4746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) {
4771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    if (value.key.name) {
4781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        out << value.key.name.value();
4791ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    } else {
4801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        out << "???";
4811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
4821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    out << " = ";
4831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    value.value->print(&out);
4846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return out;
4856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
487769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiArray* Array::clone(StringPool* newPool) const {
4886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    Array* array = new Array();
489b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    array->mComment = mComment;
490b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    array->mSource = mSource;
4916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    for (auto& item : items) {
492769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski        array->items.emplace_back(std::unique_ptr<Item>(item->clone(newPool)));
4936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return array;
4956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Array::print(std::ostream* out) const {
4981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(array) ["
4996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << util::joiner(items.begin(), items.end(), ", ")
5006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << "]";
5016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
503769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiPlural* Plural::clone(StringPool* newPool) const {
5046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    Plural* p = new Plural();
505b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    p->mComment = mComment;
506b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    p->mSource = mSource;
5076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const size_t count = values.size();
5086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    for (size_t i = 0; i < count; i++) {
5096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (values[i]) {
510769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski            p->values[i] = std::unique_ptr<Item>(values[i]->clone(newPool));
5116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
5126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return p;
5146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Plural::print(std::ostream* out) const {
5171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(plural)";
5186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic ::std::ostream& operator<<(::std::ostream& out, const std::unique_ptr<Item>& item) {
5216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return out << *item;
5226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
524769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam LesinskiStyleable* Styleable::clone(StringPool* /*newPool*/) const {
525467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    return new Styleable(*this);
5266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid Styleable::print(std::ostream* out) const {
5291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    *out << "(styleable) " << " ["
5306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << util::joiner(entries.begin(), entries.end(), ", ")
5316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        << "]";
5326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt
535