ResourceTypes.cpp revision a1d82ff39315c962fbd6839f7a581ffaafe675e4
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "ResourceType" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/ResourceTypes.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ByteOrder.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Debug.h> 24b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <utils/Log.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String16.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/TextOutput.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <memory.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef INT32_MAX 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INT32_MAX ((int32_t)(2147483647)) 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define POOL_NOISY(x) //x 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define XML_NOISY(x) //x 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_NOISY(x) //x 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_GETENTRY(x) //x 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_SUPER_NOISY(x) //x 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOAD_TABLE_NOISY(x) //x 45b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn#define TABLE_THEME(x) //x 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_WINSOCK 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef nhtol 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef htonl 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_LITTLE_ENDIAN 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) ) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htonl(x) ntohl(x) 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) ) 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htons(x) ntohs(x) 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohl(x) (x) 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htonl(x) (x) 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohs(x) (x) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htons(x) (x) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#define IDMAP_MAGIC 0x706d6469 6757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad// size measured in sizeof(uint32_t) 6857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t)) 6957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void printToLogFunc(void* cookie, const char* txt) 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("%s", txt); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Standard C isspace() is only required to look at the low byte of its input, so 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// produces incorrect results for UTF-16 characters. For safety's sake, assume that 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// any high-byte UTF-16 code point is not whitespace. 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline int isspace16(char16_t c) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (c < 0x0080 && isspace(c)); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// range checked; guaranteed to NUL-terminate within the stated number of available slots 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// NOTE: if this truncates the dst string due to running out of space, no attempt is 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// made to avoid splitting surrogate pairs. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail) 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint16_t* last = dst + avail - 1; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*src && (dst < last)) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t s = dtohs(*src); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *dst++ = s; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src++; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *dst = 0; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t validate_chunk(const ResChunk_header* chunk, 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t minSize, 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* dataEnd, 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* name) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(chunk->headerSize); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(chunk->size); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize >= minSize) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize <= size) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((headerSize|size)&0x3) == 0) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1108564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s data size %p extends beyond resource end %p.", 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)size, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dataEnd-((const uint8_t*)chunk))); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1158564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.", 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (int)size, (int)headerSize); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1198564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s size %p is smaller than header size %p.", 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)size, (void*)(int)headerSize); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1238564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s header size %p is too small.", 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)(int)headerSize); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline void Res_value::copyFrom_dtoh(const Res_value& src) 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = dtohs(src.size); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res0 = src.res0; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dataType = src.dataType; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = dtohl(src.data); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::deviceToFile() 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numXDivs; i++) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xDivs[i] = htonl(xDivs[i]); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numYDivs; i++) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yDivs[i] = htonl(yDivs[i]); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingLeft = htonl(paddingLeft); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingRight = htonl(paddingRight); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingTop = htonl(paddingTop); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingBottom = htonl(paddingBottom); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numColors; i++) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = htonl(colors[i]); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::fileToDevice() 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numXDivs; i++) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xDivs[i] = ntohl(xDivs[i]); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numYDivs; i++) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yDivs[i] = ntohl(yDivs[i]); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingLeft = ntohl(paddingLeft); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingRight = ntohl(paddingRight); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingTop = ntohl(paddingTop); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingBottom = ntohl(paddingBottom); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numColors; i++) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = ntohl(colors[i]); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t Res_png_9patch::serializedSize() 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The size of this struct is 32 bytes on the 32-bit target system 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 4 * int8_t 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 4 * int32_t 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 3 * pointer 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 32 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numXDivs * sizeof(int32_t) 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numYDivs * sizeof(int32_t) 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numColors * sizeof(uint32_t); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* Res_png_9patch::serialize() 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // Use calloc since we're going to leave a few holes in the data 1854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // and want this to run cleanly under valgrind 1864df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project void* newData = calloc(1, serializedSize()); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project serialize(newData); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newData; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::serialize(void * outData) 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* data = (char*) outData; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, &wasDeserialized, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data + 12, &paddingLeft, 16); // copy paddingXXXX 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += 32; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->xDivs, numXDivs * sizeof(int32_t)); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += numXDivs * sizeof(int32_t); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->yDivs, numYDivs * sizeof(int32_t)); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += numYDivs * sizeof(int32_t); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->colors, numColors * sizeof(uint32_t)); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void deserializeInternal(const void* inData, Res_png_9patch* outData) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* patch = (char*) inData; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inData != outData) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->wasDeserialized = true; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* data = (char*)outData; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += sizeof(Res_png_9patch); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->xDivs = (int32_t*) data; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += outData->numXDivs * sizeof(int32_t); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->yDivs = (int32_t*) data; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += outData->numYDivs * sizeof(int32_t); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->colors = (uint32_t*) data; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes) 22257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 22357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) { 2246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes); 22557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 22657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 22757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess 2288564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("idmap assertion failed: invalid magic found (is 0x%08x, expected 0x%08x)\n", 22957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *map, htodl(IDMAP_MAGIC)); 23057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 23157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 23257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return true; 23357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 23457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 23557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key, uint32_t* outValue) 23657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 23757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // see README for details on the format of map 23857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, sizeBytes)) { 23957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 24057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 24157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad map = map + IDMAP_HEADER_SIZE; // skip ahead to data segment 24257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // size of data block, in uint32_t 24357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t size = (sizeBytes - ResTable::IDMAP_HEADER_SIZE_BYTES) / sizeof(uint32_t); 24457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t type = Res_GETTYPE(key) + 1; // add one, idmap stores "public" type id 24557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entry = Res_GETENTRY(key); 24657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t typeCount = *map; 24757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 24857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (type > typeCount) { 2498564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Resource ID map: type=%d exceeds number of types=%d\n", type, typeCount); 25057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 25157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 25257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeCount > size) { 2536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size); 25457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 25557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 25657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t typeOffset = map[type]; 25757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeOffset == 0) { 25857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 25957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 26057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 26157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeOffset + 1 > size) { 2628564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n", 2636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn typeOffset, (int)size); 26457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 26557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 26657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entryCount = map[typeOffset]; 26757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entryOffset = map[typeOffset + 1]; 26857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (entryCount == 0 || entry < entryOffset || entry - entryOffset > entryCount - 1) { 26957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 27057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 27157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 27257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t index = typeOffset + 2 + entry - entryOffset; 27357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (index > size) { 2746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size); 27557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 27657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 27757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 27857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = map[index]; 27957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 28057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 28157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 28257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 28357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic status_t getIdmapPackageId(const uint32_t* map, size_t mapSize, uint32_t *outId) 28457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 28557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, mapSize)) { 28657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 28757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 28857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t* p = map + IDMAP_HEADER_SIZE + 1; 28957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad while (*p == 0) { 29057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ++p; 29157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 29257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff; 29357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 29457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 29557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRes_png_9patch* Res_png_9patch::deserialize(const void* inData) 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sizeof(void*) != sizeof(int32_t)) { 2993762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Cannot deserialize on non 32-bit system\n"); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deserializeInternal(inData, (Res_png_9patch*) inData); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (Res_png_9patch*) inData; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResStringPool::ResStringPool() 31119138468caf7050d482dc15f35a344eab11bb756Kenny Root : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL) 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResStringPool::ResStringPool(const void* data, size_t size, bool copyData) 31619138468caf7050d482dc15f35a344eab11bb756Kenny Root : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL) 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTo(data, size, copyData); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResStringPool::~ResStringPool() 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResStringPool::setTo(const void* data, size_t size, bool copyData) 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!data || !size) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool notDeviceEndian = htods(0xf0) != 0xf0; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData || notDeviceEndian) { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = malloc(size); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData == NULL) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mOwnedData, data, size); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = mOwnedData; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader = (const ResStringPool_header*)data; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.headerSize = dtohs(mHeader->header.headerSize); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.type = dtohs(mHeader->header.type); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.size = dtohl(mHeader->header.size); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stringCount = dtohl(mHeader->stringCount); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->styleCount = dtohl(mHeader->styleCount); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->flags = dtohl(mHeader->flags); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stringsStart = dtohl(mHeader->stringsStart); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stylesStart = dtohl(mHeader->stylesStart); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->header.headerSize > mHeader->header.size 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mHeader->header.size > size) { 3618564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: header size %d or total size %d is larger than data size %d\n", 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = mHeader->header.size; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntries = (const uint32_t*) 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->header.headerSize); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stringCount > 0) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount) // uint32 overflow? 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > size) { 3738564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: entry of %d items extends past data size %d\n", 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))), 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)size); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37819138468caf7050d482dc15f35a344eab11bb756Kenny Root 37919138468caf7050d482dc15f35a344eab11bb756Kenny Root size_t charSize; 38019138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mHeader->flags&ResStringPool_header::UTF8_FLAG) { 38119138468caf7050d482dc15f35a344eab11bb756Kenny Root charSize = sizeof(uint8_t); 3827e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**)); 38319138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 38419138468caf7050d482dc15f35a344eab11bb756Kenny Root charSize = sizeof(char16_t); 38519138468caf7050d482dc15f35a344eab11bb756Kenny Root } 38619138468caf7050d482dc15f35a344eab11bb756Kenny Root 38719138468caf7050d482dc15f35a344eab11bb756Kenny Root mStrings = (const void*) 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->stringsStart); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) { 3908564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string pool starts at %d, after total size %d\n", 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stringsStart, (int)mHeader->header.size); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->styleCount == 0) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 39619138468caf7050d482dc15f35a344eab11bb756Kenny Root (mHeader->header.size-mHeader->stringsStart)/charSize; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3985e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root // check invariant: styles starts before end of data 3995e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) { 4008564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad style block: style block starts at %d past data size of %d\n", 4015e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root (int)mHeader->stylesStart, (int)mHeader->header.size); 4025e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root return (mError=BAD_TYPE); 4035e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check invariant: styles follow the strings 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stylesStart <= mHeader->stringsStart) { 4068564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad style block: style block starts at %d, before strings at %d\n", 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stylesStart, (int)mHeader->stringsStart); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 41119138468caf7050d482dc15f35a344eab11bb756Kenny Root (mHeader->stylesStart-mHeader->stringsStart)/charSize; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check invariant: stringCount > 0 requires a string pool to exist 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStringPoolSize == 0) { 4168564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* e = const_cast<uint32_t*>(mEntries); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mHeader->stringCount; i++) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e[i] = dtohl(mEntries[i]); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42619138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) { 42719138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* strings = (const char16_t*)mStrings; 42819138468caf7050d482dc15f35a344eab11bb756Kenny Root char16_t* s = const_cast<char16_t*>(strings); 42919138468caf7050d482dc15f35a344eab11bb756Kenny Root for (i=0; i<mStringPoolSize; i++) { 43019138468caf7050d482dc15f35a344eab11bb756Kenny Root s[i] = dtohs(strings[i]); 43119138468caf7050d482dc15f35a344eab11bb756Kenny Root } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43519138468caf7050d482dc15f35a344eab11bb756Kenny Root if ((mHeader->flags&ResStringPool_header::UTF8_FLAG && 43619138468caf7050d482dc15f35a344eab11bb756Kenny Root ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) || 43719138468caf7050d482dc15f35a344eab11bb756Kenny Root (!mHeader->flags&ResStringPool_header::UTF8_FLAG && 43819138468caf7050d482dc15f35a344eab11bb756Kenny Root ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) { 4398564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: last string is not 0-terminated\n"); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings = NULL; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 0; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->styleCount > 0) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntryStyles = mEntries + mHeader->stringCount; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // invariant: integer overflow in calculating mEntryStyles 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEntryStyles < mEntries) { 4518564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: integer overflow finding styles\n"); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) { 4568564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: entry of %d styles extends past data size %d\n", 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader), 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)size); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStyles = (const uint32_t*) 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->stylesStart); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stylesStart >= mHeader->header.size) { 4648564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: style pool starts %d, after total size %d\n", 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stylesStart, (int)mHeader->header.size); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStylePoolSize = 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* e = const_cast<uint32_t*>(mEntryStyles); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mHeader->styleCount; i++) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e[i] = dtohl(mEntryStyles[i]); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* s = const_cast<uint32_t*>(mStyles); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mStylePoolSize; i++) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s[i] = dtohl(mStyles[i]); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResStringPool_span endSpan = { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { htodl(ResStringPool_span::END) }, 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project htodl(ResStringPool_span::END), htodl(ResStringPool_span::END) 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))], 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &endSpan, sizeof(endSpan)) != 0) { 4898564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n"); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntryStyles = NULL; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStyles = NULL; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStylePoolSize = 0; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_ERROR); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResStringPool::getError() const 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResStringPool::uninit() 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 50919138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mHeader != NULL && mCache != NULL) { 51019138468caf7050d482dc15f35a344eab11bb756Kenny Root for (size_t x = 0; x < mHeader->stringCount; x++) { 51119138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mCache[x] != NULL) { 51219138468caf7050d482dc15f35a344eab11bb756Kenny Root free(mCache[x]); 51319138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache[x] = NULL; 51419138468caf7050d482dc15f35a344eab11bb756Kenny Root } 51519138468caf7050d482dc15f35a344eab11bb756Kenny Root } 51619138468caf7050d482dc15f35a344eab11bb756Kenny Root free(mCache); 51719138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache = NULL; 51819138468caf7050d482dc15f35a344eab11bb756Kenny Root } 519a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman if (mOwnedData) { 520a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman free(mOwnedData); 521a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman mOwnedData = NULL; 522a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 525300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root/** 526300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * Strings in UTF-16 format have length indicated by a length encoded in the 527300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * stored data. It is either 1 or 2 characters of length data. This allows a 528300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that 529300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * much data in a string, you're abusing them. 530300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * 531300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * If the high bit is set, then there are two characters or 4 bytes of length 532300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * data encoded. In that case, drop the high bit of the first character and 533300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * add it together with the next character. 534300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root */ 535300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic inline size_t 536300ba6846949f5b21c6d93d7698dbc39716cf832Kenny RootdecodeLength(const char16_t** str) 537300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root{ 538300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t len = **str; 539300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((len & 0x8000) != 0) { 540300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 541300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root len = ((len & 0x7FFF) << 16) | **str; 542300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 543300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 544300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return len; 545300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root} 546300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 547300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root/** 548300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * Strings in UTF-8 format have length indicated by a length encoded in the 549300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * stored data. It is either 1 or 2 characters of length data. This allows a 550300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * maximum length of 0x7FFF (32767 bytes), but you should consider storing 551300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * text in another way if you're using that much data in a single string. 552300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * 553300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * If the high bit is set, then there are two characters or 2 bytes of length 554300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * data encoded. In that case, drop the high bit of the first character and 555300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * add it together with the next character. 556300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root */ 557300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic inline size_t 558300ba6846949f5b21c6d93d7698dbc39716cf832Kenny RootdecodeLength(const uint8_t** str) 559300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root{ 560300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t len = **str; 561300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((len & 0x80) != 0) { 562300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 563300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root len = ((len & 0x7F) << 8) | **str; 564300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 565300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 566300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return len; 567300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root} 568300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 569300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootconst uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError == NO_ERROR && idx < mHeader->stringCount) { 57219138468caf7050d482dc15f35a344eab11bb756Kenny Root const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0; 57319138468caf7050d482dc15f35a344eab11bb756Kenny Root const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t)); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < (mStringPoolSize-1)) { 57519138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!isUTF8) { 57619138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* strings = (char16_t*)mStrings; 57719138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* str = strings+off; 578300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 579300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root *u16len = decodeLength(&str); 580300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) { 58119138468caf7050d482dc15f35a344eab11bb756Kenny Root return str; 58219138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 5838564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d extends to %d, past end at %d\n", 584300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize); 58519138468caf7050d482dc15f35a344eab11bb756Kenny Root } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 58719138468caf7050d482dc15f35a344eab11bb756Kenny Root const uint8_t* strings = (uint8_t*)mStrings; 588300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root const uint8_t* u8str = strings+off; 589300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 590300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root *u16len = decodeLength(&u8str); 591300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t u8len = decodeLength(&u8str); 592300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 593300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root // encLen must be less than 0x7FFF due to encoding. 594300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) { 59519138468caf7050d482dc15f35a344eab11bb756Kenny Root AutoMutex lock(mDecodeLock); 596300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 59719138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mCache[idx] != NULL) { 59819138468caf7050d482dc15f35a344eab11bb756Kenny Root return mCache[idx]; 59919138468caf7050d482dc15f35a344eab11bb756Kenny Root } 600300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 601300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root ssize_t actualLen = utf8_to_utf16_length(u8str, u8len); 602300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if (actualLen < 0 || (size_t)actualLen != *u16len) { 6038564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%lld decoded length is not correct " 604300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root "%lld vs %llu\n", 605300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)idx, (long long)actualLen, (long long)*u16len); 606300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return NULL; 607300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 608300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 609300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t)); 61019138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!u16str) { 6118564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No memory when trying to allocate decode cache for string #%d\n", 61219138468caf7050d482dc15f35a344eab11bb756Kenny Root (int)idx); 61319138468caf7050d482dc15f35a344eab11bb756Kenny Root return NULL; 61419138468caf7050d482dc15f35a344eab11bb756Kenny Root } 615300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 616300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root utf8_to_utf16(u8str, u8len, u16str); 61719138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache[idx] = u16str; 61819138468caf7050d482dc15f35a344eab11bb756Kenny Root return u16str; 61919138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 6208564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n", 621300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)idx, (long long)(u8str+u8len-strings), 622300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)mStringPoolSize); 62319138468caf7050d482dc15f35a344eab11bb756Kenny Root } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6268564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n", 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)(off*sizeof(uint16_t)), 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mStringPoolSize*sizeof(uint16_t))); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 634780d2a1b714724d85227141c76b3c64f543f00b4Kenny Rootconst char* ResStringPool::string8At(size_t idx, size_t* outLen) const 635780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root{ 636780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (mError == NO_ERROR && idx < mHeader->stringCount) { 637780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0; 638780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t)); 639780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (off < (mStringPoolSize-1)) { 640780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (isUTF8) { 641780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const uint8_t* strings = (uint8_t*)mStrings; 642780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const uint8_t* str = strings+off; 643300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root *outLen = decodeLength(&str); 644300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t encLen = decodeLength(&str); 645780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if ((uint32_t)(str+encLen-strings) < mStringPoolSize) { 646780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root return (const char*)str; 647780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } else { 6488564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d extends to %d, past end at %d\n", 649780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize); 650780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 651780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 652780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } else { 6538564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n", 654780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root (int)idx, (int)(off*sizeof(uint16_t)), 655780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root (int)(mStringPoolSize*sizeof(uint16_t))); 656780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 657780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 658780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root return NULL; 659780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root} 660780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root 6616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornconst String8 ResStringPool::string8ObjectAt(size_t idx) const 6626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 6636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size_t len; 6646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const char *str = (const char*)string8At(idx, &len); 6656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (str != NULL) { 6666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return String8(str); 6676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 6686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return String8(stringAt(idx, &len)); 6696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 6706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return styleAt(ref.index); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool_span* ResStringPool::styleAt(size_t idx) const 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError == NO_ERROR && idx < mHeader->styleCount) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t)); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < mStylePoolSize) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (const ResStringPool_span*)(mStyles+off); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6838564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: style #%d entry is at %d, past end at %d\n", 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)(off*sizeof(uint32_t)), 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mStylePoolSize*sizeof(uint32_t))); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 69919138468caf7050d482dc15f35a344eab11bb756Kenny Root // TODO optimize searching for UTF-8 strings taking into account 70019138468caf7050d482dc15f35a344eab11bb756Kenny Root // the cache fill to determine when to convert the searched-for 70119138468caf7050d482dc15f35a344eab11bb756Kenny Root // string key to UTF-8. 70219138468caf7050d482dc15f35a344eab11bb756Kenny Root 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->flags&ResStringPool_header::SORTED_FLAG) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do a binary search for the string... 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t l = 0; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t h = mHeader->stringCount-1; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t mid; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (l <= h) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mid = l + (h - l)/2; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s = stringAt(mid, &len); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c = s ? strzcmp16(s, len, str, strLen) : -1; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n", 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(str).string(), 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s).string(), 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c, (int)l, (int)mid, (int)h)); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == 0) { 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mid; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (c < 0) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = mid + 1; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h = mid - 1; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It is unusual to get the ID from an unsorted string block... 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // most often this happens because we want to get IDs for style 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // span tags; since those always appear at the end of the string 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // block, start searching at the back. 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=mHeader->stringCount-1; i>=0; i--) { 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s = stringAt(i, &len); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project POOL_NOISY(printf("Looking for %s, at %s, i=%d\n", 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(str, strLen).string(), 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s).string(), 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i)); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s && strzcmp16(s, len, str, strLen) == 0) { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return i; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResStringPool::size() const 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError == NO_ERROR) ? mHeader->stringCount : 0; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornsize_t ResStringPool::styleCount() const 7516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 7526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mError == NO_ERROR) ? mHeader->styleCount : 0; 7536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 7546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 7556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornsize_t ResStringPool::bytes() const 7566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 7576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mError == NO_ERROR) ? mHeader->header.size : 0; 7586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 7596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 7606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResStringPool::isSorted() const 7616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 7626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0; 7636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 7646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 765bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Rootbool ResStringPool::isUTF8() const 766bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root{ 767bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0; 768bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root} 769bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::ResXMLParser(const ResXMLTree& tree) 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mTree(tree), mEventCode(BAD_DOCUMENT) 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::restart() 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 784cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackbornconst ResStringPool& ResXMLParser::getStrings() const 785cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn{ 786cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn return mTree.mStrings; 787cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn} 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::getEventType() const 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::next() 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_DOCUMENT) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = mTree.mRootNode; 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = mTree.mRootExt; 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=mTree.mRootCode); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mEventCode >= FIRST_CHUNK_CODE) { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextNode(); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8065f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getCommentID() const 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getComment(size_t* outLen) const 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getCommentID(); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8175f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianuint32_t ResXMLParser::getLineNumber() const 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8225f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getTextID() const 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == TEXT) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getText(size_t* outLen) const 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getTextID(); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::getTextValue(Res_value* outValue) const 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == TEXT) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sizeof(Res_value); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8455f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getNamespacePrefixID() const 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getNamespacePrefixID(); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("prefix=%d event=%p\n", id, mEventCode); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8605f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getNamespaceUriID() const 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getNamespaceUriID(); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("uri=%d event=%p\n", id, mEventCode); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8755f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getElementNamespaceID() const 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == END_TAG) { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getElementNamespaceID(); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8925f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getElementNameID() const 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index); 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == END_TAG) { 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getElementName(size_t* outLen) const 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getElementNameID(); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResXMLParser::getAttributeCount() const 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9175f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->ns.index); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -2; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNamespaceID(idx); 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id)); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9405f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeNameID(size_t idx) const 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->name.index); 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNameID(idx); 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode); 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id)); 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9635f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianuint32_t ResXMLParser::getAttributeNameResID(size_t idx) const 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNameID(idx); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id >= 0 && (size_t)id < mTree.mNumResIds) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(mTree.mResIds[id]); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9725f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeValueStringID(size_t idx) const 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->rawValue.index); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeValueStringID(idx); 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id)); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t ResXMLParser::getAttributeDataType(size_t idx) const 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return attr->typedValue.dataType; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_value::TYPE_NULL; 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t ResXMLParser::getAttributeData(size_t idx) const 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->typedValue.data); 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->copyFrom_dtoh(attr->typedValue); 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sizeof(Res_value); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 nsStr(ns != NULL ? ns : ""); 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 attrStr(attr); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0, 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrStr.string(), attrStr.size()); 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen, 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* attr, size_t attrLen) const 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = getAttributeCount(); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curNsLen, curAttrLen; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* curNs = getAttributeNamespace(i, &curNsLen); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* curAttr = getAttributeName(i, &curAttrLen); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n", 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // i, ns, attr, curNs, curAttr); 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf(" --> attr=%s, curAttr=%s\n", 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(attr).string(), String8(curAttr).string()); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) { 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ns == NULL) { 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curNs == NULL) return i; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (curNs != NULL) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf(" --> ns=%s, curNs=%s\n", 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(ns).string(), String8(curNs).string()); 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfID() const 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex); 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfClass() const 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfStyle() const 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex); 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::nextNode() 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode < 0) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_node* next = (const ResXMLTree_node*) 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size)); 11128564c8da817a845353d213acd8636b76f567b234Steve Block //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)next) >= mTree.mDataEnd) { 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=END_DOCUMENT); 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTree.validateNode(next) != NO_ERROR) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=BAD_DOCUMENT); 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = next; 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(next->header.headerSize); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t totalSize = dtohl(next->header.size); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = ((const uint8_t*)next) + headerSize; 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t minExtSize = 0; 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event_code_t eventCode = (event_code_t)dtohs(next->header.type); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch ((mEventCode=eventCode)) { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_START_NAMESPACE_TYPE: 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_END_NAMESPACE_TYPE: 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_namespaceExt); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_START_ELEMENT_TYPE: 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_attrExt); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_END_ELEMENT_TYPE: 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_endElementExt); 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_CDATA_TYPE: 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_cdataExt); 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 11458564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unknown XML block: header type %d in node at %d\n", 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(next->header.type), 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader))); 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((totalSize-headerSize) < minExtSize) { 11528564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n", 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(next->header.type), 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)), 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(totalSize-headerSize), (int)minExtSize); 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=BAD_DOCUMENT); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n", 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mCurNode, mCurExt, headerSize, minExtSize); 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return eventCode; 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (true); 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->eventCode = mEventCode; 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->curNode = mCurNode; 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->curExt = mCurExt; 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos) 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = pos.eventCode; 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = pos.curNode; 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = pos.curExt; 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gCount = 0; 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::ResXMLTree() 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : ResXMLParser(*this) 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mError(NO_INIT), mOwnedData(NULL) 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11896215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData) 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : ResXMLParser(*this) 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mError(NO_INIT), mOwnedData(NULL) 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11976215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1); 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTo(data, size, copyData); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::~ResXMLTree() 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12036215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = START_DOCUMENT; 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData) { 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = malloc(size); 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData == NULL) { 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mOwnedData, data, size); 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = mOwnedData; 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader = (const ResXMLTree_header*)data; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = dtohl(mHeader->header.size); 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) { 12248564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n", 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(mHeader->header.headerSize), 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(mHeader->header.size), (int)size); 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataEnd = ((const uint8_t*)mHeader) + mSize; 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings.uninit(); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode = NULL; 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResIds = NULL; 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumResIds = 0; 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First look for a couple interesting chunks: the string block 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and first XML node. 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize)); 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* lastChunk = chunk; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) && 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) { 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML"); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = err; 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t type = dtohs(chunk->type); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = dtohl(chunk->size); 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n", 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size)); 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == RES_STRING_POOL_TYPE) { 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings.setTo(chunk, size); 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == RES_XML_RESOURCE_MAP_TYPE) { 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResIds = (const uint32_t*) 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk)+dtohs(chunk->headerSize)); 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t); 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type >= RES_XML_FIRST_CHUNK_TYPE 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && type <= RES_XML_LAST_CHUNK_TYPE) { 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) { 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = (const ResXMLTree_node*)lastChunk; 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nextNode() == BAD_DOCUMENT) { 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode = mCurNode; 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootExt = mCurExt; 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootCode = mEventCode; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_NOISY(printf("Skipping unknown chunk!\n")); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastChunk = chunk; 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + size); 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRootNode == NULL) { 12848564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: no root element node found\n"); 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = mStrings.getError(); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone: 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::getError() const 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLTree::uninit() 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 130419138468caf7050d482dc15f35a344eab11bb756Kenny Root mStrings.uninit(); 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData) { 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(mOwnedData); 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = NULL; 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::validateNode(const ResXMLTree_node* node) const 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t eventCode = dtohs(node->header.type); 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk( 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &node->header, sizeof(ResXMLTree_node), 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataEnd, "ResXMLTree_node"); 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err >= NO_ERROR) { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Only perform additional validation on START nodes 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (eventCode != RES_XML_START_ELEMENT_TYPE) { 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(node->header.headerSize); 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(node->header.size); 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*) 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)node) + headerSize); 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check for sensical values pulled out of the stream so far... 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size >= headerSize + sizeof(ResXMLTree_attrExt)) 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((void*)attrExt > (void*)node)) { 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize)) 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * dtohs(attrExt->attributeCount); 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) { 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13388564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n", 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)(dtohs(attrExt->attributeStart)+attrSize), 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)(size-headerSize)); 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 13438564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML start block: node header size 0x%x, size 0x%x\n", 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)headerSize, (unsigned int)size); 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE; 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(node->header.headerSize); 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(node->header.size); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) { 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size >= headerSize) { 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)node) <= (mDataEnd-size)) { 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isStart) { 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount)) 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <= (size-headerSize)) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13678564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n", 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount), 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(size-headerSize)); 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13728564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n", 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13768564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n", 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)headerSize, (int)size); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13818564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x header size 0x%x too small\n", 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)headerSize); 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) { 13936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const size_t size = dtohl(o.size); 13946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (size >= sizeof(ResTable_config)) { 13956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn *this = o; 13966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else { 13976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memcpy(this, &o, size); 13986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size); 13996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 14016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 14026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::copyFromDtoH(const ResTable_config& o) { 14036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn copyFromDeviceNoSwap(o); 14046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size = sizeof(ResTable_config); 14056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mcc = dtohs(mcc); 14066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mnc = dtohs(mnc); 14076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn density = dtohs(density); 14086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidth = dtohs(screenWidth); 14096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeight = dtohs(screenHeight); 14106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn sdkVersion = dtohs(sdkVersion); 14116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn minorVersion = dtohs(minorVersion); 14126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn smallestScreenWidthDp = dtohs(smallestScreenWidthDp); 14136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidthDp = dtohs(screenWidthDp); 14146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeightDp = dtohs(screenHeightDp); 14156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 14166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 14176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::swapHtoD() { 14186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size = htodl(size); 14196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mcc = htods(mcc); 14206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mnc = htods(mnc); 14216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn density = htods(density); 14226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidth = htods(screenWidth); 14236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeight = htods(screenHeight); 14246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn sdkVersion = htods(sdkVersion); 14256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn minorVersion = htods(minorVersion); 14266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn smallestScreenWidthDp = htods(smallestScreenWidthDp); 14276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidthDp = htods(screenWidthDp); 14286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeightDp = htods(screenHeightDp); 14296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 14306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 14316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::compare(const ResTable_config& o) const { 14326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int32_t diff = (int32_t)(imsi - o.imsi); 14336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(locale - o.locale); 14356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenType - o.screenType); 14376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(input - o.input); 14396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenSize - o.screenSize); 14416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(version - o.version); 14436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenLayout - o.screenLayout); 14456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(uiMode - o.uiMode); 14476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp); 14496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 14506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenSizeDp - o.screenSizeDp); 14516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (int)diff; 14526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 14536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 14546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::compareLogical(const ResTable_config& o) const { 14556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) { 14566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return mcc < o.mcc ? -1 : 1; 14576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) { 14596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return mnc < o.mnc ? -1 : 1; 14606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != o.language[0]) { 14626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return language[0] < o.language[0] ? -1 : 1; 14636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[1] != o.language[1]) { 14656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return language[1] < o.language[1] ? -1 : 1; 14666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != o.country[0]) { 14686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return country[0] < o.country[0] ? -1 : 1; 14696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[1] != o.country[1]) { 14716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return country[1] < o.country[1] ? -1 : 1; 14726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 14746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1; 14756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != o.screenWidthDp) { 14776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenWidthDp < o.screenWidthDp ? -1 : 1; 14786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != o.screenHeightDp) { 14806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenHeightDp < o.screenHeightDp ? -1 : 1; 14816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != o.screenWidth) { 14836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenWidth < o.screenWidth ? -1 : 1; 14846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != o.screenHeight) { 14866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenHeight < o.screenHeight ? -1 : 1; 14876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) { 14896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return density < o.density ? -1 : 1; 14906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) { 14926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return orientation < o.orientation ? -1 : 1; 14936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) { 14956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return touchscreen < o.touchscreen ? -1 : 1; 14966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 14976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input != o.input) { 14986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return input < o.input ? -1 : 1; 14996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout != o.screenLayout) { 15016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenLayout < o.screenLayout ? -1 : 1; 15026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode != o.uiMode) { 15046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return uiMode < o.uiMode ? -1 : 1; 15056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != o.version) { 15076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return version < o.version ? -1 : 1; 15086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return 0; 15106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::diff(const ResTable_config& o) const { 15136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int diffs = 0; 15146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) diffs |= CONFIG_MCC; 15156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) diffs |= CONFIG_MNC; 15166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale != o.locale) diffs |= CONFIG_LOCALE; 15176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION; 15186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) diffs |= CONFIG_DENSITY; 15196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN; 15206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0) 15216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diffs |= CONFIG_KEYBOARD_HIDDEN; 15226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD; 15236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION; 15246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE; 15256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != o.version) diffs |= CONFIG_VERSION; 15266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT; 15276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; 15286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE; 15296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; 15306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return diffs; 15316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const { 15346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // The order of the following tests defines the importance of one 15356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // configuration parameter over another. Those tests first are more 15366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // important, trumping any values in those following them. 15376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi || o.imsi) { 15386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) { 15396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!mcc) return false; 15406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.mcc) return true; 15416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) { 15446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!mnc) return false; 15456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.mnc) return true; 15466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale || o.locale) { 15506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != o.language[0]) { 15516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!language[0]) return false; 15526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.language[0]) return true; 15536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != o.country[0]) { 15566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!country[0]) return false; 15576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.country[0]) return true; 15586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp || o.smallestScreenWidthDp) { 15626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 15636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!smallestScreenWidthDp) return false; 15646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.smallestScreenWidthDp) return true; 15656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp || o.screenSizeDp) { 15696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != o.screenWidthDp) { 15706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenWidthDp) return false; 15716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenWidthDp) return true; 15726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != o.screenHeightDp) { 15756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenHeightDp) return false; 15766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenHeightDp) return true; 15776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout || o.screenLayout) { 15816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) { 15826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(screenLayout & MASK_SCREENSIZE)) return false; 15836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.screenLayout & MASK_SCREENSIZE)) return true; 15846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) { 15866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(screenLayout & MASK_SCREENLONG)) return false; 15876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.screenLayout & MASK_SCREENLONG)) return true; 15886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) { 15926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!orientation) return false; 15936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.orientation) return true; 15946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode || o.uiMode) { 15976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) { 15986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(uiMode & MASK_UI_MODE_TYPE)) return false; 15996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true; 16006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) { 16026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(uiMode & MASK_UI_MODE_NIGHT)) return false; 16036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true; 16046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density is never 'more specific' 16086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // as the default just equals 160 16096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) { 16116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!touchscreen) return false; 16126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.touchscreen) return true; 16136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input || o.input) { 16166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) { 16176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(inputFlags & MASK_KEYSHIDDEN)) return false; 16186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true; 16196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) { 16226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(inputFlags & MASK_NAVHIDDEN)) return false; 16236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.inputFlags & MASK_NAVHIDDEN)) return true; 16246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != o.keyboard) { 16276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!keyboard) return false; 16286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.keyboard) return true; 16296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != o.navigation) { 16326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!navigation) return false; 16336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.navigation) return true; 16346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize || o.screenSize) { 16386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != o.screenWidth) { 16396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenWidth) return false; 16406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenWidth) return true; 16416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != o.screenHeight) { 16446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenHeight) return false; 16456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenHeight) return true; 16466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version || o.version) { 16506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (sdkVersion != o.sdkVersion) { 16516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!sdkVersion) return false; 16526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.sdkVersion) return true; 16536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != o.minorVersion) { 16566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!minorVersion) return false; 16576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.minorVersion) return true; 16586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 16616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 16626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::isBetterThan(const ResTable_config& o, 16646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const ResTable_config* requested) const { 16656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested) { 16666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi || o.imsi) { 16676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((mcc != o.mcc) && requested->mcc) { 16686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mcc); 16696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((mnc != o.mnc) && requested->mnc) { 16726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mnc); 16736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale || o.locale) { 16776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((language[0] != o.language[0]) && requested->language[0]) { 16786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (language[0]); 16796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((country[0] != o.country[0]) && requested->country[0]) { 16826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (country[0]); 16836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp || o.smallestScreenWidthDp) { 16876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // The configuration closest to the actual size is best. 16886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // We assume that larger configs have already been filtered 16896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // out at this point. That means we just want the largest one. 16905c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 16915c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return smallestScreenWidthDp > o.smallestScreenWidthDp; 16925c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 16936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp || o.screenSizeDp) { 16966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // "Better" is based on the sum of the difference between both 16976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // width and height from the requested dimensions. We are 16986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // assuming the invalid configs (with smaller dimens) have 16996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // already been filtered. Note that if a particular dimension 17006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is unspecified, we will end up with a large value (the 17016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // difference between 0 and the requested dimension), which is 17026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // good since we will prefer a config that has specified a 17036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // dimension value. 17046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int myDelta = 0, otherDelta = 0; 17056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenWidthDp) { 17066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenWidthDp - screenWidthDp; 17076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenWidthDp - o.screenWidthDp; 17086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenHeightDp) { 17106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenHeightDp - screenHeightDp; 17116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenHeightDp - o.screenHeightDp; 17126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d", 17146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp, 17156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta); 17165c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (myDelta != otherDelta) { 17175c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return myDelta < otherDelta; 17185c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 17196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout || o.screenLayout) { 17226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0 17236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->screenLayout & MASK_SCREENSIZE)) { 17246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // A little backwards compatibility here: undefined is 17256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // considered equivalent to normal. But only if the 17266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested size is at least normal; otherwise, small 17276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is better than the default. 17286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int mySL = (screenLayout & MASK_SCREENSIZE); 17296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int oSL = (o.screenLayout & MASK_SCREENSIZE); 17306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int fixedMySL = mySL; 17316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int fixedOSL = oSL; 17326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) { 17336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL; 17346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL; 17356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For screen size, the best match is the one that is 17376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // closest to the requested screen size, but not over 17386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // (the not over part is dealt with in match() below). 17396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedMySL == fixedOSL) { 17406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // If the two are the same, but 'this' is actually 17416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // undefined, then the other is really a better match. 17426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mySL == 0) return false; 17436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return true; 17446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17455c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (fixedMySL != fixedOSL) { 17465c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return fixedMySL > fixedOSL; 17475c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 17486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0 17506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->screenLayout & MASK_SCREENLONG)) { 17516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (screenLayout & MASK_SCREENLONG); 17526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((orientation != o.orientation) && requested->orientation) { 17566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (orientation); 17576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode || o.uiMode) { 17606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0 17616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->uiMode & MASK_UI_MODE_TYPE)) { 17626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (uiMode & MASK_UI_MODE_TYPE); 17636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0 17656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->uiMode & MASK_UI_MODE_NIGHT)) { 17666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (uiMode & MASK_UI_MODE_NIGHT); 17676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenType || o.screenType) { 17716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) { 17726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density is tough. Any density is potentially useful 17736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // because the system will scale it. Scaling down 17746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is generally better than scaling up. 17756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // Default density counts as 160dpi (the system default) 17766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // TODO - remove 160 constants 17776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int h = (density?density:160); 17786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int l = (o.density?o.density:160); 17796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn bool bImBigger = true; 17806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (l > h) { 17816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int t = h; 17826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn h = l; 17836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn l = t; 17846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn bImBigger = false; 17856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int reqValue = (requested->density?requested->density:160); 17886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqValue >= h) { 17896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested value higher than both l and h, give h 17906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return bImBigger; 17916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (l >= reqValue) { 17936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested value lower than both l and h, give l 17946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return !bImBigger; 17956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // saying that scaling down is 2x better than up 17976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((2 * l) - reqValue) * h > reqValue * reqValue) { 17986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return !bImBigger; 17996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else { 18006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return bImBigger; 18016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((touchscreen != o.touchscreen) && requested->touchscreen) { 18056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (touchscreen); 18066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input || o.input) { 18106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int keysHidden = inputFlags & MASK_KEYSHIDDEN; 18116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN; 18126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != oKeysHidden) { 18136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int reqKeysHidden = 18146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->inputFlags & MASK_KEYSHIDDEN; 18156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden) { 18166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!keysHidden) return false; 18186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!oKeysHidden) return true; 18196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For compatibility, we count KEYSHIDDEN_NO as being 18206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // the same as KEYSHIDDEN_SOFT. Here we disambiguate 18216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // these by making an exact match more specific. 18226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden == keysHidden) return true; 18236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden == oKeysHidden) return false; 18246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int navHidden = inputFlags & MASK_NAVHIDDEN; 18286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN; 18296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navHidden != oNavHidden) { 18306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int reqNavHidden = 18316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->inputFlags & MASK_NAVHIDDEN; 18326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqNavHidden) { 18336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!navHidden) return false; 18356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!oNavHidden) return true; 18366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((keyboard != o.keyboard) && requested->keyboard) { 18406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (keyboard); 18416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((navigation != o.navigation) && requested->navigation) { 18446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (navigation); 18456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize || o.screenSize) { 18496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // "Better" is based on the sum of the difference between both 18506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // width and height from the requested dimensions. We are 18516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // assuming the invalid configs (with smaller sizes) have 18526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // already been filtered. Note that if a particular dimension 18536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is unspecified, we will end up with a large value (the 18546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // difference between 0 and the requested dimension), which is 18556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // good since we will prefer a config that has specified a 18566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // size value. 18576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int myDelta = 0, otherDelta = 0; 18586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenWidth) { 18596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenWidth - screenWidth; 18606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenWidth - o.screenWidth; 18616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenHeight) { 18636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenHeight - screenHeight; 18646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenHeight - o.screenHeight; 18656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18665c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (myDelta != otherDelta) { 18675c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return myDelta < otherDelta; 18685c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 18696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version || o.version) { 18726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) { 18736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (sdkVersion > o.sdkVersion); 18746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((minorVersion != o.minorVersion) && 18776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->minorVersion) { 18786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (minorVersion); 18796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 18836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return isMoreSpecificThan(o); 18856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 18866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::match(const ResTable_config& settings) const { 18886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi != 0) { 18896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != 0 && mcc != settings.mcc) { 18906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 18916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != 0 && mnc != settings.mnc) { 18936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 18946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale != 0) { 18976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != 0 18986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (language[0] != settings.language[0] 18996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn || language[1] != settings.language[1])) { 19006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != 0 19036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (country[0] != settings.country[0] 19046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn || country[1] != settings.country[1])) { 19056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenConfig != 0) { 19096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int screenSize = screenLayout&MASK_SCREENSIZE; 19106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE; 19116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // Any screen sizes for larger screens than the setting do not 19126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // match. 19136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0 && screenSize > setScreenSize) { 19146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int screenLong = screenLayout&MASK_SCREENLONG; 19186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setScreenLong = settings.screenLayout&MASK_SCREENLONG; 19196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLong != 0 && screenLong != setScreenLong) { 19206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int uiModeType = uiMode&MASK_UI_MODE_TYPE; 19246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE; 19256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiModeType != 0 && uiModeType != setUiModeType) { 19266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT; 19306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT; 19316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiModeNight != 0 && uiModeNight != setUiModeNight) { 19326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != 0 19366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && smallestScreenWidthDp > settings.smallestScreenWidthDp) { 19376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp != 0) { 19416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) { 19426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp); 19436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) { 19466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp); 19476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenType != 0) { 19516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != 0 && orientation != settings.orientation) { 19526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density always matches - we can scale it. See isBetterThan 19556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != 0 && touchscreen != settings.touchscreen) { 19566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input != 0) { 19606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int keysHidden = inputFlags&MASK_KEYSHIDDEN; 19616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN; 19626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != 0 && keysHidden != setKeysHidden) { 19636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For compatibility, we count a request for KEYSHIDDEN_NO as also 19646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // matching the more recent KEYSHIDDEN_SOFT. Basically 19656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // KEYSHIDDEN_NO means there is some kind of keyboard available. 19666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden); 19676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) { 19686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("No match!"); 19696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int navHidden = inputFlags&MASK_NAVHIDDEN; 19736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN; 19746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navHidden != 0 && navHidden != setNavHidden) { 19756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != 0 && keyboard != settings.keyboard) { 19786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != 0 && navigation != settings.navigation) { 19816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0) { 19856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != 0 && screenWidth > settings.screenWidth) { 19866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != 0 && screenHeight > settings.screenHeight) { 19896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != 0) { 19936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) { 19946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != 0 && minorVersion != settings.minorVersion) { 19976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 19986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return true; 20016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 20026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::getLocale(char str[6]) const { 20046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memset(str, 0, 6); 20056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0]) { 20066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[0] = language[0]; 20076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[1] = language[1]; 20086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0]) { 20096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[2] = '_'; 20106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[3] = country[0]; 20116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[4] = country[1]; 20126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 20156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne HackbornString8 ResTable_config::toString() const { 20176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn String8 res; 20186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != 0) { 20206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dmcc", dtohs(mcc)); 20226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != 0) { 20246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dmnc", dtohs(mnc)); 20266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != 0) { 20286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append(language, 2); 20306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != 0) { 20326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append(country, 2); 20346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != 0) { 20366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp)); 20386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != 0) { 20406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("w%ddp", dtohs(screenWidthDp)); 20426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != 0) { 20446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("h%ddp", dtohs(screenHeightDp)); 20466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) { 20486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (screenLayout&ResTable_config::MASK_SCREENSIZE) { 20506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_SMALL: 20516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("small"); 20526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_NORMAL: 20546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("normal"); 20556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_LARGE: 20576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("large"); 20586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_XLARGE: 20606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xlarge"); 20616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 20636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("screenLayoutSize=%d", 20646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE)); 20656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((screenLayout&MASK_SCREENLONG) != 0) { 20696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (screenLayout&ResTable_config::MASK_SCREENLONG) { 20716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENLONG_NO: 20726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notlong"); 20736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENLONG_YES: 20756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("long"); 20766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 20786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("screenLayoutLong=%d", 20796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_SCREENLONG)); 20806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != ORIENTATION_ANY) { 20846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 20856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (orientation) { 20866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_PORT: 20876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("port"); 20886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_LAND: 20906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("land"); 20916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_SQUARE: 20936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("square"); 20946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 20966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("orientation=%d", dtohs(orientation)); 20976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 20986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) { 21016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) { 21036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_DESK: 21046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("desk"); 21056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_CAR: 21076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("car"); 21086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_TELEVISION: 21106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("television"); 21116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_APPLIANCE: 21136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("appliance"); 21146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 21166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("uiModeType=%d", 21176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE)); 21186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((uiMode&MASK_UI_MODE_NIGHT) != 0) { 21226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) { 21246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_NIGHT_NO: 21256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notnight"); 21266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_NIGHT_YES: 21286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("night"); 21296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 21316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("uiModeNight=%d", 21326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(uiMode&MASK_UI_MODE_NIGHT)); 21336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != DENSITY_DEFAULT) { 21376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (density) { 21396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_LOW: 21406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("ldpi"); 21416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_MEDIUM: 21436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("mdpi"); 21446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_TV: 21466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("tvdpi"); 21476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_HIGH: 21496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("hdpi"); 21506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_XHIGH: 21526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xhdpi"); 21536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_XXHIGH: 21556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xxhdpi"); 21566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_NONE: 21586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nodpi"); 21596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 21615c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn res.appendFormat("%ddpi", dtohs(density)); 21626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != TOUCHSCREEN_ANY) { 21666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (touchscreen) { 21686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_NOTOUCH: 21696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notouch"); 21706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_FINGER: 21726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("finger"); 21736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_STYLUS: 21756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("stylus"); 21766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 21786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("touchscreen=%d", dtohs(touchscreen)); 21796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != KEYBOARD_ANY) { 21836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (keyboard) { 21856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_NOKEYS: 21866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nokeys"); 21876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_QWERTY: 21896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("qwerty"); 21906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_12KEY: 21926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("12key"); 21936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 21956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("keyboard=%d", dtohs(keyboard)); 21966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 21976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((inputFlags&MASK_KEYSHIDDEN) != 0) { 22006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (inputFlags&MASK_KEYSHIDDEN) { 22026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_NO: 22036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keysexposed"); 22046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_YES: 22066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keyshidden"); 22076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_SOFT: 22096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keyssoft"); 22106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != NAVIGATION_ANY) { 22146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (navigation) { 22166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_NONAV: 22176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nonav"); 22186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_DPAD: 22206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("dpad"); 22216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_TRACKBALL: 22236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("trackball"); 22246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_WHEEL: 22266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("wheel"); 22276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("navigation=%d", dtohs(navigation)); 22306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((inputFlags&MASK_NAVHIDDEN) != 0) { 22346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (inputFlags&MASK_NAVHIDDEN) { 22366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVHIDDEN_NO: 22376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("navsexposed"); 22386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVHIDDEN_YES: 22406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("navhidden"); 22416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("inputFlagsNavHidden=%d", 22446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(inputFlags&MASK_NAVHIDDEN)); 22456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0) { 22496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight)); 22516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != 0) { 22536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("v%d", dtohs(sdkVersion)); 22556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != 0) { 22566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat(".%d", dtohs(minorVersion)); 22576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 22606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return res; 22616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 22626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 22636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 22646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 22656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 22666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Header 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 226957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL), 227057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resourceIDMap(NULL), resourceIDMapSize(0) { } 227157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 227257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ~Header() 227357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad { 227457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad free(resourceIDMap); 227557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 227778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* ownedData; 22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_header* header; 22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size; 22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* dataEnd; 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t index; 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* cookie; 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResStringPool values; 228657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* resourceIDMap; 228757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t resourceIDMapSize; 22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Type 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type(const Header* _header, const Package* _package, size_t count) 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : header(_header), package(_package), entryCount(count), 22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSpec(NULL), typeSpecFlags(NULL) { } 22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Header* const header; 22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package; 22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t entryCount; 22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_typeSpec* typeSpec; 22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* typeSpecFlags; 23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<const ResTable_type*> configs; 23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Package 23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 230578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package(ResTable* _owner, const Header* _header, const ResTable_package* _package) 230678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn : owner(_owner), header(_header), package(_package) { } 23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~Package() 23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i = types.size(); 23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i > 0) { 23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete types[i]; 23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 231678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Header* const header; 23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_package* const package; 23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<Type*> types; 23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 232178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResStringPool typeStrings; 232278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResStringPool keyStrings; 232378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* getType(size_t idx) const { 23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return idx < types.size() ? types[idx] : NULL; 23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// A group of objects describing a particular resource package. 23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// The first in 'package' is always the root object (from the resource 23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// table that defined the package); the ones after are skins on top of it. 23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::PackageGroup 23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 233478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id) 233578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { } 23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~PackageGroup() { 23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearBagCache(); 23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = packages.size(); 23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 234078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package* pkg = packages[i]; 234178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (pkg->owner == owner) { 234278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete pkg; 234378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clearBagCache() { 23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bags) { 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("bags=%p\n", bags)); 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Package* pkg = packages[0]; 23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("typeCount=%x\n", typeCount)); 23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<typeCount; i++) { 23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("type=%d\n", i)); 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = pkg->getType(i); 23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != NULL) { 23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeBags = bags[i]; 23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("typeBags=%p\n", typeBags)); 23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeBags) { 23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount)); 23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = type->entryCount; 23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<N; j++) { 23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF) 23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(typeBags[j]); 23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(typeBags); 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(bags); 23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bags = NULL; 23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 237478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 const name; 23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t const id; 23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<Package*> packages; 237878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 237978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn // This is for finding typeStrings and other common package stuff. 238078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package* basePackage; 23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 238278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn // For quick access. 23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t typeCount; 238478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Computed attribute bags, first indexed by the type and second 23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // by the entry in that type. 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set*** bags; 23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::bag_set 23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t numAttrs; // number in array 23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t availAttrs; // total space in array 23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t typeSpecFlags; 23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Followed by 'numAttr' bag_entry structures. 23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::Theme(const ResTable& table) 23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mTable(table) 24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackages, 0, sizeof(mPackages)); 24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::~Theme() 24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* pi = mPackages[i]; 24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi != NULL) { 24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(pi); 24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::Theme::free_package(package_info* pi) 24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<pi->numTypes; j++) { 24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* te = pi->types[j].entries; 24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te != NULL) { 24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(te); 24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(pi); 24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi) 24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* newpi = (package_info*)malloc( 24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(package_info) + (pi->numTypes*sizeof(type_info))); 24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->numTypes = pi->numTypes; 24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<newpi->numTypes; j++) { 24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t cnt = pi->types[j].numEntries; 24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].numEntries = cnt; 24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* te = pi->types[j].entries; 24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te != NULL) { 24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry)); 24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].entries = newte; 24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(newte, te, cnt*sizeof(theme_entry)); 24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].entries = NULL; 24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newpi; 24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::Theme::applyStyle(uint32_t resID, bool force) 24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t bagTypeSpecFlags = 0; 24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.lock(); 24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags); 24515c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N)); 24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N < 0) { 24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.unlock(); 24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return N; 24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t curPackage = 0xffffffff; 24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t curPackageIndex = 0; 24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* curPI = NULL; 24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t curType = 0xffffffff; 24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t numEntries = 0; 24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* curEntries = NULL; 24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* end = bag + N; 24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (bag < end) { 24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t attrRes = bag->map.name.ident; 24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t p = Res_GETPACKAGE(attrRes); 24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t t = Res_GETTYPE(attrRes); 24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t e = Res_GETENTRY(attrRes); 24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage != p) { 24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t pidx = mTable.getResourcePackageIndex(attrRes); 24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pidx < 0) { 24743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad package: 0x%08x\n", attrRes); 24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackage = p; 24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackageIndex = pidx; 24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI = mPackages[pidx]; 24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPI == NULL) { 24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mTable.mPackageGroups[pidx]; 24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = grp->typeCount; 24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI = (package_info*)malloc( 24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(package_info) + (cnt*sizeof(type_info))); 24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->numTypes = cnt; 24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(curPI->types, 0, cnt*sizeof(type_info)); 24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[pidx] = curPI; 24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curType = 0xffffffff; 24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curType != t) { 24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t >= curPI->numTypes) { 24943762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad type: 0x%08x\n", attrRes); 24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curType = t; 24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntries = curPI->types[t].entries; 25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curEntries == NULL) { 25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex]; 25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = grp->packages[0]->getType(t); 25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = type != NULL ? type->entryCount : 0; 25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry)); 25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry)); 25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->types[t].numEntries = cnt; 25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->types[t].entries = curEntries; 25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numEntries = curPI->types[t].numEntries; 25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e >= numEntries) { 25123762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad entry: 0x%08x\n", attrRes); 25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 25159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* curEntry = curEntries + e; 25175c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x", 25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrRes, bag->map.value.dataType, bag->map.value.data, 25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->value.dataType)); 25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (force || curEntry->value.dataType == Res_value::TYPE_NULL) { 25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->stringBlock = bag->stringBlock; 25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->typeSpecFlags |= bagTypeSpecFlags; 25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->value = bag->map.value; 25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.unlock(); 25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25316215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Applying style 0x%08x (force=%d) theme %p...\n", resID, force, this); 25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::Theme::setTo(const Theme& other) 25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25396215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Setting theme %p from theme %p...\n", this, &other); 25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //other.dumpToLog(); 25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&mTable == &other.mTable) { 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPackages[i] != NULL) { 25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(mPackages[i]); 25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (other.mPackages[i] != NULL) { 25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = copy_package(other.mPackages[i]); 25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = NULL; 25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // @todo: need to really implement this, not just copy 25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the system package (which is still wrong because it isn't 25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fixing up resource references). 25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPackages[i] != NULL) { 25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(mPackages[i]); 25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == 0 && other.mPackages[i] != NULL) { 25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = copy_package(other.mPackages[i]); 25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = NULL; 25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25706215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Final theme:"); 25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, 25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = 20; 25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0; 25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = mTable.getResourcePackageIndex(resID); 25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t t = Res_GETTYPE(resID); 25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t e = Res_GETENTRY(resID); 25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25885c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this)); 25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p >= 0) { 25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const package_info* const pi = mPackages[p]; 25925c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Found package: %p", pi)); 25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi != NULL) { 25945c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes)); 25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < pi->numTypes) { 25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const type_info& ti = pi->types[t]; 25975c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries)); 25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e < ti.numEntries) { 25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const theme_entry& te = ti.entries[e]; 2600b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn if (outTypeSpecFlags != NULL) { 2601b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn *outTypeSpecFlags |= te.typeSpecFlags; 2602b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn } 26035c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x", 2604b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn te.value.dataType, te.value.data)); 26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t type = te.value.dataType; 26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Res_value::TYPE_ATTRIBUTE) { 26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt > 0) { 26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resID = te.value.data; 26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26128564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID); 26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type != Res_value::TYPE_NULL) { 26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outValue = te.value; 26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return te.stringBlock; 26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (true); 26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue, 26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t blockIndex, uint32_t* outLastRef, 26320d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const 26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Resolving type=0x%x\n", inOutValue->dataType); 26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) { 26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t newTypeSpecFlags; 26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags); 26385c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n", 2639b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data)); 26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags; 26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType); 26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (blockIndex < 0) { 26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26460d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn return mTable.resolveReference(inOutValue, blockIndex, outLastRef, 26470d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn inoutTypeSpecFlags, inoutConfig); 26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::Theme::dumpToLog() const 26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26526215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI("Theme %p:\n", this); 26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* pi = mPackages[i]; 26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi == NULL) continue; 26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26576215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" Package #0x%02x:\n", (int)(i+1)); 26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<pi->numTypes; j++) { 26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type_info& ti = pi->types[j]; 26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ti.numEntries == 0) continue; 26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26626215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" Type #0x%02x:\n", (int)(j+1)); 26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t k=0; k<ti.numEntries; k++) { 26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry& te = ti.entries[k]; 26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te.value.dataType == Res_value::TYPE_NULL) continue; 26666215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" 0x%08x: t=0x%x, d=0x%08x (block=%d)\n", 26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)Res_MAKEID(i, j, k), 26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project te.value.dataType, (int)te.value.data, (int)te.stringBlock); 26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::ResTable() 26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mError(NO_INIT) 26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&mParams, 0, sizeof(mParams)); 26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackageMap, 0, sizeof(mPackageMap)); 26796215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResTable %p\n", this); 26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData) 26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mError(NO_INIT) 26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&mParams, 0, sizeof(mParams)); 26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackageMap, 0, sizeof(mPackageMap)); 26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project add(data, size, cookie, copyData); 26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table"); 26896215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResTable %p\n", this); 26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::~ResTable() 26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26946215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Destroying ResTable in %p\n", this); 26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const 26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1; 27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 270357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData, 270457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const void* idmap) 27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 270657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap)); 27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 270957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap) 27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* data = asset->getBuffer(true); 27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data == NULL) { 27138564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unable to get buffer of resource asset file"); 27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size = (size_t)asset->getLength(); 271757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap)); 27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 272078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackbornstatus_t ResTable::add(ResTable* src) 272178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn{ 272278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mError = src->mError; 272378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 272478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t i=0; i<src->mHeaders.size(); i++) { 272578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mHeaders.add(src->mHeaders[i]); 272678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 272778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 272878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t i=0; i<src->mPackageGroups.size(); i++) { 272978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup* srcPg = src->mPackageGroups[i]; 273078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id); 273178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t j=0; j<srcPg->packages.size(); j++) { 273278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->packages.add(srcPg->packages[j]); 273378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 273478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->basePackage = srcPg->basePackage; 273578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->typeCount = srcPg->typeCount; 273678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mPackageGroups.add(pg); 273778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 273878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 273978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap)); 274078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 274178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn return mError; 274278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn} 274378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::add(const void* data, size_t size, void* cookie, 274557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Asset* asset, bool copyData, const Asset* idmap) 27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!data) return NO_ERROR; 274878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Header* header = new Header(this); 27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->index = mHeaders.size(); 27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->cookie = cookie; 275157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (idmap != NULL) { 275257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t idmap_size = idmap->getLength(); 275357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const void* idmap_data = const_cast<Asset*>(idmap)->getBuffer(true); 275457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMap = (uint32_t*)malloc(idmap_size); 275557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (header->resourceIDMap == NULL) { 275657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad delete header; 275757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return (mError = NO_MEMORY); 275857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 275957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memcpy((void*)header->resourceIDMap, idmap_data, idmap_size); 276057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMapSize = idmap_size; 276157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeaders.add(header); 27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool notDeviceEndian = htods(0xf0) != 0xf0; 27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY( 276771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d " 276857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad "idmap=%p\n", data, size, cookie, asset, copyData, idmap)); 27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData || notDeviceEndian) { 27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->ownedData = malloc(size); 27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (header->ownedData == NULL) { 27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(header->ownedData, data, size); 27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = header->ownedData; 27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->header = (const ResTable_header*)data; 27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->size = dtohl(header->header->header.size); 27816215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size, 27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // dtohl(header->header->header.size), header->header->header.size); 27835c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header)); 27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256, 27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16, 16, 0, false, printToLogFunc)); 27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(header->header->header.headerSize) > header->size 27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || header->size > size) { 27888564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n", 27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(header->header->header.headerSize), 27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)header->size, (int)size); 27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) { 27948564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n", 27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(header->header->header.headerSize), 27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)header->size); 27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd = ((const uint8_t*)header->header) + header->size; 28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Iterate through all chunks. 28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curPackage = 0; 28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)header->header) 28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(header->header->header.headerSize)); 28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) && 28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) { 28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable"); 28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28135c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n", 28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size), 28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)))); 28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t csize = dtohl(chunk->size); 28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t ctype = dtohs(chunk->type); 28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ctype == RES_STRING_POOL_TYPE) { 28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (header->values.getError() != NO_ERROR) { 28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Only use the first string chunk; ignore any others that 28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // may appear. 28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = header->values.setTo(chunk, csize); 28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 28278564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Multiple string chunks found in resource table."); 28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ctype == RES_TABLE_PACKAGE_TYPE) { 28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage >= dtohl(header->header->packageCount)) { 28318564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("More package chunks were found than the %d declared in the header.", 28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohl(header->header->packageCount)); 28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 283557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t idmap_id = 0; 283657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (idmap != NULL) { 283757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t tmp; 283857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (getIdmapPackageId(header->resourceIDMap, 283957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMapSize, 284057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad &tmp) == NO_ERROR) { 284157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad idmap_id = tmp; 284257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 284357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 284457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (parsePackage((ResTable_package*)chunk, header, idmap_id) != NO_ERROR) { 28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackage++; 28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 28498564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unknown chunk type %p in table at %p.\n", 28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(int)(ctype), 28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))); 28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + csize); 28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage < dtohl(header->header->packageCount)) { 28588564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.", 28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)curPackage, dtohl(header->header->packageCount)); 28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = header->values.getError(); 28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 28648564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No string values found in resource table!"); 28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 286657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 28675c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError)); 28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::getError() const 28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::uninit() 28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = mPackageGroups.size(); 28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* g = mPackageGroups[i]; 28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete g; 28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N = mHeaders.size(); 28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Header* header = mHeaders[i]; 288778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (header->owner == this) { 288878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (header->ownedData) { 288978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn free(header->ownedData); 289078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 289178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete header; 28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageGroups.clear(); 28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeaders.clear(); 28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::getResourceName(uint32_t resID, resource_name* outName) const 29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 29019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 29106cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn if (Res_GETPACKAGE(resID)+1 == 0) { 29118564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No package identifier when getting name for resource number 0x%08x", resID); 29126cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } else { 29138564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No known package when getting name for resource number 0x%08x", resID); 29146cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } 29159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 29188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting name for resource number 0x%08x", resID); 29199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* const grp = mPackageGroups[p]; 29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 29248564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting name for resource number 0x%08x", resID); 29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp->packages.size() > 0) { 29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[0]; 29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL); 29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName->package = grp->name.string(); 29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName->packageLen = grp->name.size(); 293978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen); 294078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn outName->name = grp->basePackage->keyStrings.stringAt( 29419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohl(entry->key.index), &outName->nameLen); 29423379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root 29433379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root // If we have a bad index for some reason, we should abort. 29443379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root if (outName->type == NULL || outName->name == NULL) { 29453379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root return false; 29463379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 29473379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root 29489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 29499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 295455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Rootssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density, 29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outSpecFlags, ResTable_config* outConfig) const 29569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 29649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 29666cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn if (Res_GETPACKAGE(resID)+1 == 0) { 29678564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No package identifier when getting value for resource number 0x%08x", resID); 29686cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } else { 29698564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No known package when getting value for resource number 0x%08x", resID); 29706cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } 29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 29748564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting value for resource number 0x%08x", resID); 29759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* bestValue = NULL; 29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* bestPackage = NULL; 29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config bestItem; 29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up 29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpecFlags != NULL) *outSpecFlags = 0; 298455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Look through all resource packages, starting with the most 29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // recently added. 29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* const grp = mPackageGroups[p]; 29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 29898564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting value for resource number 0x%08x", resID); 299020cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn return BAD_INDEX; 29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 299255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 299355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root // Allow overriding density 299455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root const ResTable_config* desiredConfig = &mParams; 299555fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root ResTable_config* overrideConfig = NULL; 299655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (density > 0) { 299755fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config)); 299855fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (overrideConfig == NULL) { 29993762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno)); 300055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root return BAD_INDEX; 300155fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 300255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root memcpy(overrideConfig, &mParams, sizeof(ResTable_config)); 300355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root overrideConfig->density = density; 300455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root desiredConfig = overrideConfig; 300555fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 300655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 30075c4cf8cd7ccd76f25a8433096774b44a6dd8ead8Kenny Root ssize_t rc = BAD_VALUE; 30089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t ip = grp->packages.size(); 30099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ip > 0) { 30109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ip--; 301157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int T = t; 301257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int E = e; 30139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[ip]; 301557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (package->header->resourceIDMap) { 301657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = 0x0; 301757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad status_t retval = idmapLookup(package->header->resourceIDMap, 301857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad package->header->resourceIDMapSize, 301957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, &overlayResID); 302057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (retval == NO_ERROR && overlayResID != 0x0) { 302157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // for this loop iteration, this is the type and entry we really want 302271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID); 302357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad T = Res_GETTYPE(overlayResID); 302457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad E = Res_GETENTRY(overlayResID); 302557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 302657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // resource not present in overlay package, continue with the next package 302757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 302857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 302957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 30309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeClass; 303418490fb93e206fd899c3258096cc32f293373c92Kenny Root ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass); 30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 303657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // No {entry, appropriate config} pair found in package. If this 303757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // package is an overlay package (ip != 0), this simply means the 303857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // overlay package did not specify a default. 303957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Non-overlay packages are still required to provide a default. 304057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (offset < 0 && ip == 0) { 30418564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n", 304257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, T, E, ip, (int)offset); 304355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = offset; 304455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 30459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 30479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) { 30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mayBeBag) { 30518564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Requesting resource %p failed because it is complex\n", 30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)resID); 30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 30559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(aout << "Resource type data: " 30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << HexDump(type, dtohl(type->header.size)) << endl); 305955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 30609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) { 30618564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_item at %d is beyond type chunk data %d", 30629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)offset, dtohl(type->header.size)); 306355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = BAD_TYPE; 306455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 306655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* item = 30689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const Res_value*)(((const uint8_t*)type) + offset); 30699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 30709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(type->config); 30719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpecFlags != NULL) { 30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeClass->typeSpecFlags != NULL) { 307457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]); 30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 30769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outSpecFlags = -1; 30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 307957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 308057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (bestPackage != NULL && 308157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) { 308257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Discard thisConfig not only if bestItem is more specific, but also if the two configs 308357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // are identical (diff == 0), or overlay packages will not take effect. 30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 30859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestItem = thisConfig; 30889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestValue = item; 30899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestPackage = package; 30909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Found result: package %p\n", bestPackage)); 30939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bestValue) { 30959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->size = dtohs(bestValue->size); 30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->res0 = bestValue->res0; 30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = bestValue->dataType; 30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = dtohl(bestValue->data); 30999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outConfig != NULL) { 31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outConfig = bestItem; 31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(size_t len; 31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n", 31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestPackage->header->index, 31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType, 31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType == bestValue->TYPE_STRING 31079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? String8(bestPackage->header->values.stringAt( 31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data, &len)).string() 31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : "", 31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data)); 311155fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = bestPackage->header->index; 311255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 311355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 311455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 311555fc850cf992cdcb0993cb109d2f716613c0dbddKenny Rootout: 311655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (overrideConfig != NULL) { 311755fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root free(overrideConfig); 31189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 312055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root return rc; 31219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, 31240d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags, 31250d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn ResTable_config* outConfig) const 31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count=0; 31289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE 31299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && value->data != 0 && count < 20) { 31309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outLastRef) *outLastRef = value->data; 31319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t lastRef = value->data; 31329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t newFlags = 0; 313355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags, 31340d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn outConfig); 313520cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn if (newIndex == BAD_INDEX) { 313620cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn return BAD_INDEX; 313720cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn } 31385c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n", 3139b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data)); 31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex); 31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags; 31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newIndex < 0) { 31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This can fail if the resource being referenced is a style... 31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in this case, just return the reference, and expect the 31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // caller to deal with. 31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blockIndex = newIndex; 31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char16_t* ResTable::valueToString( 31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* value, size_t stringBlock, 31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen) 31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!value) { 31599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 31609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value->dataType == value->TYPE_STRING) { 31629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getTableStringBlock(stringBlock)->stringAt(value->data, outLen); 31639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XXX do int to string conversions. 31659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 31669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const 31699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 31719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t err = getBagLocked(resID, outBag); 31729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 31739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("*** get failed! unlocking\n"); 31749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::unlockBag(const bag_entry* bag) const 31809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("<<< unlockBag %p\n", this); 31829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 31839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::lock() const 31869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 31889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::unlock() const 31919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 31939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag, 31969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 31979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 31999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 32009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 32039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 32078564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID); 32089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 32118564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting bag for resource number 0x%08x", resID); 32129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 32139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t); 32169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mPackageGroups[p]; 32179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 32188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting bag for resource number 0x%08x", resID); 32199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 32209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t >= (int)grp->typeCount) { 32238564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Type identifier 0x%x is larger than type count 0x%x", 32249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t+1, (int)grp->typeCount); 32259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 32269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const basePackage = grp->packages[0]; 32299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* const typeConfigs = basePackage->getType(t); 32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NENTRY = typeConfigs->entryCount; 32339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e >= (int)NENTRY) { 32348564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Entry identifier 0x%x is larger than entry count 0x%x", 32359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e, (int)typeConfigs->entryCount); 32369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 32379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First see if we've already computed this bag... 32409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp->bags) { 32419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeSet = grp->bags[t]; 32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeSet) { 32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set* set = typeSet[e]; 32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) { 32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set != (bag_set*)0xFFFFFFFF) { 32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) { 32479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = set->typeSpecFlags; 32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outBag = (bag_entry*)(set+1); 32506215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Found existing bag for: %p\n", (void*)resID); 32519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return set->numAttrs; 32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32538564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.", 32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resID); 32559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bag not found, we need to compute it! 32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!grp->bags) { 32627e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*)); 32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!grp->bags) return NO_MEMORY; 32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeSet = grp->bags[t]; 32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!typeSet) { 32687e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*)); 32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!typeSet) return NO_MEMORY; 32709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project grp->bags[t] = typeSet; 32719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mark that we are currently working on this one. 32749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSet[e] = (bag_set*)0xFFFFFFFF; 32759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is what we are building. 32779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set* set = NULL; 32789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32795c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID)); 32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 328157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ResTable_config bestConfig; 328257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memset(&bestConfig, 0, sizeof(bestConfig)); 328357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 32849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now collect all bag attributes from all packages. 32859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t ip = grp->packages.size(); 32869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ip > 0) { 32879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ip--; 328857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int T = t; 328957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int E = e; 32909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[ip]; 329257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (package->header->resourceIDMap) { 329357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = 0x0; 329457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad status_t retval = idmapLookup(package->header->resourceIDMap, 329557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad package->header->resourceIDMapSize, 329657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, &overlayResID); 329757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (retval == NO_ERROR && overlayResID != 0x0) { 329857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // for this loop iteration, this is the type and entry we really want 329971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID); 330057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad T = Res_GETTYPE(overlayResID); 330157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad E = Res_GETENTRY(overlayResID); 330257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 330357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // resource not present in overlay package, continue with the next package 330457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 330557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 330657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 33079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 33099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 33109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeClass; 331171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E); 331257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass); 331371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Resulting offset=%d\n", offset); 33149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 331557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // No {entry, appropriate config} pair found in package. If this 331657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // package is an overlay package (ip != 0), this simply means the 331757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // overlay package did not specify a default. 331857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Non-overlay packages are still required to provide a default. 331957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (offset < 0 && ip == 0) { 33209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) free(set); 33219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return offset; 33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 33249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) { 33278564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Skipping entry %p in package table %d because it is not complex!\n", 33289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)resID, (int)ip); 33299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 33309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 333257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set != NULL && !type->config.isBetterThan(bestConfig, NULL)) { 333357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 333457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 333557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad bestConfig = type->config; 333657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set) { 333757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad free(set); 333857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = NULL; 333957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 334057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 33419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t entrySize = dtohs(entry->size); 33429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t parent = entrySize >= sizeof(ResTable_map_entry) 33439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0; 33449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t count = entrySize >= sizeof(ResTable_map_entry) 33459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? dtohl(((const ResTable_map_entry*)entry)->count) : 0; 33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = count; 33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33495c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n", 33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entrySize, parent, count)); 33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 335257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // If this map inherits from another, we need to start 335357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // with its parent's values. Otherwise start out empty. 335457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n", 335557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad entrySize, parent)); 335657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (parent) { 335757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const bag_entry* parentBag; 335857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t parentTypeSpecFlags = 0; 335957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags); 336057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t NT = ((NP >= 0) ? NP : 0) + N; 336157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT); 336257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set == NULL) { 336357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 336457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 336557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (NP > 0) { 336657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memcpy(set+1, parentBag, NP*sizeof(bag_entry)); 336757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->numAttrs = NP; 33685c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP)); 33699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 33705c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n")); 33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs = 0; 33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 337357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->availAttrs = NT; 337457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags = parentTypeSpecFlags; 337557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 337657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N); 337757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set == NULL) { 337857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 337957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 338057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->numAttrs = 0; 338157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->availAttrs = N; 338257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags = 0; 33839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeClass->typeSpecFlags != NULL) { 338657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[E]); 33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->typeSpecFlags = -1; 33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now merge in the new attributes... 33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t curOff = offset; 33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_map* map; 33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_entry* entries = (bag_entry*)(set+1); 33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curEntry = 0; 33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t pos = 0; 33975c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n", 33989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set, entries, set->availAttrs)); 33999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < count) { 34009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Now at %p\n", (void*)curOff)); 34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) { 34038564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_map at %d is beyond type chunk data %d", 34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)curOff, dtohl(type->header.size)); 34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map = (const ResTable_map*)(((const uint8_t*)type) + curOff); 34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N++; 34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t newName = htodl(map->name.ident); 34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isInside; 34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t oldName = 0; 34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((isInside=(curEntry < set->numAttrs)) 34149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (oldName=entries[curEntry].map.name.ident) < newName) { 34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n", 34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, entries[curEntry].map.name.ident)); 34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry++; 34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((!isInside) || oldName != newName) { 34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a new attribute... figure out what to do with it. 34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set->numAttrs >= set->availAttrs) { 34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Need to alloc more memory... 34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t newAvail = set->availAttrs+N; 34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set = (bag_set*)realloc(set, 34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(bag_set) 34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + sizeof(bag_entry)*newAvail); 34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set == NULL) { 34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 34309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->availAttrs = newAvail; 34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entries = (bag_entry*)(set+1); 34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n", 34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set, entries, set->availAttrs)); 34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isInside) { 34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Going in the middle, need to make space. 34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(entries+curEntry+1, entries+curEntry, 34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(bag_entry)*(set->numAttrs-curEntry)); 34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs++; 34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n", 34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, newName)); 34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n", 34469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, oldName)); 34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_entry* cur = entries+curEntry; 34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->stringBlock = package->header->index; 34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.name.ident = newName; 34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.value.copyFrom_dtoh(map->value); 34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n", 34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, cur, cur->stringBlock, cur->map.name.ident, 34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.value.dataType, cur->map.value.data)); 34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // On to the next! 34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry++; 34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 34619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = dtohs(map->value.size); 34629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curOff += size + sizeof(*map)-sizeof(map->value); 34639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 34649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curEntry > set->numAttrs) { 34659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs = curEntry; 34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // And this is it... 34709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSet[e] = set; 34719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) { 34729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) { 34739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = set->typeSpecFlags; 34749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outBag = (bag_entry*)(set+1); 34765c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs)); 34779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return set->numAttrs; 34789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 34819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::setParameters(const ResTable_config* params) 34839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 34849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 34855c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string())); 34869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams = *params; 34879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<mPackageGroups.size(); i++) { 34885c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i)); 34899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageGroups[i]->clearBagCache(); 34909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 34929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 34939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getParameters(ResTable_config* params) const 34959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 34969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 34979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *params = mParams; 34989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 34999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 35009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct id_name_map { 35029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t id; 35039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 35049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t name[6]; 35059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 35069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst static id_name_map ID_NAMES[] = { 35089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_TYPE, 5, { '^', 't', 'y', 'p', 'e' } }, 35099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_L10N, 5, { '^', 'l', '1', '0', 'n' } }, 35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MIN, 4, { '^', 'm', 'i', 'n' } }, 35119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MAX, 4, { '^', 'm', 'a', 'x' } }, 35129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } }, 35139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_ZERO, 5, { '^', 'z', 'e', 'r', 'o' } }, 35149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_ONE, 4, { '^', 'o', 'n', 'e' } }, 35159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_TWO, 4, { '^', 't', 'w', 'o' } }, 35169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_FEW, 4, { '^', 'f', 'e', 'w' } }, 35179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MANY, 5, { '^', 'm', 'a', 'n', 'y' } }, 35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen, 35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* type, size_t typeLen, 35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* package, 35239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t packageLen, 35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError)); 35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check for internal resource identifier as the very first thing, so 35299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // that we will always find them even when there are no resources. 35309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name[0] == '^') { 35319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0])); 35329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 35339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 35349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const id_name_map* m = ID_NAMES + i; 35359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = m->len; 35369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len != nameLen) { 35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=1; j<len; j++) { 35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m->name[j] != name[j]) { 35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto nope; 35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3544426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outTypeSpecFlags) { 3545426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC; 3546426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return m->id; 35489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnope: 35499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ; 35509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nameLen > 7) { 35529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name[1] == 'i' && name[2] == 'n' 35539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && name[3] == 'd' && name[4] == 'e' && name[5] == 'x' 35549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && name[6] == '_') { 35559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = atoi(String8(name + 7, nameLen - 7).string()); 35569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Res_CHECKID(index)) { 35578564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Array resource index: %d is too large.", 35589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index); 35599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 35609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3561426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outTypeSpecFlags) { 3562426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC; 3563426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 35649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_MAKEARRAY(index); 35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 35689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 35719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 35729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3574426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn bool fakePublic = false; 3575426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn 35769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Figure out the package and type we are looking in... 35779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* packageEnd = NULL; 35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* typeEnd = NULL; 35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* const nameEnd = name+nameLen; 35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = name; 35829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < nameEnd) { 35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == ':') packageEnd = p; 35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (*p == '/') typeEnd = p; 35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3587426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*name == '@') { 3588426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn name++; 3589426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*name == '*') { 3590426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn fakePublic = true; 3591426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn name++; 3592426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3593426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name >= nameEnd) { 35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 35969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (packageEnd) { 35999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package = name; 36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project packageLen = packageEnd-name; 36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = packageEnd+1; 36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!package) { 36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeEnd) { 36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = name; 36089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeLen = typeEnd-name; 36099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = typeEnd+1; 36109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!type) { 36119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 36129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name >= nameEnd) { 36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nameLen = nameEnd-name; 36189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n", 36209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(type, typeLen).string(), 36219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name, nameLen).string(), 36229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package, packageLen).string())); 36239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NG = mPackageGroups.size(); 36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t ig=0; ig<NG; ig++) { 36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* group = mPackageGroups[ig]; 36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(package, packageLen, 36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group->name.string(), group->name.size())) { 36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string())); 36319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 363478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen); 36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ti < 0) { 36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string())); 36379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 364078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen); 36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ei < 0) { 36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string())); 36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei)); 36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* const typeConfigs = group->packages[0]->getType(ti); 36499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) { 36509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n", 36519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(group->name).string(), ti)); 36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t NTC = typeConfigs->configs.size(); 36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t tci=0; tci<NTC; tci++) { 36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* const ty = typeConfigs->configs[tci]; 36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t typeOffset = dtohl(ty->entriesStart); 36589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size); 36609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 36619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ty) + dtohs(ty->header.headerSize)); 36629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NE = dtohl(ty->entryCount); 36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<NE; i++) { 36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset = dtohl(eindex[i]); 36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset == ResTable_type::NO_ENTRY) { 36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset += typeOffset; 36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) { 36738564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at %d is beyond type chunk data %d", 36749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset, dtohl(ty->header.size)); 36759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 36769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset&0x3) != 0) { 36788564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s", 36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)offset, (int)group->id, (int)ti+1, (int)i, 36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package, packageLen).string(), 36819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(type, typeLen).string(), 36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name, nameLen).string()); 36839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 36849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* const entry = (const ResTable_entry*) 36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ty) + offset); 36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(entry->size) < sizeof(*entry)) { 36898564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry size %d is too small", dtohs(entry->size)); 36909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 36919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n", 36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i, ei, dtohl(entry->key.index))); 36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(entry->key.index) == (size_t)ei) { 36969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags) { 36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = typeConfigs->typeSpecFlags[i]; 3698426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (fakePublic) { 3699426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; 3700426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_MAKEID(group->id-1, ti, i); 37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen, 37129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outPackage, 37139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outType, 37149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outName, 37159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defType, 37169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defPackage, 3717426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn const char** outErrorMsg, 3718426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn bool* outPublicOnly) 37199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 37209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* packageEnd = NULL; 37219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* typeEnd = NULL; 37229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = refStr; 37239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* const end = p + refLen; 37249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < end) { 37259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == ':') packageEnd = p; 37269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (*p == '/') { 37279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeEnd = p; 37289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 37299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 37319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = refStr; 37339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == '@') p++; 37349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3735426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outPublicOnly != NULL) { 3736426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outPublicOnly = true; 3737426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3738426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*p == '*') { 3739426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn p++; 3740426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outPublicOnly != NULL) { 3741426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outPublicOnly = false; 3742426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3743426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3744426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn 37459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (packageEnd) { 37469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outPackage = String16(p, packageEnd-p); 37479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = packageEnd+1; 37489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 37499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defPackage) { 37509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 37519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "No resource package specified"; 37529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 37549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outPackage = *defPackage; 37569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeEnd) { 37589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = String16(p, typeEnd-p); 37599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = typeEnd+1; 37609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 37619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defType) { 37629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 37639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "No resource type specified"; 37649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 37669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = *defType; 37689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outName = String16(p, end-p); 3770ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outPackage == 0) { 3771ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3772ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource package cannot be an empty string"; 3773ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3774ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3775ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3776ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outType == 0) { 3777ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3778ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource type cannot be an empty string"; 3779ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3780ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3781ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3782ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outName == 0) { 3783ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3784ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource id cannot be an empty string"; 3785ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3786ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3787ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 37889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 37899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 37909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t get_hex(char c, bool* outError) 37929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 37939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c >= '0' && c <= '9') { 37949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - '0'; 37959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (c >= 'a' && c <= 'f') { 37969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - 'a' + 0xa; 37979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (c >= 'A' && c <= 'F') { 37989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - 'A' + 0xa; 37999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outError = true; 38019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 38039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct unit_entry 38059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 38069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* name; 38079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 38089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t type; 38099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t unit; 38109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale; 38119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 38129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const unit_entry unitNames[] = { 38149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f }, 38159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f }, 38169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f }, 38179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f }, 38189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f }, 38199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f }, 38209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f }, 38219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 }, 38229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 }, 38239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { NULL, 0, 0, 0, 0 } 38249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 38259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool parse_unit(const char* str, Res_value* outValue, 38279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* outScale, const char** outEnd) 38289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 38299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* end = str; 38309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*end != 0 && !isspace((unsigned char)*end)) { 38319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project end++; 38329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t len = end-str; 38349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* realEnd = end; 38369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*realEnd != 0 && isspace((unsigned char)*realEnd)) { 38379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project realEnd++; 38389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*realEnd != 0) { 38409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 38419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const unit_entry* cur = unitNames; 38449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cur->name) { 38459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == cur->len && strncmp(cur->name, str, len) == 0) { 38469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = cur->type; 38479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT; 38489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outScale = cur->scale; 38499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outEnd = end; 38509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Found unit %s for %s\n", cur->name, str); 38519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 38529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur++; 38549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 38579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 38589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) 38619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 38629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 38639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 38649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 38659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len <= 0) { 38689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 38699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i = 0; 38729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t val = 0; 38739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool neg = false; 38749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '-') { 38769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project neg = true; 38779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 38789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] < '0' || s[i] > '9') { 38819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 38829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Decimal or hex? 38859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] == '0' && s[i+1] == 'x') { 38869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 38879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_HEX; 38889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i += 2; 38899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool error = false; 38909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len && !error) { 38919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val = (val*16) + get_hex(s[i], &error); 38929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 38939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error) { 38959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 38969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 38989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 38999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_DEC; 39009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len) { 39019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] < '0' || s[i] > '9') { 39029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val = (val*10) + s[i]-'0'; 39059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 39069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) val = -val; 39109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len && isspace16(s[i])) { 39129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 39139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == len) { 39169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 39179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = val; 39189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 39199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 39239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) 39259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 39269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 39279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 39289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 39299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len <= 0) { 39329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 39369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i=0; 39379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && *s != 0 && i < 126) { 39389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s > 255) { 39399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[i++] = *s++; 39429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 39439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) { 39469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') { 39499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[i] = 0; 39539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* end; 39549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = strtof(buf, (char**)&end); 39559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*end != 0 && !isspace((unsigned char)*end)) { 39579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Might be a unit... 39589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale; 39599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parse_unit(end, outValue, &scale, &end)) { 39609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= scale; 39619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool neg = f < 0; 39629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) f = -f; 39639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint64_t bits = (uint64_t)(f*(1<<23)+.5f); 39649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t radix; 39659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t shift; 39669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((bits&0x7fffff) == 0) { 39679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always use 23p0 if there is no fraction, just to make 39689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // things easier to read. 39699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_23p0; 39709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 23; 39719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffffffff800000LL) == 0) { 39729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude is zero -- can fit in 0 bits of precision. 39739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_0p23; 39749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 0; 39759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffffff80000000LL) == 0) { 39769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude can fit in 8 bits of precision. 39779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_8p15; 39789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 8; 39799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffff8000000000LL) == 0) { 39809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude can fit in 16 bits of precision. 39819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_16p7; 39829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 16; 39839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 39849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude needs entire range, so no fractional part. 39859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_23p0; 39869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 23; 39879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t mantissa = (int32_t)( 39899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK); 39909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) { 39919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK; 39929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data |= 39949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (radix<<Res_value::COMPLEX_RADIX_SHIFT) 39959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT); 39969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n", 39979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // f * (neg ? -1 : 1), bits, f*(1<<23), 39989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // radix, shift, outValue->data); 39999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 40009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*end != 0 && isspace((unsigned char)*end)) { 40059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project end++; 40069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*end == 0) { 40099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) { 40109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_FLOAT; 40119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *(float*)(&outValue->data) = f; 40129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 40139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 40189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToValue(Res_value* outValue, String16* outString, 40209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s, size_t len, 40219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool preserveSpaces, bool coerceType, 40229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrID, 40239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defType, 40249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defPackage, 40259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Accessor* accessor, 40269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* accessorCookie, 40279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrType, 40289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool enforcePrivate) const 40299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 40309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting(); 40319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* errorMsg = NULL; 40329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->size = sizeof(Res_value); 40349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->res0 = 0; 40359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First strip leading/trailing whitespace. Do this before handling 40379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // escapes, so they can be used to force whitespace into the string. 40389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces) { 40399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 40409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 40419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 40429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(s[len-1])) { 40449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 40459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the string ends with '\', then we keep the space after it. 40479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0 && s[len-1] == '\\' && s[len] != 0) { 40489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len++; 40499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Value for: %s\n", String8(s, len).string()); 40539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED; 40559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff; 40569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool fromAccessor = false; 40579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attrID != 0 && !Res_INTERNALID(attrID)) { 40589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 40599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 40609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 40619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("For attr 0x%08x got bag of %d\n", attrID, cnt); 40629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 40639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cnt > 0) { 40649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data); 40659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (bag->map.name.ident) { 40669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_TYPE: 40679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrType = bag->map.value.data; 40689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 40699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_MIN: 40709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrMin = bag->map.value.data; 40719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 40729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_MAX: 40739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrMax = bag->map.value.data; 40749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 40759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_L10N: 40769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l10nReq = bag->map.value.data; 40779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 40789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 40809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 40819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 40839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (accessor && accessor->getAttributeType(attrID, &attrType)) { 40849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fromAccessor = true; 40859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attrType == ResTable_map::TYPE_ENUM 40869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || attrType == ResTable_map::TYPE_FLAGS 40879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || attrType == ResTable_map::TYPE_INTEGER) { 40889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getAttributeMin(attrID, &attrMin); 40899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getAttributeMax(attrID, &attrMax); 40909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localizationSetting) { 40929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l10nReq = accessor->getAttributeL10N(attrID); 40939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool canStringCoerce = 40989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project coerceType && (attrType&ResTable_map::TYPE_STRING) != 0; 40999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '@') { 41019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_REFERENCE; 41029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: we don't check attrType here because the reference can 41049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be to any other type; we just need to count on the client making 41059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sure the referenced type is correct. 41069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Looking up ref: %s\n", String8(s, len).string()); 41089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's a reference! 41109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') { 41119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 41129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 41149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool createIfNotFound = false; 41159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* resourceRefName; 41169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int resourceNameLen; 41179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 2 && s[1] == '+') { 41189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound = true; 41199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 2; 41209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 2; 41219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len > 2 && s[1] == '*') { 41229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforcePrivate = false; 41239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 2; 41249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 2; 41259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 41269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound = false; 41279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 1; 41289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 1; 41299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 package, type, name; 41319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name, 41329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defType, defPackage, &errorMsg)) { 41339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 41349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 41359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t specFlags = 0; 41409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = identifierForName(name.string(), name.size(), type.string(), 41419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type.size(), package.string(), package.size(), &specFlags); 41429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 41439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enforcePrivate) { 41449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) { 41459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 41469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Resource is not public."); 41479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!accessor) { 41529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 41539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rid = Res_MAKEID( 41569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getRemappedPackage(Res_GETPACKAGE(rid)), 41579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_GETTYPE(rid), Res_GETENTRY(rid)); 41589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n", 41599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package).string(), String8(type).string(), 41609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name).string(), rid)); 41619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 41629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor) { 41669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name, 41679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound); 41689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 41699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n", 41709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package).string(), String8(type).string(), 41719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name).string(), rid)); 41729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 41739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 41799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "No resource found that matches the given name"); 41809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we got to here, and localization is required and it's not a reference, 41859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // complain and bail. 41869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l10nReq == ResTable_map::L10N_SUGGESTED) { 41879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localizationSetting) { 41889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 41899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "This attribute must be localized."); 41909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '#') { 41959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's a color! Convert to an integer of the form 0xaarrggbb. 41969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t color = 0; 41979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool error = false; 41989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 4) { 41999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_RGB4; 42009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= 0xFF000000; 42019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 20; 42029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 16; 42039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 12; 42049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 8; 42059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 4; 42069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error); 42079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 5) { 42089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4; 42099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 28; 42109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 24; 42119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 20; 42129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 16; 42139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 12; 42149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 8; 42159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 4; 42169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error); 42179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 7) { 42189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_RGB8; 42199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= 0xFF000000; 42209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 20; 42219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 16; 42229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 12; 42239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 8; 42249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[5], &error) << 4; 42259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[6], &error); 42269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 9) { 42279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8; 42289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 28; 42299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 24; 42309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 20; 42319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 16; 42329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[5], &error) << 12; 42339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[6], &error) << 8; 42349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[7], &error) << 4; 42359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[8], &error); 42369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 42379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error = true; 42389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!error) { 42409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_COLOR) == 0) { 42419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 42429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 42439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, 42449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Color types not allowed"); 42459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 42479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 42499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = color; 42509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color); 42519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 42529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 42549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_COLOR) != 0) { 42559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 42569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Color value not valid --" 42579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " must be #rgb, #argb, #rrggbb, or #aarrggbb"); 42589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 42609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "%s: Color ID %s value %s is not valid\n", 42619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Resource File", //(const char*)in->getPrintableSource(), 42629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(*curTag).string(), 42639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s, len).string()); 42649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 42659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 42669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '?') { 42719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_ATTRIBUTE; 42729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: we don't check attrType here because the reference can 42749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be to any other type; we just need to count on the client making 42759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sure the referenced type is correct. 42769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Looking up attr: %s\n", String8(s, len).string()); 42789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static const String16 attr16("attr"); 42809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 package, type, name; 42819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!expandResourceRef(s+1, len-1, &package, &type, &name, 42829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &attr16, defPackage, &errorMsg)) { 42839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 42849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 42859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 42879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Pkg: %s, Type: %s, Name: %s\n", 42909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 42919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string()); 42929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t specFlags = 0; 42939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = 42949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project identifierForName(name.string(), name.size(), 42959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type.string(), type.size(), 42969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package.string(), package.size(), &specFlags); 42979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 42989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enforcePrivate) { 42999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) { 43009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Attribute is not public."); 43029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!accessor) { 43079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rid = Res_MAKEID( 43119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getRemappedPackage(Res_GETPACKAGE(rid)), 43129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_GETTYPE(rid), Res_GETENTRY(rid)); 43139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Incl %s:%s/%s: 0x%08x\n", 43149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 43159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string(), rid); 43169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor) { 43219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = accessor->getCustomResource(package, type, name); 43229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 43239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Mine %s:%s/%s: 0x%08x\n", 43249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 43259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string(), rid); 43269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "No resource found that matches the given name"); 43339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stringToInt(s, len, outValue)) { 43389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_INTEGER) == 0) { 43399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this type does not allow integers, but does allow floats, 43409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through on this error case because the float type should 43419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be able to accept any integer value. 43429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) { 43439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Integer types not allowed"); 43459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 43499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((int32_t)outValue->data) < ((int32_t)attrMin) 43509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || ((int32_t)outValue->data) > ((int32_t)attrMax)) { 43519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Integer value out of range"); 43539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stringToFloat(s, len, outValue)) { 43619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue->dataType == Res_value::TYPE_DIMENSION) { 43629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) { 43639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 43669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Dimension types not allowed"); 43689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (outValue->dataType == Res_value::TYPE_FRACTION) { 43729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_FRACTION) != 0) { 43739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 43769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Fraction types not allowed"); 43789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) { 43829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 43839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Float types not allowed"); 43859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 43899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 4) { 43949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((s[0] == 't' || s[0] == 'T') && 43959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[1] == 'r' || s[1] == 'R') && 43969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[2] == 'u' || s[2] == 'U') && 43979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[3] == 'e' || s[3] == 'E')) { 43989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) { 43999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 44009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Boolean types not allowed"); 44029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 44049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 44069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_BOOLEAN; 44079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = (uint32_t)-1; 44089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 44099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 5) { 44149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((s[0] == 'f' || s[0] == 'F') && 44159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[1] == 'a' || s[1] == 'A') && 44169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[2] == 'l' || s[2] == 'L') && 44179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[3] == 's' || s[3] == 'S') && 44189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[4] == 'e' || s[4] == 'E')) { 44199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) { 44209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 44219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Boolean types not allowed"); 44239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 44259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 44279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_BOOLEAN; 44289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 44299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 44309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_ENUM) != 0) { 44359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 44369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 44379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 44389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Got %d for enum\n", cnt); 44399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 44409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name rname; 44419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cnt > 0) { 44429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!Res_INTERNALID(bag->map.name.ident)) { 44439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Trying attr #%08x\n", bag->map.name.ident); 44449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getResourceName(bag->map.name.ident, &rname)) { 44459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 44469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Matching %s against %s (0x%08x)\n", 44479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s, len).string(), 44489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(rname.name, rname.nameLen).string(), 44499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag->map.name.ident); 44509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 44519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) { 44529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = bag->map.value.dataType; 44539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = bag->map.value.data; 44549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 44559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 44569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 44619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 44629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 44649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fromAccessor) { 44679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor->getAttributeEnum(attrID, s, len, outValue)) { 44689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 44699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_FLAGS) != 0) { 44749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 44759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 44769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 44779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Got %d for flags\n", cnt); 44789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 44799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool failed = false; 44809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name rname; 44819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = Res_value::TYPE_INT_HEX; 44829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 44839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* end = s + len; 44849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* pos = s; 44859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < end && !failed) { 44869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* start = pos; 44874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project pos++; 44889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < end && *pos != '|') { 44899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 44909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Looking for: %s\n", String8(start, pos-start).string()); 44929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bagi = bag; 44934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ssize_t i; 44949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<cnt; i++, bagi++) { 44959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!Res_INTERNALID(bagi->map.name.ident)) { 44969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Trying attr #%08x\n", bagi->map.name.ident); 44979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getResourceName(bagi->map.name.ident, &rname)) { 44989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 44999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Matching %s against %s (0x%08x)\n", 45009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(start,pos-start).string(), 45019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(rname.name, rname.nameLen).string(), 45029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bagi->map.name.ident); 45039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 45049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) { 45059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data |= bagi->map.value.data; 45069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 45079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i >= cnt) { 45129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Didn't find this flag identifier. 45139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failed = true; 45149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos < end) { 45169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 45179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 45209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!failed) { 45214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Final flag value: 0x%lx\n", outValue->data); 45229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fromAccessor) { 45289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor->getAttributeFlags(attrID, s, len, outValue)) { 45294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Final flag value: 0x%lx\n", outValue->data); 45309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_STRING) == 0) { 45369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "String types not allowed"); 45389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Generic string handling... 45439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_STRING; 45449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outString) { 45459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg); 45469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 45489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return failed; 45509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 45549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::collectString(String16* outString, 45569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s, size_t len, 45579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool preserveSpaces, 45589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char** outErrorMsg, 45599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool append) 45609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 45619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 tmp; 45629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char quoted = 0; 45649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = s; 45659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len)) { 45669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len)) { 45679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t c = *p; 45689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '\\') { 45699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 45709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces) { 45729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (quoted == 0 && isspace16(c) 45739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (c != ' ' || isspace16(*(p+1)))) { 45749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 45759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '"' && (quoted == 0 || quoted == '"')) { 45779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 45789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '\'' && (quoted == 0 || quoted == '\'')) { 4580c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer /* 4581c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * In practice, when people write ' instead of \' 4582c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * in a string, they are doing it by accident 4583c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * instead of really meaning to use ' as a quoting 4584c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * character. Warn them so they don't lose it. 4585c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer */ 4586c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer if (outErrorMsg) { 4587c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer *outErrorMsg = "Apostrophe not preceded by \\"; 4588c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer } 4589c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer return false; 45909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 45939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < (s+len)) { 45959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p > s) { 45969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(s, p-s)); 45979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces && (*p == '"' || *p == '\'')) { 45999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (quoted == 0) { 46009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project quoted = *p; 46019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project quoted = 0; 46039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!preserveSpaces && isspace16(*p)) { 46069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Space outside of a quote -- consume all spaces and 46079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // leave a single plain space char. 46089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(" ")); 46099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len) && isspace16(*p)) { 46119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p == '\\') { 46149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < (s+len)) { 46169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (*p) { 46179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 't': 46189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\t")); 46199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'n': 46219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\n")); 46229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '#': 46249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("#")); 46259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '@': 46279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("@")); 46289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '?': 46309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("?")); 46319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '"': 46339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\"")); 46349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\'': 46369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("'")); 46379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\\': 46399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\\")); 46409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'u': 46429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 46439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t chr = 0; 46449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 46459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < 4 && p[1] != 0) { 46469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 46489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c; 46499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p >= '0' && *p <= '9') { 46509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - '0'; 46519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p >= 'a' && *p <= 'f') { 46529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - 'a' + 10; 46539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p >= 'A' && *p <= 'F') { 46549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - 'A' + 10; 46559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 46579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "Bad character in \\u unicode escape sequence"; 46589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 46609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chr = (chr<<4) | c; 46629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(&chr, 1)); 46649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 46659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 46669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore unknown escape chars. 46679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 46689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 46709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len -= (p-s); 46739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = p; 46749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tmp.size() != 0) { 46789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) { 46799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(s, len)); 46809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (append) { 46829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->append(tmp); 46839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->setTo(tmp); 46859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (append) { 46889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->append(String16(s, len)); 46899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->setTo(s, len); 46919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 46959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 46969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResTable::getBasePackageCount() const 46989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 46999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 47009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 47019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups.size(); 47039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char16_t* ResTable::getBasePackageName(size_t idx) const 47069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 47089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 47099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(idx >= mPackageGroups.size(), 47119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requested package index %d past package count %d", 47129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)mPackageGroups.size()); 47139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups[idx]->name.string(); 47149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResTable::getBasePackageId(size_t idx) const 47179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 47199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 47209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(idx >= mPackageGroups.size(), 47229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requested package index %d past package count %d", 47239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)mPackageGroups.size()); 47249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups[idx]->id; 47259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResTable::getTableCount() const 47289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeaders.size(); 47309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool* ResTable::getTableStringBlock(size_t index) const 47339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return &mHeaders[index]->values; 47359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* ResTable::getTableCookie(size_t index) const 47389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeaders[index]->cookie; 47409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getConfigurations(Vector<ResTable_config>* configs) const 47439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t I = mPackageGroups.size(); 47459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<I; i++) { 47469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* packageGroup = mPackageGroups[i]; 47479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t J = packageGroup->packages.size(); 47489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<J; j++) { 47499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* package = packageGroup->packages[j]; 47509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t K = package->types.size(); 47519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t k=0; k<K; k++) { 47529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = package->types[k]; 47539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == NULL) continue; 47549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t L = type->configs.size(); 47559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t l=0; l<L; l++) { 47569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* config = type->configs[l]; 47579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_config* cfg = &config->config; 47589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only insert unique 47599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t M = configs->size(); 47609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t m; 47619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (m=0; m<M; m++) { 47629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == (*configs)[m].compare(*cfg)) { 47639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we didn't find it 47679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m == M) { 47689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project configs->add(*cfg); 47699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getLocales(Vector<String8>* locales) const 47779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<ResTable_config> configs; 477971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("calling getConfigurations"); 47809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getConfigurations(&configs); 478171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("called getConfigurations size=%d", (int)configs.size()); 47829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t I = configs.size(); 47839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<I; i++) { 47849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char locale[6]; 47859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project configs[i].getLocale(locale); 47869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t J = locales->size(); 47879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t j; 47889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (j=0; j<J; j++) { 47899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strcmp(locale, (*locales)[j].string())) { 47909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (j == J) { 47949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locales->add(String8(locale)); 47959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::getEntry( 48009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* package, int typeIndex, int entryIndex, 48019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_config* config, 48029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type** outType, const ResTable_entry** outEntry, 48039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type** outTypeClass) const 48049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 480571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Getting entry from package %p\n", package); 48069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_package* const pkg = package->package; 48079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* allTypes = package->getType(typeIndex); 480971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("allTypes=%p\n", allTypes); 48109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (allTypes == NULL) { 481171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex); 48129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 48139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)entryIndex >= allTypes->entryCount) { 48168564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d", 48179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entryIndex, (int)allTypes->entryCount); 48189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 48199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = NULL; 48229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset = ResTable_type::NO_ENTRY; 48239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config bestConfig; 48249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up 48259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NT = allTypes->configs.size(); 48279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<NT; i++) { 48289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* const thisType = allTypes->configs[i]; 48299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisType == NULL) continue; 48309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 48329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(thisType->config); 48339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48345c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n", 48359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entryIndex, typeIndex+1, dtohl(thisType->config.size), 48366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn thisConfig.toString().string())); 48379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check to make sure this one is valid for the current parameters. 48399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (config && !thisConfig.match(*config)) { 48405c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Does not match config!\n")); 48419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 48429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if there is the desired entry in this type. 48459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)thisType) 48479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohl(thisType->header.size); 48489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 48499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize)); 48509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t thisOffset = dtohl(eindex[entryIndex]); 48529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisOffset == ResTable_type::NO_ENTRY) { 48535c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n")); 48549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 48559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != NULL) { 48589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if this one is less specific than the last found. If so, 48599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we will skip it. We check starting with things we most care 48609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // about to those we least care about. 48619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!thisConfig.isBetterThan(bestConfig, config)) { 48625c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("This config is worse than last!\n")); 48639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 48649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = thisType; 48689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = thisOffset; 48699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestConfig = thisConfig; 48705c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n")); 48719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!config) break; 48729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == NULL) { 48755c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("No value found for requested entry!\n")); 48769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 48779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset += dtohl(type->entriesStart); 48809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(aout << "Looking in resource table " << package->header->header 48819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << ", typeOff=" 48829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << (void*)(((const char*)type)-((const char*)package->header->header)) 48839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << ", offset=" << (void*)offset << endl); 48849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) { 48868564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x", 48879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset, dtohl(type->header.size)); 48889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 48899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset&0x3) != 0) { 48918564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at 0x%x is not on an integer boundary", 48929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset); 48939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 48949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* const entry = (const ResTable_entry*) 48979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + offset); 48989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(entry->size) < sizeof(*entry)) { 48998564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size)); 49009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 49019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = type; 49049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outEntry = entry; 49059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeClass != NULL) { 49069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeClass = allTypes; 49079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return offset + dtohs(entry->size); 49099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::parsePackage(const ResTable_package* const pkg, 491257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Header* const header, uint32_t idmap_id) 49139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* base = (const uint8_t*)pkg; 49159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(&pkg->header, sizeof(*pkg), 49169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd, "ResTable_package"); 49179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 49189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 49199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t pkgSize = dtohl(pkg->header.size); 49229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(pkg->typeStrings) >= pkgSize) { 49248564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package type strings at %p are past chunk size %p.", 49259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->typeStrings), (void*)pkgSize); 49269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 49279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(pkg->typeStrings)&0x3) != 0) { 49298564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package type strings at %p is not on an integer boundary.", 49309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->typeStrings)); 49319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 49329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(pkg->keyStrings) >= pkgSize) { 49348564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package key strings at %p are past chunk size %p.", 49359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->keyStrings), (void*)pkgSize); 49369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 49379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(pkg->keyStrings)&0x3) != 0) { 49398564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package key strings at %p is not on an integer boundary.", 49409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->keyStrings)); 49419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 49429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Package* package = NULL; 49459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* group = NULL; 494657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t id = idmap_id != 0 ? idmap_id : dtohl(pkg->id); 494757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // If at this point id == 0, pkg is an overlay package without a 494857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // corresponding idmap. During regular usage, overlay packages are 494957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // always loaded alongside their idmaps, but during idmap creation 495057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // the package is temporarily loaded by itself. 495157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (id < 256) { 495278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 495378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn package = new Package(this, header, pkg); 495478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (package == NULL) { 495578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn return (mError=NO_MEMORY); 495678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 495778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 49589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t idx = mPackageMap[id]; 49599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx == 0) { 49609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx = mPackageGroups.size()+1; 49619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)]; 49639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t)); 496478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn group = new PackageGroup(this, String16(tmpName), id); 49659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group == NULL) { 496678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 49679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 49689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 497078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings), 49719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd-(base+dtohl(pkg->typeStrings))); 49729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 497378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete group; 497478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 49759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 49769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 497778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings), 49789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd-(base+dtohl(pkg->keyStrings))); 49799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 498078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete group; 498178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 49829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 49839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Adding new package id %d at index %d\n", id, idx); 49869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = mPackageGroups.add(group); 49879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 49889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 49899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 499078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn group->basePackage = package; 499178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 49929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageMap[id] = (uint8_t)idx; 49939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 49949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group = mPackageGroups.itemAt(idx-1); 49959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group == NULL) { 49969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=UNKNOWN_ERROR); 49979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = group->packages.add(package); 50009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 50019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 50029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 500457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad LOG_ALWAYS_FATAL("Package id out of range"); 50059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 50069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Iterate through all chunks. 50109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curPackage = 0; 50119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 50139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)pkg) 50149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(pkg->header.headerSize)); 50159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size); 50169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) && 50179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) { 50185c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n", 50199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size), 50209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)))); 50219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t csize = dtohl(chunk->size); 50229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t ctype = dtohs(chunk->type); 50239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ctype == RES_TABLE_TYPE_SPEC_TYPE) { 50249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk); 50259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = validate_chunk(&typeSpec->header, sizeof(*typeSpec), 50269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_typeSpec"); 50279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 50289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 50299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t typeSpecSize = dtohl(typeSpec->header.size); 50329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n", 50349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(base-(const uint8_t*)chunk), 50359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(typeSpec->header.type), 50369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(typeSpec->header.headerSize), 50379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize)); 50389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // look for block overrun or int overflow when multiplying by 4 50399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t)) 50409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount)) 50419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > typeSpecSize)) { 50428564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.", 50439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dtohs(typeSpec->header.headerSize) 50449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))), 50459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSpecSize); 50469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 50479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeSpec->id == 0) { 50508564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type has an id of 0."); 50519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 50529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (package->types.size() < typeSpec->id) { 50559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.add(NULL); 50569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type* t = package->types[typeSpec->id-1]; 50589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == NULL) { 50599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = new Type(header, package, dtohl(typeSpec->entryCount)); 50609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.editItemAt(typeSpec->id-1) = t; 50619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (dtohl(typeSpec->entryCount) != t->entryCount) { 50628564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d", 50639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(typeSpec->entryCount), (int)t->entryCount); 50649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 50659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->typeSpecFlags = (const uint32_t*)( 50679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize)); 50689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->typeSpec = typeSpec; 50699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ctype == RES_TABLE_TYPE_TYPE) { 50719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = (const ResTable_type*)(chunk); 50729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4, 50739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_type"); 50749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 50759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 50769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t typeSize = dtohl(type->header.size); 50799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n", 50819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(base-(const uint8_t*)chunk), 50829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(type->header.type), 50839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(type->header.headerSize), 50849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize)); 50859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount)) 50869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > typeSize) { 50878564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entry index to %p extends beyond chunk end %p.", 50889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dtohs(type->header.headerSize) 50899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project +(sizeof(uint32_t)*dtohl(type->entryCount))), 50909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize); 50919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 50929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(type->entryCount) != 0 50949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) { 50958564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.", 50969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(type->entriesStart), (void*)typeSize); 50979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 50989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type->id == 0) { 51008564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type has an id of 0."); 51019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (package->types.size() < type->id) { 51059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.add(NULL); 51069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type* t = package->types[type->id-1]; 51089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == NULL) { 51099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = new Type(header, package, dtohl(type->entryCount)); 51109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.editItemAt(type->id-1) = t; 51119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (dtohl(type->entryCount) != t->entryCount) { 51128564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entry count inconsistent: given %d, previously %d", 51139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(type->entryCount), (int)t->entryCount); 51149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_GETENTRY( 51189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 51199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(type->config); 51206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGI("Adding config to type %d: %s\n", 51216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn type->id, thisConfig.toString().string())); 51229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->configs.add(type); 51239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 51249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), 51259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_package:unknown"); 51269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 51279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 51319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + csize); 51329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group->typeCount == 0) { 51359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group->typeCount = package->types.size(); 51369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 51399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 51409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 514157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc, 514257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad void** outData, size_t* outSize) const 514357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 514457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // see README for details on the format of map 514557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mPackageGroups.size() == 0) { 514657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 514757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 514857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mPackageGroups[0]->packages.size() == 0) { 514957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 515057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 515157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 515257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Vector<Vector<uint32_t> > map; 515357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const PackageGroup* pg = mPackageGroups[0]; 515457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Package* pkg = pg->packages[0]; 515557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t typeCount = pkg->types.size(); 515657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // starting size is header + first item (number of types in map) 515757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t); 515857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name); 515957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t pkg_id = pkg->package->id << 24; 516057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 516157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) { 5162249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ssize_t first = -1; 5163249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ssize_t last = -1; 516457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Type* typeConfigs = pkg->getType(typeIndex); 516557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ssize_t mapIndex = map.add(); 516657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mapIndex < 0) { 516757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 516857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 516957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Vector<uint32_t>& vector = map.editItemAt(mapIndex); 517057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) { 5171c761d8b0086f9e92eb1e4b3a5683ae6afb84036aMårten Kongstad uint32_t resID = pkg_id 517257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad | (0x00ff0000 & ((typeIndex+1)<<16)) 517357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad | (0x0000ffff & (entryIndex)); 517457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resource_name resName; 517557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!this->getResourceName(resID, &resName)) { 51768564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID); 5177249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // add dummy value, or trimming leading/trailing zeroes later will fail 5178249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.push(0); 5179fcaba1464ef010ba0e3fdcbce2af74e45daec627Mårten Kongstad continue; 518057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 518157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 518257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayType(resName.type, resName.typeLen); 518357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayName(resName.name, resName.nameLen); 518457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = overlay.identifierForName(overlayName.string(), 518557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayName.size(), 518657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayType.string(), 518757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayType.size(), 518857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayPackage.string(), 518957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayPackage.size()); 519057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (overlayResID != 0) { 5191c761d8b0086f9e92eb1e4b3a5683ae6afb84036aMårten Kongstad overlayResID = pkg_id | (0x00ffffff & overlayResID); 5192249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad last = Res_GETENTRY(resID); 5193249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (first == -1) { 5194249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad first = Res_GETENTRY(resID); 5195249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad } 519657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 519757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad vector.push(overlayResID); 519857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#if 0 519957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (overlayResID != 0) { 52005baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("%s/%s 0x%08x -> 0x%08x\n", 520157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad String8(String16(resName.type)).string(), 520257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad String8(String16(resName.name)).string(), 520357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, overlayResID); 520457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 520557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#endif 520657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 520757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 5208249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (first != -1) { 5209249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // shave off trailing entries which lack overlay values 5210249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad const size_t last_past_one = last + 1; 5211249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (last_past_one < vector.size()) { 5212249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.removeItemsAt(last_past_one, vector.size() - last_past_one); 521357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 5214249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // shave off leading entries which lack overlay values 5215249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.removeItemsAt(0, first); 5216249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // store offset to first overlaid resource ID of this type 5217249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.insertAt((uint32_t)first, 0, 1); 521857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // reserve space for number and offset of entries, and the actual entries 521957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize += (2 + vector.size()) * sizeof(uint32_t); 522057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 522157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // no entries of current type defined in overlay package 522257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad vector.clear(); 522357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // reserve space for type offset 522457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize += 1 * sizeof(uint32_t); 522557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 522657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 522757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 522857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if ((*outData = malloc(*outSize)) == NULL) { 522957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 523057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 523157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* data = (uint32_t*)*outData; 523257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(IDMAP_MAGIC); 523357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(originalCrc); 523457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(overlayCrc); 523557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t mapSize = map.size(); 523657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(mapSize); 523757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t offset = mapSize; 523857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t i = 0; i < mapSize; ++i) { 523957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Vector<uint32_t>& vector = map.itemAt(i); 524057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t N = vector.size(); 524157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (N == 0) { 524257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(0); 524357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 524457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad offset++; 524557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(offset); 524657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad offset += N; 524757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 524857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 524957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t i = 0; i < mapSize; ++i) { 525057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Vector<uint32_t>& vector = map.itemAt(i); 525157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t N = vector.size(); 525257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (N == 0) { 525357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 525457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 5255249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (N == 1) { // vector expected to hold (offset) + (N > 0 entries) 5256249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i); 5257249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad return UNKNOWN_ERROR; 5258249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad } 525957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(N - 1); // do not count the offset (which is vector's first element) 526057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t j = 0; j < N; ++j) { 526157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t& overlayResID = vector.itemAt(j); 526257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(overlayResID); 526357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 526457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 526557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 526657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 526757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 526857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 526957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadbool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes, 527057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* pOriginalCrc, uint32_t* pOverlayCrc) 527157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 527257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t* map = (const uint32_t*)idmap; 527357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, sizeBytes)) { 527457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 527557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 527657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *pOriginalCrc = map[1]; 527757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *pOverlayCrc = map[2]; 527857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return true; 527957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 528057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 528157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 52829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_ANDROID_OS 52839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string()) 52849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define CHAR16_ARRAY_EQ(constant, var, len) \ 52869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len)))) 52879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5288e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackbornvoid print_complex(uint32_t complex, bool isFraction) 5289e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn{ 5290e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const float MANTISSA_MULT = 5291e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT); 5292e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const float RADIX_MULTS[] = { 5293e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT, 5294e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT 5295e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn }; 5296e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5297e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK 5298e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn <<Res_value::COMPLEX_MANTISSA_SHIFT)) 5299e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT) 5300e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn & Res_value::COMPLEX_RADIX_MASK]; 5301e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("%f", value); 5302e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5303de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (!isFraction) { 5304e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) { 5305e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_PX: printf("px"); break; 5306e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break; 5307e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_SP: printf("sp"); break; 5308e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_PT: printf("pt"); break; 5309e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_IN: printf("in"); break; 5310e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_MM: printf("mm"); break; 5311e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn default: printf(" (unknown unit)"); break; 5312e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5313e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } else { 5314e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) { 5315e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break; 5316e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break; 5317e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn default: printf(" (unknown unit)"); break; 5318e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5319e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5320e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn} 5321e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 53229872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh// Normalize a string for output 53239872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar ShemeshString8 ResTable::normalizeForOutput( const char *input ) 53249872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh{ 53259872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh String8 ret; 53269872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh char buff[2]; 53279872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh buff[1] = '\0'; 53289872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 53299872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh while (*input != '\0') { 53309872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh switch (*input) { 53319872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh // All interesting characters are in the ASCII zone, so we are making our own lives 53329872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh // easier by scanning the string one byte at a time. 53339872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '\\': 53349872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\\\"; 53359872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 53369872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '\n': 53379872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\n"; 53389872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 53399872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '"': 53409872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\\""; 53419872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 53429872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh default: 53439872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh buff[0] = *input; 53449872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += buff; 53459872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 53469872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh } 53479872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 53489872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh input++; 53499872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh } 53509872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 53519872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh return ret; 53529872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh} 53539872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 5354de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornvoid ResTable::print_value(const Package* pkg, const Res_value& value) const 5355de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn{ 5356de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (value.dataType == Res_value::TYPE_NULL) { 5357de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(null)\n"); 5358de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_REFERENCE) { 5359de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(reference) 0x%08x\n", value.data); 5360de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) { 5361de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(attribute) 0x%08x\n", value.data); 5362de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_STRING) { 5363de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn size_t len; 5364780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const char* str8 = pkg->header->values.string8At( 5365de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.data, &len); 5366780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (str8 != NULL) { 53679872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh printf("(string8) \"%s\"\n", normalizeForOutput(str8).string()); 5368de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else { 5369780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const char16_t* str16 = pkg->header->values.stringAt( 5370780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root value.data, &len); 5371780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (str16 != NULL) { 5372780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root printf("(string16) \"%s\"\n", 53739872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh normalizeForOutput(String8(str16, len).string()).string()); 5374780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } else { 5375780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root printf("(string) null\n"); 5376780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 5377de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5378de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_FLOAT) { 5379de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(float) %g\n", *(const float*)&value.data); 5380de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_DIMENSION) { 5381de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(dimension) "); 5382de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_complex(value.data, false); 5383de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("\n"); 5384de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_FRACTION) { 5385de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(fraction) "); 5386de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_complex(value.data, true); 5387de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("\n"); 5388de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT 5389de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) { 5390de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(color) #%08x\n", value.data); 5391de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) { 5392de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(boolean) %s\n", value.data ? "true" : "false"); 5393de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType >= Res_value::TYPE_FIRST_INT 5394de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn || value.dataType <= Res_value::TYPE_LAST_INT) { 5395de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(int) 0x%08x or %d\n", value.data, value.data); 5396de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else { 5397de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n", 5398de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.dataType, (int)value.data, 5399de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.size, (int)value.res0); 5400de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5401de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn} 5402de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 5403e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackbornvoid ResTable::print(bool inclValues) const 54049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5405e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn if (mError != 0) { 5406e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("mError=0x%x (%s)\n", mError, strerror(mError)); 5407e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 54089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 54099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("mParams=%c%c-%c%c,\n", 54109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams.language[0], mParams.language[1], 54119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams.country[0], mParams.country[1]); 54129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 54139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t pgCount = mPackageGroups.size(); 54149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Package Groups (%d)\n", (int)pgCount); 54159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) { 54169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* pg = mPackageGroups[pgIndex]; 54179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Package Group %d id=%d packageCount=%d name=%s\n", 54189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)pgIndex, pg->id, (int)pg->packages.size(), 54199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(pg->name).string()); 54209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t pkgCount = pg->packages.size(); 54229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) { 54239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* pkg = pg->packages[pkgIndex]; 54249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t typeCount = pkg->types.size(); 54259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex, 54269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pkg->package->id, String8(String16(pkg->package->name)).string(), 54279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)typeCount); 54289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) { 54299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeConfigs = pkg->getType(typeIndex); 54309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs == NULL) { 54319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" type %d NULL\n", (int)typeIndex); 54329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 54339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NTC = typeConfigs->configs.size(); 54359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" type %d configCount=%d entryCount=%d\n", 54369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount); 54379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs->typeSpecFlags != NULL) { 54389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) { 54399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) 54409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x00ff0000 & ((typeIndex+1)<<16)) 54419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x0000ffff & (entryIndex)); 54429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name resName; 54433379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root if (this->getResourceName(resID, &resName)) { 54443379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" spec resource 0x%08x %s:%s/%s: flags=0x%08x\n", 54453379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root resID, 54463379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.package, resName.packageLen), 54473379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.type, resName.typeLen), 54483379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.name, resName.nameLen), 54493379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root dtohl(typeConfigs->typeSpecFlags[entryIndex])); 54503379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } else { 54513379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID); 54523379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 54539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t configIndex=0; configIndex<NTC; configIndex++) { 54569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = typeConfigs->configs[configIndex]; 54579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((((uint64_t)type)&0x3) != 0) { 54589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); 54599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 54609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn String8 configStr = type->config.toString(); 54626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printf(" config %s:\n", configStr.size() > 0 54636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ? configStr.string() : "(default)"); 54649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t entryCount = dtohl(type->entryCount); 54659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t entriesStart = dtohl(type->entriesStart); 54669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((entriesStart&0x3) != 0) { 54679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart); 54689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 54699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t typeSize = dtohl(type->header.size); 54719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((typeSize&0x3) != 0) { 54729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize); 54739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 54749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) { 54769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)type) 54789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohl(type->header.size); 54799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 54809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + dtohs(type->header.headerSize)); 54819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t thisOffset = dtohl(eindex[entryIndex]); 54839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisOffset == ResTable_type::NO_ENTRY) { 54849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 54859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 54869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) 54889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x00ff0000 & ((typeIndex+1)<<16)) 54899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x0000ffff & (entryIndex)); 54909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name resName; 54913379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root if (this->getResourceName(resID, &resName)) { 54923379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" resource 0x%08x %s:%s/%s: ", resID, 54933379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.package, resName.packageLen), 54943379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.type, resName.typeLen), 54953379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.name, resName.nameLen)); 54963379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } else { 54973379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" INVALID RESOURCE 0x%08x: ", resID); 54983379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 54999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((thisOffset&0x3) != 0) { 55009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset); 55019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 55029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((thisOffset+sizeof(ResTable_entry)) > typeSize) { 55049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n", 55059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)entriesStart, (void*)thisOffset, 55069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize); 55079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 55089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* ent = (const ResTable_entry*) 55119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + entriesStart + thisOffset); 55129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((entriesStart + thisOffset)&0x3) != 0) { 55139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("NON-INTEGER ResTable_entry OFFSET: %p\n", 55149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(entriesStart + thisOffset)); 55159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 55169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5517e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5518de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn uint16_t esize = dtohs(ent->size); 5519de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if ((esize&0x3) != 0) { 5520de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize); 5521de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn continue; 5522de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5523de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if ((thisOffset+esize) > typeSize) { 5524de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n", 5525de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (void*)entriesStart, (void*)thisOffset, 5526de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (void*)esize, (void*)typeSize); 5527de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn continue; 5528de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5529de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 5530de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const Res_value* valuePtr = NULL; 5531de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const ResTable_map_entry* bagPtr = NULL; 5532de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn Res_value value; 55339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) { 55349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("<bag>"); 5535de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn bagPtr = (const ResTable_map_entry*)ent; 55369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5537de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn valuePtr = (const Res_value*) 55389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ent) + esize); 5539de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.copyFrom_dtoh(*valuePtr); 55409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)", 5541de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.dataType, (int)value.data, 5542de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.size, (int)value.res0); 55439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) { 55469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" (PUBLIC)"); 55479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 5549e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5550e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn if (inclValues) { 5551de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (valuePtr != NULL) { 5552e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf(" "); 5553de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_value(pkg, value); 5554de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (bagPtr != NULL) { 5555de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const int N = dtohl(bagPtr->count); 555606983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root const uint8_t* baseMapPtr = (const uint8_t*)ent; 555706983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root size_t mapOffset = esize; 555806983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset); 5559de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf(" Parent=0x%08x, Count=%d\n", 5560de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn dtohl(bagPtr->parent.ident), N); 556106983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) { 5562de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf(" #%i (Key=0x%08x): ", 5563de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn i, dtohl(mapPtr->name.ident)); 5564de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.copyFrom_dtoh(mapPtr->value); 5565de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_value(pkg, value); 5566de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const size_t size = dtohs(mapPtr->value.size); 556706983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value); 556806983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root mapPtr = (ResTable_map*)(baseMapPtr+mapOffset); 5569e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5570e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5571e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 55729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 55789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif // HAVE_ANDROID_OS 55809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 5582