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