ResourceTypes.cpp revision d45c68dd24fe3dd510af5a9591b5e2f509b56772
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 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <memory.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef INT32_MAX 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INT32_MAX ((int32_t)(2147483647)) 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn#define STRING_POOL_NOISY(x) //x 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define XML_NOISY(x) //x 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_NOISY(x) //x 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_GETENTRY(x) //x 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TABLE_SUPER_NOISY(x) //x 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOAD_TABLE_NOISY(x) //x 44b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn#define TABLE_THEME(x) //x 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_WINSOCK 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef nhtol 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef htonl 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_LITTLE_ENDIAN 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) ) 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htonl(x) ntohl(x) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) ) 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htons(x) ntohs(x) 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohl(x) (x) 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htonl(x) (x) 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ntohs(x) (x) 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define htons(x) (x) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#define IDMAP_MAGIC 0x706d6469 6657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad// size measured in sizeof(uint32_t) 6757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t)) 6857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void printToLogFunc(void* cookie, const char* txt) 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("%s", txt); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Standard C isspace() is only required to look at the low byte of its input, so 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// produces incorrect results for UTF-16 characters. For safety's sake, assume that 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// any high-byte UTF-16 code point is not whitespace. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline int isspace16(char16_t c) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (c < 0x0080 && isspace(c)); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// range checked; guaranteed to NUL-terminate within the stated number of available slots 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// NOTE: if this truncates the dst string due to running out of space, no attempt is 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// made to avoid splitting surrogate pairs. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail) 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint16_t* last = dst + avail - 1; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*src && (dst < last)) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t s = dtohs(*src); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *dst++ = s; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src++; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *dst = 0; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t validate_chunk(const ResChunk_header* chunk, 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t minSize, 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* dataEnd, 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* name) 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(chunk->headerSize); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(chunk->size); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize >= minSize) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize <= size) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((headerSize|size)&0x3) == 0) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1098564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s data size %p extends beyond resource end %p.", 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)size, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dataEnd-((const uint8_t*)chunk))); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1148564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.", 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (int)size, (int)headerSize); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s size %p is smaller than header size %p.", 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)size, (void*)(int)headerSize); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1228564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("%s header size %p is too small.", 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, (void*)(int)headerSize); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline void Res_value::copyFrom_dtoh(const Res_value& src) 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = dtohs(src.size); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res0 = src.res0; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dataType = src.dataType; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = dtohl(src.data); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::deviceToFile() 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numXDivs; i++) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xDivs[i] = htonl(xDivs[i]); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numYDivs; i++) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yDivs[i] = htonl(yDivs[i]); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingLeft = htonl(paddingLeft); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingRight = htonl(paddingRight); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingTop = htonl(paddingTop); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingBottom = htonl(paddingBottom); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numColors; i++) { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = htonl(colors[i]); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::fileToDevice() 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numXDivs; i++) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xDivs[i] = ntohl(xDivs[i]); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numYDivs; i++) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yDivs[i] = ntohl(yDivs[i]); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingLeft = ntohl(paddingLeft); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingRight = ntohl(paddingRight); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingTop = ntohl(paddingTop); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paddingBottom = ntohl(paddingBottom); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numColors; i++) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = ntohl(colors[i]); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t Res_png_9patch::serializedSize() 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The size of this struct is 32 bytes on the 32-bit target system 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 4 * int8_t 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 4 * int32_t 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 3 * pointer 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 32 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numXDivs * sizeof(int32_t) 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numYDivs * sizeof(int32_t) 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + numColors * sizeof(uint32_t); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* Res_png_9patch::serialize() 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // Use calloc since we're going to leave a few holes in the data 1844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // and want this to run cleanly under valgrind 1854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project void* newData = calloc(1, serializedSize()); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project serialize(newData); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newData; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Res_png_9patch::serialize(void * outData) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* data = (char*) outData; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, &wasDeserialized, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data + 12, &paddingLeft, 16); // copy paddingXXXX 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += 32; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->xDivs, numXDivs * sizeof(int32_t)); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += numXDivs * sizeof(int32_t); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->yDivs, numYDivs * sizeof(int32_t)); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += numYDivs * sizeof(int32_t); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(data, this->colors, numColors * sizeof(uint32_t)); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void deserializeInternal(const void* inData, Res_png_9patch* outData) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* patch = (char*) inData; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inData != outData) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->wasDeserialized = true; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* data = (char*)outData; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += sizeof(Res_png_9patch); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->xDivs = (int32_t*) data; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += outData->numXDivs * sizeof(int32_t); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->yDivs = (int32_t*) data; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data += outData->numYDivs * sizeof(int32_t); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outData->colors = (uint32_t*) data; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes) 22157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 22257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) { 2236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes); 22457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 22557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 22657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess 2278564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("idmap assertion failed: invalid magic found (is 0x%08x, expected 0x%08x)\n", 22857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *map, htodl(IDMAP_MAGIC)); 22957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 23057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 23157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return true; 23257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 23357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 23457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key, uint32_t* outValue) 23557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 23657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // see README for details on the format of map 23757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, sizeBytes)) { 23857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 23957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 24057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad map = map + IDMAP_HEADER_SIZE; // skip ahead to data segment 24157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // size of data block, in uint32_t 24257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t size = (sizeBytes - ResTable::IDMAP_HEADER_SIZE_BYTES) / sizeof(uint32_t); 24357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t type = Res_GETTYPE(key) + 1; // add one, idmap stores "public" type id 24457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entry = Res_GETENTRY(key); 24557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t typeCount = *map; 24657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 24757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (type > typeCount) { 2488564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Resource ID map: type=%d exceeds number of types=%d\n", type, typeCount); 24957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 25057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 25157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeCount > size) { 2526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size); 25357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 25457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 25557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t typeOffset = map[type]; 25657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeOffset == 0) { 25757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 25857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 25957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 26057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (typeOffset + 1 > size) { 2618564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n", 2626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn typeOffset, (int)size); 26357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 26457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 26557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entryCount = map[typeOffset]; 26657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t entryOffset = map[typeOffset + 1]; 26757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (entryCount == 0 || entry < entryOffset || entry - entryOffset > entryCount - 1) { 26857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 26957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 27057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 27157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t index = typeOffset + 2 + entry - entryOffset; 27257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (index > size) { 2736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size); 27457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = 0; 27557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 27657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 27757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outValue = map[index]; 27857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 27957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 28057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 28157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 28257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatic status_t getIdmapPackageId(const uint32_t* map, size_t mapSize, uint32_t *outId) 28357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 28457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, mapSize)) { 28557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 28657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 28757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t* p = map + IDMAP_HEADER_SIZE + 1; 28857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad while (*p == 0) { 28957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ++p; 29057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 29157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff; 29257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 29357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 29457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRes_png_9patch* Res_png_9patch::deserialize(const void* inData) 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sizeof(void*) != sizeof(int32_t)) { 2983762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Cannot deserialize on non 32-bit system\n"); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deserializeInternal(inData, (Res_png_9patch*) inData); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (Res_png_9patch*) inData; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 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 ProjectResStringPool::ResStringPool() 31019138468caf7050d482dc15f35a344eab11bb756Kenny Root : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL) 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResStringPool::ResStringPool(const void* data, size_t size, bool copyData) 31519138468caf7050d482dc15f35a344eab11bb756Kenny Root : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL) 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTo(data, size, copyData); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResStringPool::~ResStringPool() 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResStringPool::setTo(const void* data, size_t size, bool copyData) 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!data || !size) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool notDeviceEndian = htods(0xf0) != 0xf0; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData || notDeviceEndian) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = malloc(size); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData == NULL) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mOwnedData, data, size); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = mOwnedData; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader = (const ResStringPool_header*)data; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.headerSize = dtohs(mHeader->header.headerSize); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.type = dtohs(mHeader->header.type); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->header.size = dtohl(mHeader->header.size); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stringCount = dtohl(mHeader->stringCount); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->styleCount = dtohl(mHeader->styleCount); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->flags = dtohl(mHeader->flags); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stringsStart = dtohl(mHeader->stringsStart); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->stylesStart = dtohl(mHeader->stylesStart); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->header.headerSize > mHeader->header.size 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mHeader->header.size > size) { 3608564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: header size %d or total size %d is larger than data size %d\n", 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = mHeader->header.size; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntries = (const uint32_t*) 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->header.headerSize); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stringCount > 0) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount) // uint32 overflow? 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))) 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > size) { 3728564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: entry of %d items extends past data size %d\n", 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))), 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)size); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37719138468caf7050d482dc15f35a344eab11bb756Kenny Root 37819138468caf7050d482dc15f35a344eab11bb756Kenny Root size_t charSize; 37919138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mHeader->flags&ResStringPool_header::UTF8_FLAG) { 38019138468caf7050d482dc15f35a344eab11bb756Kenny Root charSize = sizeof(uint8_t); 38119138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 38219138468caf7050d482dc15f35a344eab11bb756Kenny Root charSize = sizeof(char16_t); 38319138468caf7050d482dc15f35a344eab11bb756Kenny Root } 38419138468caf7050d482dc15f35a344eab11bb756Kenny Root 38519138468caf7050d482dc15f35a344eab11bb756Kenny Root mStrings = (const void*) 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->stringsStart); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) { 3888564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string pool starts at %d, after total size %d\n", 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stringsStart, (int)mHeader->header.size); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->styleCount == 0) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 39419138468caf7050d482dc15f35a344eab11bb756Kenny Root (mHeader->header.size-mHeader->stringsStart)/charSize; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3965e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root // check invariant: styles starts before end of data 3975e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) { 3988564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad style block: style block starts at %d past data size of %d\n", 3995e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root (int)mHeader->stylesStart, (int)mHeader->header.size); 4005e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root return (mError=BAD_TYPE); 4015e4d9a04fdf9bf28650853cb19a1b06b0d543c51Kenny Root } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check invariant: styles follow the strings 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stylesStart <= mHeader->stringsStart) { 4048564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad style block: style block starts at %d, before strings at %d\n", 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stylesStart, (int)mHeader->stringsStart); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 40919138468caf7050d482dc15f35a344eab11bb756Kenny Root (mHeader->stylesStart-mHeader->stringsStart)/charSize; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check invariant: stringCount > 0 requires a string pool to exist 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStringPoolSize == 0) { 4148564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* e = const_cast<uint32_t*>(mEntries); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mHeader->stringCount; i++) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e[i] = dtohl(mEntries[i]); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42419138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) { 42519138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* strings = (const char16_t*)mStrings; 42619138468caf7050d482dc15f35a344eab11bb756Kenny Root char16_t* s = const_cast<char16_t*>(strings); 42719138468caf7050d482dc15f35a344eab11bb756Kenny Root for (i=0; i<mStringPoolSize; i++) { 42819138468caf7050d482dc15f35a344eab11bb756Kenny Root s[i] = dtohs(strings[i]); 42919138468caf7050d482dc15f35a344eab11bb756Kenny Root } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43319138468caf7050d482dc15f35a344eab11bb756Kenny Root if ((mHeader->flags&ResStringPool_header::UTF8_FLAG && 43419138468caf7050d482dc15f35a344eab11bb756Kenny Root ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) || 43519138468caf7050d482dc15f35a344eab11bb756Kenny Root (!mHeader->flags&ResStringPool_header::UTF8_FLAG && 43619138468caf7050d482dc15f35a344eab11bb756Kenny Root ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) { 4378564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: last string is not 0-terminated\n"); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings = NULL; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStringPoolSize = 0; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->styleCount > 0) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntryStyles = mEntries + mHeader->stringCount; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // invariant: integer overflow in calculating mEntryStyles 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEntryStyles < mEntries) { 4498564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: integer overflow finding styles\n"); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) { 4548564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: entry of %d styles extends past data size %d\n", 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader), 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)size); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStyles = (const uint32_t*) 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)data)+mHeader->stylesStart); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeader->stylesStart >= mHeader->header.size) { 4628564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: style pool starts %d, after total size %d\n", 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)mHeader->stylesStart, (int)mHeader->header.size); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStylePoolSize = 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (notDeviceEndian) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* e = const_cast<uint32_t*>(mEntryStyles); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mHeader->styleCount; i++) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e[i] = dtohl(mEntryStyles[i]); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* s = const_cast<uint32_t*>(mStyles); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<mStylePoolSize; i++) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s[i] = dtohl(mStyles[i]); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResStringPool_span endSpan = { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { htodl(ResStringPool_span::END) }, 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project htodl(ResStringPool_span::END), htodl(ResStringPool_span::END) 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))], 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &endSpan, sizeof(endSpan)) != 0) { 4878564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n"); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEntryStyles = NULL; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStyles = NULL; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStylePoolSize = 0; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_ERROR); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResStringPool::getError() const 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResStringPool::uninit() 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 50719138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mHeader != NULL && mCache != NULL) { 50819138468caf7050d482dc15f35a344eab11bb756Kenny Root for (size_t x = 0; x < mHeader->stringCount; x++) { 50919138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mCache[x] != NULL) { 51019138468caf7050d482dc15f35a344eab11bb756Kenny Root free(mCache[x]); 51119138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache[x] = NULL; 51219138468caf7050d482dc15f35a344eab11bb756Kenny Root } 51319138468caf7050d482dc15f35a344eab11bb756Kenny Root } 51419138468caf7050d482dc15f35a344eab11bb756Kenny Root free(mCache); 51519138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache = NULL; 51619138468caf7050d482dc15f35a344eab11bb756Kenny Root } 517a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman if (mOwnedData) { 518a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman free(mOwnedData); 519a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman mOwnedData = NULL; 520a1d82ff39315c962fbd6839f7a581ffaafe675e4Chris Dearman } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 523300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root/** 524300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * Strings in UTF-16 format have length indicated by a length encoded in the 525300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * stored data. It is either 1 or 2 characters of length data. This allows a 526300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that 527300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * much data in a string, you're abusing them. 528300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * 529300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * If the high bit is set, then there are two characters or 4 bytes of length 530300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * data encoded. In that case, drop the high bit of the first character and 531300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * add it together with the next character. 532300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root */ 533300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic inline size_t 534300ba6846949f5b21c6d93d7698dbc39716cf832Kenny RootdecodeLength(const char16_t** str) 535300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root{ 536300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t len = **str; 537300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((len & 0x8000) != 0) { 538300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 539300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root len = ((len & 0x7FFF) << 16) | **str; 540300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 541300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 542300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return len; 543300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root} 544300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 545300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root/** 546300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * Strings in UTF-8 format have length indicated by a length encoded in the 547300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * stored data. It is either 1 or 2 characters of length data. This allows a 548300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * maximum length of 0x7FFF (32767 bytes), but you should consider storing 549300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * text in another way if you're using that much data in a single string. 550300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * 551300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * If the high bit is set, then there are two characters or 2 bytes of length 552300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * data encoded. In that case, drop the high bit of the first character and 553300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root * add it together with the next character. 554300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root */ 555300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic inline size_t 556300ba6846949f5b21c6d93d7698dbc39716cf832Kenny RootdecodeLength(const uint8_t** str) 557300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root{ 558300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t len = **str; 559300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((len & 0x80) != 0) { 560300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 561300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root len = ((len & 0x7F) << 8) | **str; 562300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 563300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (*str)++; 564300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return len; 565300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root} 566300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 567300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootconst uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError == NO_ERROR && idx < mHeader->stringCount) { 57019138468caf7050d482dc15f35a344eab11bb756Kenny Root const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0; 57119138468caf7050d482dc15f35a344eab11bb756Kenny Root const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t)); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < (mStringPoolSize-1)) { 57319138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!isUTF8) { 57419138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* strings = (char16_t*)mStrings; 57519138468caf7050d482dc15f35a344eab11bb756Kenny Root const char16_t* str = strings+off; 576300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 577300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root *u16len = decodeLength(&str); 578300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) { 57919138468caf7050d482dc15f35a344eab11bb756Kenny Root return str; 58019138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 5818564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d extends to %d, past end at %d\n", 582300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize); 58319138468caf7050d482dc15f35a344eab11bb756Kenny Root } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 58519138468caf7050d482dc15f35a344eab11bb756Kenny Root const uint8_t* strings = (uint8_t*)mStrings; 586300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root const uint8_t* u8str = strings+off; 587300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 588300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root *u16len = decodeLength(&u8str); 589300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root size_t u8len = decodeLength(&u8str); 590300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 591300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root // encLen must be less than 0x7FFF due to encoding. 592300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) { 59319138468caf7050d482dc15f35a344eab11bb756Kenny Root AutoMutex lock(mDecodeLock); 594300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 595d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (mCache == NULL) { 596d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn#ifndef HAVE_ANDROID_OS 597d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("CREATING STRING CACHE OF %d bytes", 598d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn mHeader->stringCount*sizeof(char16_t**))); 599d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn#else 600d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // We do not want to be in this case when actually running Android. 601d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ALOGW("CREATING STRING CACHE OF %d bytes", 602d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn mHeader->stringCount*sizeof(char16_t**)); 603d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn#endif 604d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**)); 605d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (mCache == NULL) { 606d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ALOGW("No memory trying to allocate decode cache table of %d bytes\n", 607d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn (int)(mHeader->stringCount*sizeof(char16_t**))); 608d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return NULL; 609d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 610d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 611d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 61219138468caf7050d482dc15f35a344eab11bb756Kenny Root if (mCache[idx] != NULL) { 61319138468caf7050d482dc15f35a344eab11bb756Kenny Root return mCache[idx]; 61419138468caf7050d482dc15f35a344eab11bb756Kenny Root } 615300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 616300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root ssize_t actualLen = utf8_to_utf16_length(u8str, u8len); 617300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root if (actualLen < 0 || (size_t)actualLen != *u16len) { 6188564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%lld decoded length is not correct " 619300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root "%lld vs %llu\n", 620300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)idx, (long long)actualLen, (long long)*u16len); 621300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root return NULL; 622300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root } 623300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 624300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t)); 62519138468caf7050d482dc15f35a344eab11bb756Kenny Root if (!u16str) { 6268564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No memory when trying to allocate decode cache for string #%d\n", 62719138468caf7050d482dc15f35a344eab11bb756Kenny Root (int)idx); 62819138468caf7050d482dc15f35a344eab11bb756Kenny Root return NULL; 62919138468caf7050d482dc15f35a344eab11bb756Kenny Root } 630300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root 631d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("Caching UTF8 string: %s", u8str)); 632300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root utf8_to_utf16(u8str, u8len, u16str); 63319138468caf7050d482dc15f35a344eab11bb756Kenny Root mCache[idx] = u16str; 63419138468caf7050d482dc15f35a344eab11bb756Kenny Root return u16str; 63519138468caf7050d482dc15f35a344eab11bb756Kenny Root } else { 6368564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n", 637300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)idx, (long long)(u8str+u8len-strings), 638300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root (long long)mStringPoolSize); 63919138468caf7050d482dc15f35a344eab11bb756Kenny Root } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6428564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n", 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)(off*sizeof(uint16_t)), 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mStringPoolSize*sizeof(uint16_t))); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 650780d2a1b714724d85227141c76b3c64f543f00b4Kenny Rootconst char* ResStringPool::string8At(size_t idx, size_t* outLen) const 651780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root{ 652780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (mError == NO_ERROR && idx < mHeader->stringCount) { 653d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) { 654d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return NULL; 655d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 656d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const uint32_t off = mEntries[idx]/sizeof(char); 657780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (off < (mStringPoolSize-1)) { 658d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const uint8_t* strings = (uint8_t*)mStrings; 659d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const uint8_t* str = strings+off; 660d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn *outLen = decodeLength(&str); 661d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn size_t encLen = decodeLength(&str); 662d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if ((uint32_t)(str+encLen-strings) < mStringPoolSize) { 663d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return (const char*)str; 664d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 665d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ALOGW("Bad string block: string #%d extends to %d, past end at %d\n", 666d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize); 667780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 668780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } else { 6698564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n", 670780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root (int)idx, (int)(off*sizeof(uint16_t)), 671780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root (int)(mStringPoolSize*sizeof(uint16_t))); 672780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 673780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 674780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root return NULL; 675780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root} 676780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root 6776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornconst String8 ResStringPool::string8ObjectAt(size_t idx) const 6786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 6796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size_t len; 6806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const char *str = (const char*)string8At(idx, &len); 6816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (str != NULL) { 6826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return String8(str); 6836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 6846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return String8(stringAt(idx, &len)); 6856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 6866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return styleAt(ref.index); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool_span* ResStringPool::styleAt(size_t idx) const 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError == NO_ERROR && idx < mHeader->styleCount) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t)); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < mStylePoolSize) { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (const ResStringPool_span*)(mStyles+off); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6998564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad string block: style #%d entry is at %d, past end at %d\n", 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)(off*sizeof(uint32_t)), 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(mStylePoolSize*sizeof(uint32_t))); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 715d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) { 716d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string())); 717d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 718d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // The string pool contains UTF 8 strings; we don't want to cause 719d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // temporary UTF-16 strings to be created as we search. 720d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (mHeader->flags&ResStringPool_header::SORTED_FLAG) { 721d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // Do a binary search for the string... this is a little tricky, 722d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // because the strings are sorted with strzcmp16(). So to match 723d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // the ordering, we need to convert strings in the pool to UTF-16. 724d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // But we don't want to hit the cache, so instead we will have a 725d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // local temporary allocation for the conversions. 726d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn char16_t* convBuffer = (char16_t*)malloc(strLen+4); 727d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t l = 0; 728d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t h = mHeader->stringCount-1; 729d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 730d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t mid; 731d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn while (l <= h) { 732d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn mid = l + (h - l)/2; 733d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const uint8_t* s = (const uint8_t*)string8At(mid, &len); 734d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn int c; 735d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (s != NULL) { 736d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3); 737d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn *end = 0; 738d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn c = strzcmp16(convBuffer, end-convBuffer, str, strLen); 739d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 740d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn c = -1; 741d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 742d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n", 743d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn (const char*)s, c, (int)l, (int)mid, (int)h)); 744d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (c == 0) { 745d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("MATCH!")); 746d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn free(convBuffer); 747d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return mid; 748d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else if (c < 0) { 749d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn l = mid + 1; 750d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 751d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn h = mid - 1; 752d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 753d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 754d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn free(convBuffer); 755d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 756d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // It is unusual to get the ID from an unsorted string block... 757d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // most often this happens because we want to get IDs for style 758d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // span tags; since those always appear at the end of the string 759d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // block, start searching at the back. 760d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 str8(str, strLen); 761d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const size_t str8Len = str8.size(); 762d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn for (int i=mHeader->stringCount-1; i>=0; i--) { 763d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char* s = string8At(i, &len); 764d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n", 765d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(s).string(), 766d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn i)); 767d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) { 768d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("MATCH!")); 769d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 770d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 773d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 775d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string())); 776d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 777d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (mHeader->flags&ResStringPool_header::SORTED_FLAG) { 778d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // Do a binary search for the string... 779d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t l = 0; 780d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t h = mHeader->stringCount-1; 781d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 782d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ssize_t mid; 783d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn while (l <= h) { 784d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn mid = l + (h - l)/2; 785d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char16_t* s = stringAt(mid, &len); 786d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn int c = s ? strzcmp16(s, len, str, strLen) : -1; 787d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n", 788d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(s).string(), 789d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn c, (int)l, (int)mid, (int)h)); 790d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (c == 0) { 791d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("MATCH!")); 792d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return mid; 793d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else if (c < 0) { 794d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn l = mid + 1; 795d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 796d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn h = mid - 1; 797d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 798d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 799d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 800d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // It is unusual to get the ID from an unsorted string block... 801d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // most often this happens because we want to get IDs for style 802d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // span tags; since those always appear at the end of the string 803d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // block, start searching at the back. 804d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn for (int i=mHeader->stringCount-1; i>=0; i--) { 805d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char16_t* s = stringAt(i, &len); 806d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n", 807d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(s).string(), 808d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn i)); 809d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) { 810d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("MATCH!")); 811d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 812d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResStringPool::size() const 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError == NO_ERROR) ? mHeader->stringCount : 0; 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornsize_t ResStringPool::styleCount() const 8266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 8276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mError == NO_ERROR) ? mHeader->styleCount : 0; 8286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 8296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 8306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornsize_t ResStringPool::bytes() const 8316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 8326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mError == NO_ERROR) ? mHeader->header.size : 0; 8336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 8346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 8356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResStringPool::isSorted() const 8366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{ 8376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0; 8386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 8396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 840bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Rootbool ResStringPool::isUTF8() const 841bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root{ 842bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0; 843bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root} 844bb79f64b89bd7be7019035a0347c681e6f39fe6bKenny Root 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::ResXMLParser(const ResXMLTree& tree) 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mTree(tree), mEventCode(BAD_DOCUMENT) 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::restart() 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT; 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 859cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackbornconst ResStringPool& ResXMLParser::getStrings() const 860cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn{ 861cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn return mTree.mStrings; 862cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn} 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::getEventType() const 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::next() 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_DOCUMENT) { 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = mTree.mRootNode; 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = mTree.mRootExt; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=mTree.mRootCode); 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mEventCode >= FIRST_CHUNK_CODE) { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextNode(); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8815f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getCommentID() const 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1; 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getComment(size_t* outLen) const 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getCommentID(); 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 Agopianuint32_t ResXMLParser::getLineNumber() const 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8975f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getTextID() const 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == TEXT) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getText(size_t* outLen) const 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getTextID(); 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::getTextValue(Res_value* outValue) const 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == TEXT) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sizeof(Res_value); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9205f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getNamespacePrefixID() const 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getNamespacePrefixID(); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("prefix=%d event=%p\n", id, mEventCode); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9355f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getNamespaceUriID() const 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) { 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getNamespaceUriID(); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("uri=%d event=%p\n", id, mEventCode); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9505f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getElementNamespaceID() const 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == END_TAG) { 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index); 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getElementNamespaceID(); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9675f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getElementNameID() const 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index); 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == END_TAG) { 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getElementName(size_t* outLen) const 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getElementNameID(); 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResXMLParser::getAttributeCount() const 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount); 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9925f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->ns.index); 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -2; 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNamespaceID(idx); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode); 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id)); 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1015d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackbornconst char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const 1016d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn{ 1017d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn int32_t id = getAttributeNamespaceID(idx); 1018d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode); 1019d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id)); 1020d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL; 1021d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn} 1022d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 10235f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeNameID(size_t idx) const 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->name.index); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNameID(idx); 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id)); 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1046d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackbornconst char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const 1047d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn{ 1048d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn int32_t id = getAttributeNameID(idx); 1049d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode); 1050d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id)); 1051d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL; 1052d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn} 1053d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn 10545f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianuint32_t ResXMLParser::getAttributeNameResID(size_t idx) const 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeNameID(idx); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id >= 0 && (size_t)id < mTree.mNumResIds) { 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(mTree.mResIds[id]); 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10635f91097b26f036a45e32f4e4cae3e9e135a6042dMathias Agopianint32_t ResXMLParser::getAttributeValueStringID(size_t idx) const 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->rawValue.index); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t id = getAttributeValueStringID(idx); 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id)); 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t ResXMLParser::getAttributeDataType(size_t idx) const 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return attr->typedValue.dataType; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_value::TYPE_NULL; 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t ResXMLParser::getAttributeData(size_t idx) const 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dtohl(attr->typedValue.data); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt; 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx < dtohs(tag->attributeCount)) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*) 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)tag) 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(tag->attributeStart) 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (dtohs(tag->attributeSize)*idx)); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->copyFrom_dtoh(attr->typedValue); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sizeof(Res_value); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 nsStr(ns != NULL ? ns : ""); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 attrStr(attr); 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0, 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrStr.string(), attrStr.size()); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen, 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* attr, size_t attrLen) const 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 1143d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (attr == NULL) { 1144d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return NAME_NOT_FOUND; 1145d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = getAttributeCount(); 1147d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (mTree.mStrings.isUTF8()) { 1148d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 ns8, attr8; 1149d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (ns != NULL) { 1150d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn ns8 = String8(ns, nsLen); 1151d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1152d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn attr8 = String8(attr, attrLen); 1153d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen, 1154d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn attr8.string(), attrLen)); 1155d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn for (size_t i=0; i<N; i++) { 1156d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn size_t curNsLen = 0, curAttrLen = 0; 1157d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char* curNs = getAttributeNamespace8(i, &curNsLen); 1158d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char* curAttr = getAttributeName8(i, &curAttrLen); 1159d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen, 1160d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn curAttr, curAttrLen)); 1161d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen 1162d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn && memcmp(attr8.string(), curAttr, attrLen) == 0) { 1163d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (ns == NULL) { 1164d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (curNs == NULL) { 1165d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" FOUND!")); 1166d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 1167d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1168d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else if (curNs != NULL) { 1169d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //printf(" --> ns=%s, curNs=%s\n", 1170d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // String8(ns).string(), String8(curNs).string()); 1171d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (memcmp(ns8.string(), curNs, nsLen) == 0) { 1172d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" FOUND!")); 1173d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 1174d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1175d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1176d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1177d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1178d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 1179d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)", 1180d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(ns, nsLen).string(), nsLen, 1181d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(attr, attrLen).string(), attrLen)); 1182d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn for (size_t i=0; i<N; i++) { 1183d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn size_t curNsLen = 0, curAttrLen = 0; 1184d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char16_t* curNs = getAttributeNamespace(i, &curNsLen); 1185d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn const char16_t* curAttr = getAttributeName(i, &curAttrLen); 1186d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)", 1187d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(curNs, curNsLen).string(), curNsLen, 1188d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8(curAttr, curAttrLen).string(), curAttrLen)); 1189d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen 1190d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) { 1191d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (ns == NULL) { 1192d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (curNs == NULL) { 1193d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" FOUND!")); 1194d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 1195d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1196d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else if (curNs != NULL) { 1197d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn //printf(" --> ns=%s, curNs=%s\n", 1198d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // String8(ns).string(), String8(curNs).string()); 1199d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) { 1200d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn STRING_POOL_NOISY(ALOGI(" FOUND!")); 1201d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return i; 1202d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 1203d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfID() const 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex); 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfClass() const 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResXMLParser::indexOfStyle() const 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode == START_TAG) { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx > 0) return (idx-1); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NAME_NOT_FOUND; 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLParser::event_code_t ResXMLParser::nextNode() 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventCode < 0) { 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEventCode; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_node* next = (const ResXMLTree_node*) 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size)); 12488564c8da817a845353d213acd8636b76f567b234Steve Block //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)next) >= mTree.mDataEnd) { 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=END_DOCUMENT); 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTree.validateNode(next) != NO_ERROR) { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = NULL; 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=BAD_DOCUMENT); 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = next; 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(next->header.headerSize); 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t totalSize = dtohl(next->header.size); 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = ((const uint8_t*)next) + headerSize; 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t minExtSize = 0; 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event_code_t eventCode = (event_code_t)dtohs(next->header.type); 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch ((mEventCode=eventCode)) { 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_START_NAMESPACE_TYPE: 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_END_NAMESPACE_TYPE: 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_namespaceExt); 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_START_ELEMENT_TYPE: 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_attrExt); 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_END_ELEMENT_TYPE: 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_endElementExt); 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RES_XML_CDATA_TYPE: 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minExtSize = sizeof(ResXMLTree_cdataExt); 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 12818564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unknown XML block: header type %d in node at %d\n", 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(next->header.type), 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader))); 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((totalSize-headerSize) < minExtSize) { 12888564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n", 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(next->header.type), 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)), 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(totalSize-headerSize), (int)minExtSize); 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mEventCode=BAD_DOCUMENT); 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n", 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mCurNode, mCurExt, headerSize, minExtSize); 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return eventCode; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (true); 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->eventCode = mEventCode; 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->curNode = mCurNode; 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos->curExt = mCurExt; 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos) 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = pos.eventCode; 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = pos.curNode; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurExt = pos.curExt; 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gCount = 0; 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::ResXMLTree() 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : ResXMLParser(*this) 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mError(NO_INIT), mOwnedData(NULL) 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13256215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1); 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData) 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : ResXMLParser(*this) 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mError(NO_INIT), mOwnedData(NULL) 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13336215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1); 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTo(data, size, copyData); 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResXMLTree::~ResXMLTree() 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13396215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1); 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventCode = START_DOCUMENT; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 134832d6aef11abd4660fc764ffa53bd88c7589f2d35Kenny Root if (!data || !size) { 134932d6aef11abd4660fc764ffa53bd88c7589f2d35Kenny Root return (mError=BAD_TYPE); 135032d6aef11abd4660fc764ffa53bd88c7589f2d35Kenny Root } 135132d6aef11abd4660fc764ffa53bd88c7589f2d35Kenny Root 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData) { 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = malloc(size); 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData == NULL) { 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mOwnedData, data, size); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = mOwnedData; 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeader = (const ResXMLTree_header*)data; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = dtohl(mHeader->header.size); 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) { 13648564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n", 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(mHeader->header.headerSize), 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(mHeader->header.size), (int)size); 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataEnd = ((const uint8_t*)mHeader) + mSize; 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings.uninit(); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode = NULL; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResIds = NULL; 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumResIds = 0; 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First look for a couple interesting chunks: the string block 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and first XML node. 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize)); 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* lastChunk = chunk; 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) && 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) { 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML"); 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = err; 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t type = dtohs(chunk->type); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = dtohl(chunk->size); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n", 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size)); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == RES_STRING_POOL_TYPE) { 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrings.setTo(chunk, size); 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type == RES_XML_RESOURCE_MAP_TYPE) { 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResIds = (const uint32_t*) 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk)+dtohs(chunk->headerSize)); 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type >= RES_XML_FIRST_CHUNK_TYPE 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && type <= RES_XML_LAST_CHUNK_TYPE) { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) { 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurNode = (const ResXMLTree_node*)lastChunk; 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nextNode() == BAD_DOCUMENT) { 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode = mCurNode; 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootExt = mCurExt; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootCode = mEventCode; 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XML_NOISY(printf("Skipping unknown chunk!\n")); 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastChunk = chunk; 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + size); 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRootNode == NULL) { 14248564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: no root element node found\n"); 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = BAD_TYPE; 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = mStrings.getError(); 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone: 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::getError() const 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResXMLTree::uninit() 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 144419138468caf7050d482dc15f35a344eab11bb756Kenny Root mStrings.uninit(); 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOwnedData) { 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(mOwnedData); 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwnedData = NULL; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restart(); 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResXMLTree::validateNode(const ResXMLTree_node* node) const 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t eventCode = dtohs(node->header.type); 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk( 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &node->header, sizeof(ResXMLTree_node), 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataEnd, "ResXMLTree_node"); 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err >= NO_ERROR) { 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Only perform additional validation on START nodes 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (eventCode != RES_XML_START_ELEMENT_TYPE) { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(node->header.headerSize); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(node->header.size); 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*) 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)node) + headerSize); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check for sensical values pulled out of the stream so far... 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size >= headerSize + sizeof(ResXMLTree_attrExt)) 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((void*)attrExt > (void*)node)) { 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize)) 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * dtohs(attrExt->attributeCount); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) { 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14788564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n", 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)(dtohs(attrExt->attributeStart)+attrSize), 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)(size-headerSize)); 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 14838564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML start block: node header size 0x%x, size 0x%x\n", 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (unsigned int)headerSize, (unsigned int)size); 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE; 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t headerSize = dtohs(node->header.headerSize); 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t size = dtohl(node->header.size); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) { 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size >= headerSize) { 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((const uint8_t*)node) <= (mDataEnd-size)) { 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isStart) { 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount)) 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <= (size-headerSize)) { 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15078564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n", 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount), 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(size-headerSize)); 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15128564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n", 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize); 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15168564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n", 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)headerSize, (int)size); 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15218564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad XML block: node at 0x%x header size 0x%x too small\n", 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)headerSize); 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// -------------------------------------------------------------------- 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) { 15336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const size_t size = dtohl(o.size); 15346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (size >= sizeof(ResTable_config)) { 15356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn *this = o; 15366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else { 15376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memcpy(this, &o, size); 15386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size); 15396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::copyFromDtoH(const ResTable_config& o) { 15436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn copyFromDeviceNoSwap(o); 15446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size = sizeof(ResTable_config); 15456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mcc = dtohs(mcc); 15466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mnc = dtohs(mnc); 15476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn density = dtohs(density); 15486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidth = dtohs(screenWidth); 15496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeight = dtohs(screenHeight); 15506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn sdkVersion = dtohs(sdkVersion); 15516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn minorVersion = dtohs(minorVersion); 15526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn smallestScreenWidthDp = dtohs(smallestScreenWidthDp); 15536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidthDp = dtohs(screenWidthDp); 15546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeightDp = dtohs(screenHeightDp); 15556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::swapHtoD() { 15586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn size = htodl(size); 15596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mcc = htods(mcc); 15606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn mnc = htods(mnc); 15616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn density = htods(density); 15626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidth = htods(screenWidth); 15636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeight = htods(screenHeight); 15646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn sdkVersion = htods(sdkVersion); 15656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn minorVersion = htods(minorVersion); 15666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn smallestScreenWidthDp = htods(smallestScreenWidthDp); 15676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenWidthDp = htods(screenWidthDp); 15686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn screenHeightDp = htods(screenHeightDp); 15696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::compare(const ResTable_config& o) const { 15726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int32_t diff = (int32_t)(imsi - o.imsi); 15736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(locale - o.locale); 15756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenType - o.screenType); 15776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(input - o.input); 15796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenSize - o.screenSize); 15816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(version - o.version); 15836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenLayout - o.screenLayout); 15856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(uiMode - o.uiMode); 15876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp); 15896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (diff != 0) return diff; 15906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diff = (int32_t)(screenSizeDp - o.screenSizeDp); 15916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (int)diff; 15926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 15936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 15946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::compareLogical(const ResTable_config& o) const { 15956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) { 15966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return mcc < o.mcc ? -1 : 1; 15976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 15986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) { 15996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return mnc < o.mnc ? -1 : 1; 16006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != o.language[0]) { 16026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return language[0] < o.language[0] ? -1 : 1; 16036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[1] != o.language[1]) { 16056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return language[1] < o.language[1] ? -1 : 1; 16066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != o.country[0]) { 16086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return country[0] < o.country[0] ? -1 : 1; 16096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[1] != o.country[1]) { 16116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return country[1] < o.country[1] ? -1 : 1; 16126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16135f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) { 16145f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1; 16155f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 16166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 16176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1; 16186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != o.screenWidthDp) { 16206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenWidthDp < o.screenWidthDp ? -1 : 1; 16216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != o.screenHeightDp) { 16236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenHeightDp < o.screenHeightDp ? -1 : 1; 16246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != o.screenWidth) { 16266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenWidth < o.screenWidth ? -1 : 1; 16276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != o.screenHeight) { 16296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenHeight < o.screenHeight ? -1 : 1; 16306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) { 16326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return density < o.density ? -1 : 1; 16336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) { 16356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return orientation < o.orientation ? -1 : 1; 16366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) { 16386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return touchscreen < o.touchscreen ? -1 : 1; 16396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input != o.input) { 16416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return input < o.input ? -1 : 1; 16426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout != o.screenLayout) { 16446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return screenLayout < o.screenLayout ? -1 : 1; 16456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode != o.uiMode) { 16476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return uiMode < o.uiMode ? -1 : 1; 16486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != o.version) { 16506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return version < o.version ? -1 : 1; 16516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return 0; 16536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 16546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornint ResTable_config::diff(const ResTable_config& o) const { 16566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int diffs = 0; 16576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) diffs |= CONFIG_MCC; 16586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) diffs |= CONFIG_MNC; 16596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale != o.locale) diffs |= CONFIG_LOCALE; 16606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION; 16616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) diffs |= CONFIG_DENSITY; 16626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN; 16636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0) 16646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn diffs |= CONFIG_KEYBOARD_HIDDEN; 16656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD; 16666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION; 16676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE; 16686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != o.version) diffs |= CONFIG_VERSION; 1669350993591974a8c7a2eca665f96304d296104789Fabrice Di Meglio if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR; 1670350993591974a8c7a2eca665f96304d296104789Fabrice Di Meglio if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT; 16716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; 16726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE; 16736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; 16746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return diffs; 16756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 16766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const { 16786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // The order of the following tests defines the importance of one 16796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // configuration parameter over another. Those tests first are more 16806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // important, trumping any values in those following them. 16816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi || o.imsi) { 16826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != o.mcc) { 16836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!mcc) return false; 16846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.mcc) return true; 16856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != o.mnc) { 16886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!mnc) return false; 16896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.mnc) return true; 16906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale || o.locale) { 16946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != o.language[0]) { 16956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!language[0]) return false; 16966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.language[0]) return true; 16976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 16986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 16996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != o.country[0]) { 17006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!country[0]) return false; 17016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.country[0]) return true; 17026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17055f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (screenLayout || o.screenLayout) { 17065f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) { 17075f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (!(screenLayout & MASK_LAYOUTDIR)) return false; 17085f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (!(o.screenLayout & MASK_LAYOUTDIR)) return true; 17095f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 17105f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 17115f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio 17126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp || o.smallestScreenWidthDp) { 17136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 17146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!smallestScreenWidthDp) return false; 17156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.smallestScreenWidthDp) return true; 17166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp || o.screenSizeDp) { 17206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != o.screenWidthDp) { 17216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenWidthDp) return false; 17226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenWidthDp) return true; 17236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != o.screenHeightDp) { 17266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenHeightDp) return false; 17276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenHeightDp) return true; 17286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout || o.screenLayout) { 17326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) { 17336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(screenLayout & MASK_SCREENSIZE)) return false; 17346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.screenLayout & MASK_SCREENSIZE)) return true; 17356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) { 17376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(screenLayout & MASK_SCREENLONG)) return false; 17386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.screenLayout & MASK_SCREENLONG)) return true; 17396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != o.orientation) { 17436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!orientation) return false; 17446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.orientation) return true; 17456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode || o.uiMode) { 17486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) { 17496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(uiMode & MASK_UI_MODE_TYPE)) return false; 17506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true; 17516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) { 17536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(uiMode & MASK_UI_MODE_NIGHT)) return false; 17546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true; 17556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density is never 'more specific' 17596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // as the default just equals 160 17606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != o.touchscreen) { 17626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!touchscreen) return false; 17636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.touchscreen) return true; 17646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input || o.input) { 17676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) { 17686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(inputFlags & MASK_KEYSHIDDEN)) return false; 17696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true; 17706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) { 17736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(inputFlags & MASK_NAVHIDDEN)) return false; 17746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!(o.inputFlags & MASK_NAVHIDDEN)) return true; 17756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != o.keyboard) { 17786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!keyboard) return false; 17796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.keyboard) return true; 17806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != o.navigation) { 17836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!navigation) return false; 17846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.navigation) return true; 17856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize || o.screenSize) { 17896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != o.screenWidth) { 17906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenWidth) return false; 17916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenWidth) return true; 17926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 17946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != o.screenHeight) { 17956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!screenHeight) return false; 17966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.screenHeight) return true; 17976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 17996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version || o.version) { 18016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (sdkVersion != o.sdkVersion) { 18026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!sdkVersion) return false; 18036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.sdkVersion) return true; 18046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != o.minorVersion) { 18076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!minorVersion) return false; 18086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!o.minorVersion) return true; 18096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 18126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 18136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::isBetterThan(const ResTable_config& o, 18156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const ResTable_config* requested) const { 18166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested) { 18176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi || o.imsi) { 18186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((mcc != o.mcc) && requested->mcc) { 18196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mcc); 18206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((mnc != o.mnc) && requested->mnc) { 18236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (mnc); 18246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale || o.locale) { 18286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((language[0] != o.language[0]) && requested->language[0]) { 18296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (language[0]); 18306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((country[0] != o.country[0]) && requested->country[0]) { 18336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (country[0]); 18346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18375f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (screenLayout || o.screenLayout) { 18385f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0 18395f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio && (requested->screenLayout & MASK_LAYOUTDIR)) { 18405f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio int myLayoutDir = screenLayout & MASK_LAYOUTDIR; 18415f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR; 18425f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio return (myLayoutDir > oLayoutDir); 18435f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 18445f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 18455f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio 18466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp || o.smallestScreenWidthDp) { 18476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // The configuration closest to the actual size is best. 18486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // We assume that larger configs have already been filtered 18496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // out at this point. That means we just want the largest one. 18505c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (smallestScreenWidthDp != o.smallestScreenWidthDp) { 18515c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return smallestScreenWidthDp > o.smallestScreenWidthDp; 18525c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 18536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp || o.screenSizeDp) { 18566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // "Better" is based on the sum of the difference between both 18576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // width and height from the requested dimensions. We are 18586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // assuming the invalid configs (with smaller dimens) have 18596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // already been filtered. Note that if a particular dimension 18606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is unspecified, we will end up with a large value (the 18616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // difference between 0 and the requested dimension), which is 18626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // good since we will prefer a config that has specified a 18636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // dimension value. 18646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int myDelta = 0, otherDelta = 0; 18656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenWidthDp) { 18666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenWidthDp - screenWidthDp; 18676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenWidthDp - o.screenWidthDp; 18686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenHeightDp) { 18706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenHeightDp - screenHeightDp; 18716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenHeightDp - o.screenHeightDp; 18726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d", 18746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp, 18756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta); 18765c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (myDelta != otherDelta) { 18775c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return myDelta < otherDelta; 18785c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 18796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 18816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLayout || o.screenLayout) { 18826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0 18836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->screenLayout & MASK_SCREENSIZE)) { 18846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // A little backwards compatibility here: undefined is 18856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // considered equivalent to normal. But only if the 18866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested size is at least normal; otherwise, small 18876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is better than the default. 18886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int mySL = (screenLayout & MASK_SCREENSIZE); 18896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int oSL = (o.screenLayout & MASK_SCREENSIZE); 18906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int fixedMySL = mySL; 18916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int fixedOSL = oSL; 18926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) { 18936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL; 18946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL; 18956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 18966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For screen size, the best match is the one that is 18976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // closest to the requested screen size, but not over 18986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // (the not over part is dealt with in match() below). 18996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (fixedMySL == fixedOSL) { 19006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // If the two are the same, but 'this' is actually 19016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // undefined, then the other is really a better match. 19026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mySL == 0) return false; 19036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return true; 19046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19055c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (fixedMySL != fixedOSL) { 19065c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return fixedMySL > fixedOSL; 19075c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 19086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0 19106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->screenLayout & MASK_SCREENLONG)) { 19116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (screenLayout & MASK_SCREENLONG); 19126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((orientation != o.orientation) && requested->orientation) { 19166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (orientation); 19176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiMode || o.uiMode) { 19206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0 19216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->uiMode & MASK_UI_MODE_TYPE)) { 19226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (uiMode & MASK_UI_MODE_TYPE); 19236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0 19256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (requested->uiMode & MASK_UI_MODE_NIGHT)) { 19266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (uiMode & MASK_UI_MODE_NIGHT); 19276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenType || o.screenType) { 19316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != o.density) { 19326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density is tough. Any density is potentially useful 19336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // because the system will scale it. Scaling down 19346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is generally better than scaling up. 19356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // Default density counts as 160dpi (the system default) 19366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // TODO - remove 160 constants 19376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int h = (density?density:160); 19386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int l = (o.density?o.density:160); 19396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn bool bImBigger = true; 19406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (l > h) { 19416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int t = h; 19426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn h = l; 19436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn l = t; 19446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn bImBigger = false; 19456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int reqValue = (requested->density?requested->density:160); 19486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqValue >= h) { 19496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested value higher than both l and h, give h 19506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return bImBigger; 19516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (l >= reqValue) { 19536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // requested value lower than both l and h, give l 19546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return !bImBigger; 19556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // saying that scaling down is 2x better than up 19576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (((2 * l) - reqValue) * h > reqValue * reqValue) { 19586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return !bImBigger; 19596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } else { 19606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return bImBigger; 19616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((touchscreen != o.touchscreen) && requested->touchscreen) { 19656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (touchscreen); 19666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input || o.input) { 19706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int keysHidden = inputFlags & MASK_KEYSHIDDEN; 19716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN; 19726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != oKeysHidden) { 19736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int reqKeysHidden = 19746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->inputFlags & MASK_KEYSHIDDEN; 19756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden) { 19766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!keysHidden) return false; 19786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!oKeysHidden) return true; 19796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For compatibility, we count KEYSHIDDEN_NO as being 19806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // the same as KEYSHIDDEN_SOFT. Here we disambiguate 19816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // these by making an exact match more specific. 19826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden == keysHidden) return true; 19836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqKeysHidden == oKeysHidden) return false; 19846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int navHidden = inputFlags & MASK_NAVHIDDEN; 19886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN; 19896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navHidden != oNavHidden) { 19906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int reqNavHidden = 19916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->inputFlags & MASK_NAVHIDDEN; 19926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (reqNavHidden) { 19936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!navHidden) return false; 19956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (!oNavHidden) return true; 19966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 19986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 19996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((keyboard != o.keyboard) && requested->keyboard) { 20006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (keyboard); 20016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((navigation != o.navigation) && requested->navigation) { 20046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (navigation); 20056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize || o.screenSize) { 20096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // "Better" is based on the sum of the difference between both 20106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // width and height from the requested dimensions. We are 20116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // assuming the invalid configs (with smaller sizes) have 20126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // already been filtered. Note that if a particular dimension 20136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // is unspecified, we will end up with a large value (the 20146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // difference between 0 and the requested dimension), which is 20156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // good since we will prefer a config that has specified a 20166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // size value. 20176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn int myDelta = 0, otherDelta = 0; 20186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenWidth) { 20196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenWidth - screenWidth; 20206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenWidth - o.screenWidth; 20216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (requested->screenHeight) { 20236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn myDelta += requested->screenHeight - screenHeight; 20246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn otherDelta += requested->screenHeight - o.screenHeight; 20256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20265c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn if (myDelta != otherDelta) { 20275c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn return myDelta < otherDelta; 20285c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn } 20296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version || o.version) { 20326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) { 20336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (sdkVersion > o.sdkVersion); 20346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((minorVersion != o.minorVersion) && 20376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn requested->minorVersion) { 20386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return (minorVersion); 20396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return isMoreSpecificThan(o); 20456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 20466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornbool ResTable_config::match(const ResTable_config& settings) const { 20486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (imsi != 0) { 20496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != 0 && mcc != settings.mcc) { 20506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != 0 && mnc != settings.mnc) { 20536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (locale != 0) { 20576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != 0 20586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (language[0] != settings.language[0] 20596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn || language[1] != settings.language[1])) { 20606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != 0 20636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && (country[0] != settings.country[0] 20646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn || country[1] != settings.country[1])) { 20656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenConfig != 0) { 20695f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio const int layoutDir = screenLayout&MASK_LAYOUTDIR; 20705f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR; 20715f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (layoutDir != 0 && layoutDir != setLayoutDir) { 20725f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio return false; 20735f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 20745f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio 20756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int screenSize = screenLayout&MASK_SCREENSIZE; 20766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE; 20776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // Any screen sizes for larger screens than the setting do not 20786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // match. 20796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0 && screenSize > setScreenSize) { 20806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int screenLong = screenLayout&MASK_SCREENLONG; 20846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setScreenLong = settings.screenLayout&MASK_SCREENLONG; 20856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenLong != 0 && screenLong != setScreenLong) { 20866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int uiModeType = uiMode&MASK_UI_MODE_TYPE; 20906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE; 20916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiModeType != 0 && uiModeType != setUiModeType) { 20926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 20946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 20956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT; 20966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT; 20976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (uiModeNight != 0 && uiModeNight != setUiModeNight) { 20986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 20996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 21016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != 0 21026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn && smallestScreenWidthDp > settings.smallestScreenWidthDp) { 21036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSizeDp != 0) { 21076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) { 21086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp); 21096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) { 21126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp); 21136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenType != 0) { 21176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != 0 && orientation != settings.orientation) { 21186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // density always matches - we can scale it. See isBetterThan 21216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != 0 && touchscreen != settings.touchscreen) { 21226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (input != 0) { 21266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int keysHidden = inputFlags&MASK_KEYSHIDDEN; 21276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN; 21286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != 0 && keysHidden != setKeysHidden) { 21296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // For compatibility, we count a request for KEYSHIDDEN_NO as also 21306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // matching the more recent KEYSHIDDEN_SOFT. Basically 21316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn // KEYSHIDDEN_NO means there is some kind of keyboard available. 21326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden); 21336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) { 21346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn //ALOGI("No match!"); 21356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int navHidden = inputFlags&MASK_NAVHIDDEN; 21396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN; 21406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navHidden != 0 && navHidden != setNavHidden) { 21416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != 0 && keyboard != settings.keyboard) { 21446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != 0 && navigation != settings.navigation) { 21476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0) { 21516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidth != 0 && screenWidth > settings.screenWidth) { 21526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeight != 0 && screenHeight > settings.screenHeight) { 21556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != 0) { 21596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) { 21606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != 0 && minorVersion != settings.minorVersion) { 21636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return false; 21646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return true; 21676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 21686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 21696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornvoid ResTable_config::getLocale(char str[6]) const { 21706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn memset(str, 0, 6); 21716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0]) { 21726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[0] = language[0]; 21736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[1] = language[1]; 21746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0]) { 21756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[2] = '_'; 21766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[3] = country[0]; 21776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn str[4] = country[1]; 21786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 21816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 21826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne HackbornString8 ResTable_config::toString() const { 21836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn String8 res; 21846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 21856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mcc != 0) { 21866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dmcc", dtohs(mcc)); 21886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (mnc != 0) { 21906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dmnc", dtohs(mnc)); 21926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (language[0] != 0) { 21946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append(language, 2); 21966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 21976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (country[0] != 0) { 21986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 21996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append(country, 2); 22006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22015f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if ((screenLayout&MASK_LAYOUTDIR) != 0) { 22025f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio if (res.size() > 0) res.append("-"); 22035f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) { 22045f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio case ResTable_config::LAYOUTDIR_LTR: 22058a802dbdabdfd27692c2e38b2c3adafe95566106Fabrice Di Meglio res.append("ldltr"); 22065f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio break; 22075f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio case ResTable_config::LAYOUTDIR_RTL: 22088a802dbdabdfd27692c2e38b2c3adafe95566106Fabrice Di Meglio res.append("ldrtl"); 22095f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio break; 22105f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio default: 22115f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio res.appendFormat("layoutDir=%d", 22125f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR)); 22135f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio break; 22145f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 22155f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio } 22166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (smallestScreenWidthDp != 0) { 22176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp)); 22196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenWidthDp != 0) { 22216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("w%ddp", dtohs(screenWidthDp)); 22236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenHeightDp != 0) { 22256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("h%ddp", dtohs(screenHeightDp)); 22276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) { 22296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (screenLayout&ResTable_config::MASK_SCREENSIZE) { 22316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_SMALL: 22326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("small"); 22336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_NORMAL: 22356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("normal"); 22366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_LARGE: 22386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("large"); 22396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENSIZE_XLARGE: 22416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xlarge"); 22426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("screenLayoutSize=%d", 22456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE)); 22466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((screenLayout&MASK_SCREENLONG) != 0) { 22506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (screenLayout&ResTable_config::MASK_SCREENLONG) { 22526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENLONG_NO: 22536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notlong"); 22546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::SCREENLONG_YES: 22566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("long"); 22576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("screenLayoutLong=%d", 22606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_SCREENLONG)); 22616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (orientation != ORIENTATION_ANY) { 22656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (orientation) { 22676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_PORT: 22686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("port"); 22696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_LAND: 22716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("land"); 22726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::ORIENTATION_SQUARE: 22746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("square"); 22756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("orientation=%d", dtohs(orientation)); 22786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 22816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) { 22826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 22836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) { 22846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_DESK: 22856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("desk"); 22866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_CAR: 22886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("car"); 22896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_TELEVISION: 22916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("television"); 22926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_TYPE_APPLIANCE: 22946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("appliance"); 22956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 22966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 22976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("uiModeType=%d", 22986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE)); 22996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((uiMode&MASK_UI_MODE_NIGHT) != 0) { 23036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) { 23056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_NIGHT_NO: 23066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notnight"); 23076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::UI_MODE_NIGHT_YES: 23096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("night"); 23106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 23126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("uiModeNight=%d", 23136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(uiMode&MASK_UI_MODE_NIGHT)); 23146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (density != DENSITY_DEFAULT) { 23186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (density) { 23206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_LOW: 23216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("ldpi"); 23226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_MEDIUM: 23246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("mdpi"); 23256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_TV: 23276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("tvdpi"); 23286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_HIGH: 23306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("hdpi"); 23316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_XHIGH: 23336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xhdpi"); 23346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_XXHIGH: 23366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("xxhdpi"); 23376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::DENSITY_NONE: 23396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nodpi"); 23406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 23425c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn res.appendFormat("%ddpi", dtohs(density)); 23436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (touchscreen != TOUCHSCREEN_ANY) { 23476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23486c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (touchscreen) { 23496c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_NOTOUCH: 23506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("notouch"); 23516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23526c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_FINGER: 23536c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("finger"); 23546c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23556c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::TOUCHSCREEN_STYLUS: 23566c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("stylus"); 23576c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 23596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("touchscreen=%d", dtohs(touchscreen)); 23606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (keyboard != KEYBOARD_ANY) { 23646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (keyboard) { 23666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_NOKEYS: 23676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nokeys"); 23686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_QWERTY: 23706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("qwerty"); 23716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23726c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYBOARD_12KEY: 23736c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("12key"); 23746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23756c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 23766c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("keyboard=%d", dtohs(keyboard)); 23776c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23786c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23796c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23806c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((inputFlags&MASK_KEYSHIDDEN) != 0) { 23816c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23826c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (inputFlags&MASK_KEYSHIDDEN) { 23836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_NO: 23846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keysexposed"); 23856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_YES: 23876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keyshidden"); 23886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::KEYSHIDDEN_SOFT: 23906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("keyssoft"); 23916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 23926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 23946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (navigation != NAVIGATION_ANY) { 23956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 23966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (navigation) { 23976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_NONAV: 23986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("nonav"); 23996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_DPAD: 24016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("dpad"); 24026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_TRACKBALL: 24046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("trackball"); 24056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24066c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVIGATION_WHEEL: 24076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("wheel"); 24086c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24096c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 24106c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("navigation=%d", dtohs(navigation)); 24116c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24126c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24136c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24146c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if ((inputFlags&MASK_NAVHIDDEN) != 0) { 24156c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 24166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn switch (inputFlags&MASK_NAVHIDDEN) { 24176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVHIDDEN_NO: 24186c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("navsexposed"); 24196c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24206c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn case ResTable_config::NAVHIDDEN_YES: 24216c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.append("navhidden"); 24226c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24236c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn default: 24246c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("inputFlagsNavHidden=%d", 24256c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn dtohs(inputFlags&MASK_NAVHIDDEN)); 24266c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn break; 24276c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (screenSize != 0) { 24306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 24316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight)); 24326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (version != 0) { 24346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (res.size() > 0) res.append("-"); 24356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat("v%d", dtohs(sdkVersion)); 24366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn if (minorVersion != 0) { 24376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn res.appendFormat(".%d", dtohs(minorVersion)); 24386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn } 24406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 24416c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn return res; 24426c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn} 24436c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 24446c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 24456c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 24466c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn// -------------------------------------------------------------------- 24476c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn 24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Header 24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 245057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL), 245157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resourceIDMap(NULL), resourceIDMapSize(0) { } 245257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 245357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ~Header() 245457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad { 245557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad free(resourceIDMap); 245657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 245878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* ownedData; 24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_header* header; 24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size; 24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* dataEnd; 24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t index; 24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* cookie; 24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResStringPool values; 246757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* resourceIDMap; 246857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t resourceIDMapSize; 24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Type 24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type(const Header* _header, const Package* _package, size_t count) 24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : header(_header), package(_package), entryCount(count), 24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSpec(NULL), typeSpecFlags(NULL) { } 24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Header* const header; 24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package; 24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t entryCount; 24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_typeSpec* typeSpec; 24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* typeSpecFlags; 24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<const ResTable_type*> configs; 24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::Package 24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 248678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package(ResTable* _owner, const Header* _header, const ResTable_package* _package) 248778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn : owner(_owner), header(_header), package(_package) { } 24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~Package() 24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i = types.size(); 24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i > 0) { 24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete types[i]; 24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Header* const header; 24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_package* const package; 25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<Type*> types; 25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 250278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResStringPool typeStrings; 250378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResStringPool keyStrings; 250478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* getType(size_t idx) const { 25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return idx < types.size() ? types[idx] : NULL; 25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// A group of objects describing a particular resource package. 25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// The first in 'package' is always the root object (from the resource 25129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// table that defined the package); the ones after are skins on top of it. 25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::PackageGroup 25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 251578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id) 251678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { } 25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~PackageGroup() { 25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearBagCache(); 25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = packages.size(); 25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 252178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package* pkg = packages[i]; 252278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (pkg->owner == owner) { 252378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete pkg; 252478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clearBagCache() { 25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bags) { 25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("bags=%p\n", bags)); 25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Package* pkg = packages[0]; 25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("typeCount=%x\n", typeCount)); 25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<typeCount; i++) { 25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("type=%d\n", i)); 25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = pkg->getType(i); 25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != NULL) { 25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeBags = bags[i]; 25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("typeBags=%p\n", typeBags)); 25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeBags) { 25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount)); 25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N = type->entryCount; 25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<N; j++) { 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF) 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(typeBags[j]); 25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(typeBags); 25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(bags); 25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bags = NULL; 25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 255578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn ResTable* const owner; 25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 const name; 25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t const id; 25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<Package*> packages; 255978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 256078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn // This is for finding typeStrings and other common package stuff. 256178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Package* basePackage; 25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 256378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn // For quick access. 25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t typeCount; 256578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Computed attribute bags, first indexed by the type and second 25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // by the entry in that type. 25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set*** bags; 25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 25709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ResTable::bag_set 25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t numAttrs; // number in array 25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t availAttrs; // total space in array 25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t typeSpecFlags; 25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Followed by 'numAttr' bag_entry structures. 25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::Theme(const ResTable& table) 25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mTable(table) 25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackages, 0, sizeof(mPackages)); 25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::~Theme() 25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* pi = mPackages[i]; 25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi != NULL) { 25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(pi); 25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::Theme::free_package(package_info* pi) 25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<pi->numTypes; j++) { 25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* te = pi->types[j].entries; 25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te != NULL) { 26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(te); 26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(pi); 26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi) 26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* newpi = (package_info*)malloc( 26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(package_info) + (pi->numTypes*sizeof(type_info))); 26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->numTypes = pi->numTypes; 26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<newpi->numTypes; j++) { 26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t cnt = pi->types[j].numEntries; 26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].numEntries = cnt; 26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* te = pi->types[j].entries; 26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te != NULL) { 26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry)); 26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].entries = newte; 26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(newte, te, cnt*sizeof(theme_entry)); 26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newpi->types[j].entries = NULL; 26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newpi; 26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::Theme::applyStyle(uint32_t resID, bool force) 26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t bagTypeSpecFlags = 0; 26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.lock(); 26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags); 26325c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N)); 26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N < 0) { 26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.unlock(); 26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return N; 26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t curPackage = 0xffffffff; 26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t curPackageIndex = 0; 26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* curPI = NULL; 26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t curType = 0xffffffff; 26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t numEntries = 0; 26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* curEntries = NULL; 26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* end = bag + N; 26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (bag < end) { 26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t attrRes = bag->map.name.ident; 26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t p = Res_GETPACKAGE(attrRes); 26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t t = Res_GETTYPE(attrRes); 26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t e = Res_GETENTRY(attrRes); 26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage != p) { 26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t pidx = mTable.getResourcePackageIndex(attrRes); 26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pidx < 0) { 26553762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad package: 0x%08x\n", attrRes); 26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackage = p; 26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackageIndex = pidx; 26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI = mPackages[pidx]; 26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPI == NULL) { 26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mTable.mPackageGroups[pidx]; 26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = grp->typeCount; 26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI = (package_info*)malloc( 26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(package_info) + (cnt*sizeof(type_info))); 26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->numTypes = cnt; 26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(curPI->types, 0, cnt*sizeof(type_info)); 26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[pidx] = curPI; 26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curType = 0xffffffff; 26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curType != t) { 26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t >= curPI->numTypes) { 26753762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad type: 0x%08x\n", attrRes); 26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curType = t; 26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntries = curPI->types[t].entries; 26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curEntries == NULL) { 26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex]; 26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = grp->packages[0]->getType(t); 26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = type != NULL ? type->entryCount : 0; 26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry)); 26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry)); 26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->types[t].numEntries = cnt; 26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPI->types[t].entries = curEntries; 26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numEntries = curPI->types[t].numEntries; 26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e >= numEntries) { 26933762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Style contains key with bad entry: 0x%08x\n", attrRes); 26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry* curEntry = curEntries + e; 26985c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x", 26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrRes, bag->map.value.dataType, bag->map.value.data, 27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->value.dataType)); 27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (force || curEntry->value.dataType == Res_value::TYPE_NULL) { 27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->stringBlock = bag->stringBlock; 27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->typeSpecFlags |= bagTypeSpecFlags; 27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry->value = bag->map.value; 27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTable.unlock(); 27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27126215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Applying style 0x%08x (force=%d) theme %p...\n", resID, force, this); 27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::Theme::setTo(const Theme& other) 27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 27206215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Setting theme %p from theme %p...\n", this, &other); 27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //other.dumpToLog(); 27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (&mTable == &other.mTable) { 27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPackages[i] != NULL) { 27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(mPackages[i]); 27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (other.mPackages[i] != NULL) { 27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = copy_package(other.mPackages[i]); 27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = NULL; 27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // @todo: need to really implement this, not just copy 27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the system package (which is still wrong because it isn't 27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fixing up resource references). 27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPackages[i] != NULL) { 27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_package(mPackages[i]); 27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == 0 && other.mPackages[i] != NULL) { 27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = copy_package(other.mPackages[i]); 27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackages[i] = NULL; 27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27516215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Final theme:"); 27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //dumpToLog(); 27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, 27589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 27609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cnt = 20; 27619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0; 27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = mTable.getResourcePackageIndex(resID); 27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t t = Res_GETTYPE(resID); 27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t e = Res_GETENTRY(resID); 27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27695c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this)); 27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p >= 0) { 27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const package_info* const pi = mPackages[p]; 27735c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Found package: %p", pi)); 27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi != NULL) { 27755c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes)); 27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < pi->numTypes) { 27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const type_info& ti = pi->types[t]; 27785c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries)); 27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e < ti.numEntries) { 27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const theme_entry& te = ti.entries[e]; 2781b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn if (outTypeSpecFlags != NULL) { 2782b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn *outTypeSpecFlags |= te.typeSpecFlags; 2783b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn } 27845c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x", 2785b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn te.value.dataType, te.value.data)); 27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t type = te.value.dataType; 27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Res_value::TYPE_ATTRIBUTE) { 27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt > 0) { 27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resID = te.value.data; 27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27938564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID); 27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (type != Res_value::TYPE_NULL) { 27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outValue = te.value; 27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return te.stringBlock; 27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (true); 28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue, 28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t blockIndex, uint32_t* outLastRef, 28130d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const 28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Resolving type=0x%x\n", inOutValue->dataType); 28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) { 28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t newTypeSpecFlags; 28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags); 28195c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n", 2820b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data)); 28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags; 28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType); 28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (blockIndex < 0) { 28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28270d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn return mTable.resolveReference(inOutValue, blockIndex, outLastRef, 28280d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn inoutTypeSpecFlags, inoutConfig); 28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::Theme::dumpToLog() const 28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28336215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI("Theme %p:\n", this); 28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<Res_MAXPACKAGE; i++) { 28359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package_info* pi = mPackages[i]; 28369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pi == NULL) continue; 28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28386215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" Package #0x%02x:\n", (int)(i+1)); 28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<pi->numTypes; j++) { 28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type_info& ti = pi->types[j]; 28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ti.numEntries == 0) continue; 28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28436215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" Type #0x%02x:\n", (int)(j+1)); 28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t k=0; k<ti.numEntries; k++) { 28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project theme_entry& te = ti.entries[k]; 28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (te.value.dataType == Res_value::TYPE_NULL) continue; 28476215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI(" 0x%08x: t=0x%x, d=0x%08x (block=%d)\n", 28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)Res_MAKEID(i, j, k), 28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project te.value.dataType, (int)te.value.data, (int)te.stringBlock); 28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::ResTable() 28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mError(NO_INIT) 28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&mParams, 0, sizeof(mParams)); 28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackageMap, 0, sizeof(mPackageMap)); 28606215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResTable %p\n", this); 28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData) 28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mError(NO_INIT) 28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&mParams, 0, sizeof(mParams)); 28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mPackageMap, 0, sizeof(mPackageMap)); 28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project add(data, size, cookie, copyData); 28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table"); 28706215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Creating ResTable %p\n", this); 28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResTable::~ResTable() 28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28756215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Destroying ResTable in %p\n", this); 28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uninit(); 28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const 28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1; 28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 288457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData, 288557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const void* idmap) 28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 288757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap)); 28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap) 28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* data = asset->getBuffer(true); 28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data == NULL) { 28948564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unable to get buffer of resource asset file"); 28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size = (size_t)asset->getLength(); 289857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap)); 28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 290178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackbornstatus_t ResTable::add(ResTable* src) 290278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn{ 290378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mError = src->mError; 290478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 290578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t i=0; i<src->mHeaders.size(); i++) { 290678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mHeaders.add(src->mHeaders[i]); 290778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 290878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 290978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t i=0; i<src->mPackageGroups.size(); i++) { 291078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup* srcPg = src->mPackageGroups[i]; 291178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id); 291278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn for (size_t j=0; j<srcPg->packages.size(); j++) { 291378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->packages.add(srcPg->packages[j]); 291478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 291578c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->basePackage = srcPg->basePackage; 291678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn pg->typeCount = srcPg->typeCount; 291778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn mPackageGroups.add(pg); 291878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 291978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 292078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap)); 292178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 292278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn return mError; 292378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn} 292478c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::add(const void* data, size_t size, void* cookie, 292657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Asset* asset, bool copyData, const Asset* idmap) 29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!data) return NO_ERROR; 292978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn Header* header = new Header(this); 29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->index = mHeaders.size(); 29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->cookie = cookie; 293257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (idmap != NULL) { 293357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t idmap_size = idmap->getLength(); 293457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const void* idmap_data = const_cast<Asset*>(idmap)->getBuffer(true); 293557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMap = (uint32_t*)malloc(idmap_size); 293657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (header->resourceIDMap == NULL) { 293757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad delete header; 293857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return (mError = NO_MEMORY); 293957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 294057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memcpy((void*)header->resourceIDMap, idmap_data, idmap_size); 294157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMapSize = idmap_size; 294257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 29439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeaders.add(header); 29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool notDeviceEndian = htods(0xf0) != 0xf0; 29469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY( 294871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d " 294957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad "idmap=%p\n", data, size, cookie, asset, copyData, idmap)); 29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (copyData || notDeviceEndian) { 29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->ownedData = malloc(size); 29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (header->ownedData == NULL) { 29549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(header->ownedData, data, size); 29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = header->ownedData; 29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->header = (const ResTable_header*)data; 29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->size = dtohl(header->header->header.size); 29626215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size, 29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // dtohl(header->header->header.size), header->header->header.size); 29645c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header)); 29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256, 29669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16, 16, 0, false, printToLogFunc)); 29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(header->header->header.headerSize) > header->size 29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || header->size > size) { 29698564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n", 29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(header->header->header.headerSize), 29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)header->size, (int)size); 29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) { 29758564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n", 29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohs(header->header->header.headerSize), 29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)header->size); 29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd = ((const uint8_t*)header->header) + header->size; 29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Iterate through all chunks. 29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curPackage = 0; 29849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)header->header) 29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(header->header->header.headerSize)); 29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) && 29899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) { 29909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable"); 29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 29929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 29939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29945c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n", 29959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size), 29969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)))); 29979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t csize = dtohl(chunk->size); 29989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t ctype = dtohs(chunk->type); 29999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ctype == RES_STRING_POOL_TYPE) { 30009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (header->values.getError() != NO_ERROR) { 30019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Only use the first string chunk; ignore any others that 30029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // may appear. 30039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = header->values.setTo(chunk, csize); 30049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 30059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 30069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 30088564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Multiple string chunks found in resource table."); 30099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ctype == RES_TABLE_PACKAGE_TYPE) { 30119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage >= dtohl(header->header->packageCount)) { 30128564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("More package chunks were found than the %d declared in the header.", 30139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohl(header->header->packageCount)); 30149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 30159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 301657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t idmap_id = 0; 301757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (idmap != NULL) { 301857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t tmp; 301957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (getIdmapPackageId(header->resourceIDMap, 302057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad header->resourceIDMapSize, 302157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad &tmp) == NO_ERROR) { 302257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad idmap_id = tmp; 302357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 302457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 302557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (parsePackage((ResTable_package*)chunk, header, idmap_id) != NO_ERROR) { 30269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 30279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curPackage++; 30299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 30308564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Unknown chunk type %p in table at %p.\n", 30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(int)(ctype), 30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))); 30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + csize); 30369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curPackage < dtohl(header->header->packageCount)) { 30398564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.", 30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)curPackage, dtohl(header->header->packageCount)); 30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = header->values.getError(); 30449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 30458564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No string values found in resource table!"); 30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 304757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 30485c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError)); 30499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 30519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::getError() const 30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 30559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::uninit() 30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 30599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mError = NO_INIT; 30609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = mPackageGroups.size(); 30619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 30629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* g = mPackageGroups[i]; 30639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete g; 30649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N = mHeaders.size(); 30669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Header* header = mHeaders[i]; 306878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (header->owner == this) { 306978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (header->ownedData) { 307078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn free(header->ownedData); 307178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 307278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete header; 30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageGroups.clear(); 30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeaders.clear(); 30789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 30799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3080d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackbornbool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const 30819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 30829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 30839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 30879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 30889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 30899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 30916cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn if (Res_GETPACKAGE(resID)+1 == 0) { 30928564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No package identifier when getting name for resource number 0x%08x", resID); 30936cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } else { 30948564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No known package when getting name for resource number 0x%08x", resID); 30956cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } 30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 30998564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting name for resource number 0x%08x", resID); 31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* const grp = mPackageGroups[p]; 31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 31058564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting name for resource number 0x%08x", resID); 31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 31079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp->packages.size() > 0) { 31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[0]; 31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 31129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 31139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL); 31149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 31159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 31169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName->package = grp->name.string(); 31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName->packageLen = grp->name.size(); 3120d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (allowUtf8) { 3121d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->type8 = grp->basePackage->typeStrings.string8At(t, &outName->typeLen); 3122d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->name8 = grp->basePackage->keyStrings.string8At( 3123d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn dtohl(entry->key.index), &outName->nameLen); 3124d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 3125d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->type8 = NULL; 3126d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->name8 = NULL; 3127d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 3128d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (outName->type8 == NULL) { 3129d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen); 3130d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // If we have a bad index for some reason, we should abort. 3131d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (outName->type == NULL) { 3132d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return false; 3133d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 3134d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 3135d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (outName->name8 == NULL) { 3136d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn outName->name = grp->basePackage->keyStrings.stringAt( 3137d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn dtohl(entry->key.index), &outName->nameLen); 3138d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn // If we have a bad index for some reason, we should abort. 3139d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (outName->name == NULL) { 3140d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn return false; 3141d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 31423379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 31433379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root 31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 315055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Rootssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density, 31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outSpecFlags, ResTable_config* outConfig) const 31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 31599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 31609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 31626cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn if (Res_GETPACKAGE(resID)+1 == 0) { 31638564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No package identifier when getting value for resource number 0x%08x", resID); 31646cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } else { 31658564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No known package when getting value for resource number 0x%08x", resID); 31666cca1599f78549716ef120245e54fa1961976ddaDianne Hackborn } 31679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 31689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 31708564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting value for resource number 0x%08x", resID); 31719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 31729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* bestValue = NULL; 31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* bestPackage = NULL; 31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config bestItem; 31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up 31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpecFlags != NULL) *outSpecFlags = 0; 318055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 31819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Look through all resource packages, starting with the most 31829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // recently added. 31839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* const grp = mPackageGroups[p]; 31849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 31858564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting value for resource number 0x%08x", resID); 318620cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn return BAD_INDEX; 31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 318855fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 318955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root // Allow overriding density 319055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root const ResTable_config* desiredConfig = &mParams; 319155fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root ResTable_config* overrideConfig = NULL; 319255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (density > 0) { 319355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config)); 319455fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (overrideConfig == NULL) { 31953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno)); 319655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root return BAD_INDEX; 319755fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 319855fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root memcpy(overrideConfig, &mParams, sizeof(ResTable_config)); 319955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root overrideConfig->density = density; 320055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root desiredConfig = overrideConfig; 320155fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 320255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 32035c4cf8cd7ccd76f25a8433096774b44a6dd8ead8Kenny Root ssize_t rc = BAD_VALUE; 32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t ip = grp->packages.size(); 32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ip > 0) { 32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ip--; 320757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int T = t; 320857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int E = e; 32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[ip]; 321157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (package->header->resourceIDMap) { 321257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = 0x0; 321357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad status_t retval = idmapLookup(package->header->resourceIDMap, 321457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad package->header->resourceIDMapSize, 321557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, &overlayResID); 321657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (retval == NO_ERROR && overlayResID != 0x0) { 321757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // for this loop iteration, this is the type and entry we really want 321871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID); 321957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad T = Res_GETTYPE(overlayResID); 322057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad E = Res_GETENTRY(overlayResID); 322157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 322257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // resource not present in overlay package, continue with the next package 322357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 322457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 322557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 32269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 32289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 32299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeClass; 323018490fb93e206fd899c3258096cc32f293373c92Kenny Root ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass); 32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 323257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // No {entry, appropriate config} pair found in package. If this 323357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // package is an overlay package (ip != 0), this simply means the 323457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // overlay package did not specify a default. 323557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Non-overlay packages are still required to provide a default. 323657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (offset < 0 && ip == 0) { 32378564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n", 323857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, T, E, ip, (int)offset); 323955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = offset; 324055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 32419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) { 32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mayBeBag) { 32478564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Requesting resource %p failed because it is complex\n", 32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)resID); 32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 32519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(aout << "Resource type data: " 32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << HexDump(type, dtohl(type->header.size)) << endl); 325555fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) { 32578564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_item at %d is beyond type chunk data %d", 32589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)offset, dtohl(type->header.size)); 325955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = BAD_TYPE; 326055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 326255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* item = 32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const Res_value*)(((const uint8_t*)type) + offset); 32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(type->config); 32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outSpecFlags != NULL) { 32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeClass->typeSpecFlags != NULL) { 327057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]); 32719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outSpecFlags = -1; 32739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 327557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 327657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (bestPackage != NULL && 327757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) { 327857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Discard thisConfig not only if bestItem is more specific, but also if the two configs 327957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // are identical (diff == 0), or overlay packages will not take effect. 32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 32819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestItem = thisConfig; 32849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestValue = item; 32859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestPackage = package; 32869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Found result: package %p\n", bestPackage)); 32899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bestValue) { 32919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->size = dtohs(bestValue->size); 32929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->res0 = bestValue->res0; 32939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = bestValue->dataType; 32949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = dtohl(bestValue->data); 32959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outConfig != NULL) { 32969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outConfig = bestItem; 32979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 32989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(size_t len; 32999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n", 33009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestPackage->header->index, 33019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType, 33029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType == bestValue->TYPE_STRING 33039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? String8(bestPackage->header->values.stringAt( 33049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data, &len)).string() 33059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : "", 33069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data)); 330755fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root rc = bestPackage->header->index; 330855fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root goto out; 330955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root } 331055fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root 331155fc850cf992cdcb0993cb109d2f716613c0dbddKenny Rootout: 331255fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root if (overrideConfig != NULL) { 331355fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root free(overrideConfig); 33149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 331655fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root return rc; 33179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, 33200d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags, 33210d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn ResTable_config* outConfig) const 33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count=0; 33249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE 33259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && value->data != 0 && count < 20) { 33269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outLastRef) *outLastRef = value->data; 33279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t lastRef = value->data; 33289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t newFlags = 0; 332955fc850cf992cdcb0993cb109d2f716613c0dbddKenny Root const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags, 33300d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn outConfig); 333120cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn if (newIndex == BAD_INDEX) { 333220cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn return BAD_INDEX; 333320cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn } 33345c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n", 3335b8d81679553ee33f6ae5281310abf2effca4ffcdDianne Hackborn (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data)); 33369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex); 33379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags; 33389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newIndex < 0) { 33399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This can fail if the resource being referenced is a style... 33409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in this case, just return the reference, and expect the 33419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // caller to deal with. 33429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 33439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blockIndex = newIndex; 33459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return blockIndex; 33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char16_t* ResTable::valueToString( 33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Res_value* value, size_t stringBlock, 33529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen) 33539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!value) { 33559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 33569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value->dataType == value->TYPE_STRING) { 33589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getTableStringBlock(stringBlock)->stringAt(value->data, outLen); 33599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XXX do int to string conversions. 33619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 33629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const 33659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 33679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t err = getBagLocked(resID, outBag); 33689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 33699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("*** get failed! unlocking\n"); 33709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 33739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::unlockBag(const bag_entry* bag) const 33769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("<<< unlockBag %p\n", this); 33789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 33799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::lock() const 33829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 33849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::unlock() const 33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag, 33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mError; 33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(resID); 33999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int t = Res_GETTYPE(resID); 34009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int e = Res_GETENTRY(resID); 34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) { 34038564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID); 34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t < 0) { 34078564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("No type identifier when getting bag for resource number 0x%08x", resID); 34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t); 34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* const grp = mPackageGroups[p]; 34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp == NULL) { 34148564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Bad identifier when getting bag for resource number 0x%08x", resID); 34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t >= (int)grp->typeCount) { 34198564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Type identifier 0x%x is larger than type count 0x%x", 34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t+1, (int)grp->typeCount); 34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const basePackage = grp->packages[0]; 34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* const typeConfigs = basePackage->getType(t); 34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NENTRY = typeConfigs->entryCount; 34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (e >= (int)NENTRY) { 34308564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Entry identifier 0x%x is larger than entry count 0x%x", 34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e, (int)typeConfigs->entryCount); 34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First see if we've already computed this bag... 34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grp->bags) { 34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeSet = grp->bags[t]; 34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeSet) { 34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set* set = typeSet[e]; 34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) { 34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set != (bag_set*)0xFFFFFFFF) { 34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) { 34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = set->typeSpecFlags; 34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outBag = (bag_entry*)(set+1); 34466215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("Found existing bag for: %p\n", (void*)resID); 34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return set->numAttrs; 34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34498564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.", 34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resID); 34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bag not found, we need to compute it! 34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!grp->bags) { 34587e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*)); 34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!grp->bags) return NO_MEMORY; 34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set** typeSet = grp->bags[t]; 34639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!typeSet) { 34647e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*)); 34659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!typeSet) return NO_MEMORY; 34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project grp->bags[t] = typeSet; 34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mark that we are currently working on this one. 34709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSet[e] = (bag_set*)0xFFFFFFFF; 34719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is what we are building. 34739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_set* set = NULL; 34749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34755c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID)); 34769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 347757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ResTable_config bestConfig; 347857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memset(&bestConfig, 0, sizeof(bestConfig)); 347957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 34809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now collect all bag attributes from all packages. 34819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t ip = grp->packages.size(); 34829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ip > 0) { 34839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ip--; 348457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int T = t; 348557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad int E = e; 34869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* const package = grp->packages[ip]; 348857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (package->header->resourceIDMap) { 348957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = 0x0; 349057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad status_t retval = idmapLookup(package->header->resourceIDMap, 349157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad package->header->resourceIDMapSize, 349257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, &overlayResID); 349357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (retval == NO_ERROR && overlayResID != 0x0) { 349457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // for this loop iteration, this is the type and entry we really want 349571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID); 349657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad T = Res_GETTYPE(overlayResID); 349757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad E = Res_GETENTRY(overlayResID); 349857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 349957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // resource not present in overlay package, continue with the next package 350057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 350157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 350257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 35039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type; 35059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* entry; 35069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeClass; 350771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E); 350857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass); 350971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Resulting offset=%d\n", offset); 35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset <= 0) { 351157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // No {entry, appropriate config} pair found in package. If this 351257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // package is an overlay package (ip != 0), this simply means the 351357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // overlay package did not specify a default. 351457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // Non-overlay packages are still required to provide a default. 351557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (offset < 0 && ip == 0) { 35169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) free(set); 35179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return offset; 35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) { 35238564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Skipping entry %p in package table %d because it is not complex!\n", 35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)resID, (int)ip); 35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 352857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set != NULL && !type->config.isBetterThan(bestConfig, NULL)) { 352957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 353057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 353157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad bestConfig = type->config; 353257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set) { 353357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad free(set); 353457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = NULL; 353557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 353657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t entrySize = dtohs(entry->size); 35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t parent = entrySize >= sizeof(ResTable_map_entry) 35399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0; 35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t count = entrySize >= sizeof(ResTable_map_entry) 35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? dtohl(((const ResTable_map_entry*)entry)->count) : 0; 35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t N = count; 35449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35455c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n", 35469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entrySize, parent, count)); 35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 354857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // If this map inherits from another, we need to start 354957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // with its parent's values. Otherwise start out empty. 355057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n", 355157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad entrySize, parent)); 355257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (parent) { 355357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const bag_entry* parentBag; 355457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t parentTypeSpecFlags = 0; 355557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags); 355657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t NT = ((NP >= 0) ? NP : 0) + N; 355757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT); 355857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set == NULL) { 355957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 356057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 356157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (NP > 0) { 356257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad memcpy(set+1, parentBag, NP*sizeof(bag_entry)); 356357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->numAttrs = NP; 35645c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP)); 35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 35665c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n")); 35679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs = 0; 35689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 356957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->availAttrs = NT; 357057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags = parentTypeSpecFlags; 357157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 357257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N); 357357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (set == NULL) { 357457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 357557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 357657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->numAttrs = 0; 357757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->availAttrs = N; 357857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags = 0; 35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeClass->typeSpecFlags != NULL) { 358257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[E]); 35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->typeSpecFlags = -1; 35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now merge in the new attributes... 35889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t curOff = offset; 35899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_map* map; 35909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_entry* entries = (bag_entry*)(set+1); 35919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curEntry = 0; 35929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t pos = 0; 35935c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n", 35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set, entries, set->availAttrs)); 35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < count) { 35969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Now at %p\n", (void*)curOff)); 35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) { 35998564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_map at %d is beyond type chunk data %d", 36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)curOff, dtohl(type->header.size)); 36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map = (const ResTable_map*)(((const uint8_t*)type) + curOff); 36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project N++; 36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t newName = htodl(map->name.ident); 36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool isInside; 36089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t oldName = 0; 36099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((isInside=(curEntry < set->numAttrs)) 36109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (oldName=entries[curEntry].map.name.ident) < newName) { 36119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n", 36129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, entries[curEntry].map.name.ident)); 36139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry++; 36149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((!isInside) || oldName != newName) { 36179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a new attribute... figure out what to do with it. 36189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set->numAttrs >= set->availAttrs) { 36199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Need to alloc more memory... 36209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t newAvail = set->availAttrs+N; 36219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set = (bag_set*)realloc(set, 36229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(bag_set) 36239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + sizeof(bag_entry)*newAvail); 36249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set == NULL) { 36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->availAttrs = newAvail; 36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entries = (bag_entry*)(set+1); 36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n", 36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set, entries, set->availAttrs)); 36319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isInside) { 36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Going in the middle, need to make space. 36349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memmove(entries+curEntry+1, entries+curEntry, 36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeof(bag_entry)*(set->numAttrs-curEntry)); 36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs++; 36379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n", 36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, newName)); 36409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n", 36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, oldName)); 36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag_entry* cur = entries+curEntry; 36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->stringBlock = package->header->index; 36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.name.ident = newName; 36499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.value.copyFrom_dtoh(map->value); 36509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n", 36519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry, cur, cur->stringBlock, cur->map.name.ident, 36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur->map.value.dataType, cur->map.value.data)); 36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // On to the next! 36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curEntry++; 36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t size = dtohs(map->value.size); 36589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curOff += size + sizeof(*map)-sizeof(map->value); 36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 36609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curEntry > set->numAttrs) { 36619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set->numAttrs = curEntry; 36629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // And this is it... 36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeSet[e] = set; 36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (set) { 36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags != NULL) { 36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = set->typeSpecFlags; 36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outBag = (bag_entry*)(set+1); 36725c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs)); 36739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return set->numAttrs; 36749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 36769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 36779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::setParameters(const ResTable_config* params) 36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 36815c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string())); 36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams = *params; 36839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<mPackageGroups.size(); i++) { 36845c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i)); 36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageGroups[i]->clearBagCache(); 36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 36899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getParameters(ResTable_config* params) const 36919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.lock(); 36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *params = mParams; 36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.unlock(); 36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 36969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct id_name_map { 36989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t id; 36999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 37009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t name[6]; 37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst static id_name_map ID_NAMES[] = { 37049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_TYPE, 5, { '^', 't', 'y', 'p', 'e' } }, 37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_L10N, 5, { '^', 'l', '1', '0', 'n' } }, 37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MIN, 4, { '^', 'm', 'i', 'n' } }, 37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MAX, 4, { '^', 'm', 'a', 'x' } }, 37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } }, 37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_ZERO, 5, { '^', 'z', 'e', 'r', 'o' } }, 37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_ONE, 4, { '^', 'o', 'n', 'e' } }, 37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_TWO, 4, { '^', 't', 'w', 'o' } }, 37129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_FEW, 4, { '^', 'f', 'e', 'w' } }, 37139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { ResTable_map::ATTR_MANY, 5, { '^', 'm', 'a', 'n', 'y' } }, 37149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 37159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen, 37179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* type, size_t typeLen, 37189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* package, 37199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t packageLen, 37209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t* outTypeSpecFlags) const 37219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 37229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError)); 37239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check for internal resource identifier as the very first thing, so 37259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // that we will always find them even when there are no resources. 37269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name[0] == '^') { 37279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0])); 37289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 37299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 37309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const id_name_map* m = ID_NAMES + i; 37319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = m->len; 37329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len != nameLen) { 37339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 37349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=1; j<len; j++) { 37369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m->name[j] != name[j]) { 37379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto nope; 37389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3740426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outTypeSpecFlags) { 3741426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC; 3742426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 37439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return m->id; 37449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnope: 37459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ; 37469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nameLen > 7) { 37489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name[1] == 'i' && name[2] == 'n' 37499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && name[3] == 'd' && name[4] == 'e' && name[5] == 'x' 37509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && name[6] == '_') { 37519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = atoi(String8(name + 7, nameLen - 7).string()); 37529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Res_CHECKID(index)) { 37538564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Array resource index: %d is too large.", 37549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index); 37559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 37569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3757426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outTypeSpecFlags) { 3758426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC; 3759426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 37609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_MAKEARRAY(index); 37619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 37649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 37679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 37689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3770426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn bool fakePublic = false; 3771426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn 37729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Figure out the package and type we are looking in... 37739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* packageEnd = NULL; 37759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* typeEnd = NULL; 37769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* const nameEnd = name+nameLen; 37779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = name; 37789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < nameEnd) { 37799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == ':') packageEnd = p; 37809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (*p == '/') typeEnd = p; 37819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 37829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3783426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*name == '@') { 3784426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn name++; 3785426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*name == '*') { 3786426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn fakePublic = true; 3787426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn name++; 3788426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3789426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 37909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name >= nameEnd) { 37919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 37929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 37939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (packageEnd) { 37959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package = name; 37969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project packageLen = packageEnd-name; 37979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = packageEnd+1; 37989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!package) { 37999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeEnd) { 38039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = name; 38049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeLen = typeEnd-name; 38059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = typeEnd+1; 38069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!type) { 38079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name >= nameEnd) { 38119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nameLen = nameEnd-name; 38149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n", 38169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(type, typeLen).string(), 38179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name, nameLen).string(), 38189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package, packageLen).string())); 38199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NG = mPackageGroups.size(); 38219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t ig=0; ig<NG; ig++) { 38229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* group = mPackageGroups[ig]; 38239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(package, packageLen, 38259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group->name.string(), group->name.size())) { 38269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string())); 38279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 38289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 383078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen); 38319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ti < 0) { 38329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string())); 38339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 38349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 383678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen); 38379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ei < 0) { 38389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string())); 38399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 38409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei)); 38439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* const typeConfigs = group->packages[0]->getType(ti); 38459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) { 38469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n", 38479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(group->name).string(), ti)); 38489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t NTC = typeConfigs->configs.size(); 38519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t tci=0; tci<NTC; tci++) { 38529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* const ty = typeConfigs->configs[tci]; 38539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t typeOffset = dtohl(ty->entriesStart); 38549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size); 38569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 38579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ty) + dtohs(ty->header.headerSize)); 38589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NE = dtohl(ty->entryCount); 38609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<NE; i++) { 38619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset = dtohl(eindex[i]); 38629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset == ResTable_type::NO_ENTRY) { 38639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 38649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset += typeOffset; 38679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) { 38698564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at %d is beyond type chunk data %d", 38709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset, dtohl(ty->header.size)); 38719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset&0x3) != 0) { 38748564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s", 38759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)offset, (int)group->id, (int)ti+1, (int)i, 38769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package, packageLen).string(), 38779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(type, typeLen).string(), 38789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name, nameLen).string()); 38799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 38809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* const entry = (const ResTable_entry*) 38839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ty) + offset); 38849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(entry->size) < sizeof(*entry)) { 38858564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry size %d is too small", dtohs(entry->size)); 38869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 38879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n", 38909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i, ei, dtohl(entry->key.index))); 38919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(entry->key.index) == (size_t)ei) { 38929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeSpecFlags) { 38939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeSpecFlags = typeConfigs->typeSpecFlags[i]; 3894426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (fakePublic) { 3895426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC; 3896426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 38979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Res_MAKEID(group->id-1, ti, i); 38999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 39059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 39069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen, 39089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outPackage, 39099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outType, 39109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16* outName, 39119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defType, 39129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defPackage, 3913426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn const char** outErrorMsg, 3914426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn bool* outPublicOnly) 39159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 39169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* packageEnd = NULL; 39179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* typeEnd = NULL; 39189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = refStr; 39199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* const end = p + refLen; 39209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < end) { 39219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == ':') packageEnd = p; 39229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (*p == '/') { 39239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeEnd = p; 39249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 39259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 39279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = refStr; 39299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p == '@') p++; 39309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3931426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outPublicOnly != NULL) { 3932426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outPublicOnly = true; 3933426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3934426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (*p == '*') { 3935426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn p++; 3936426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn if (outPublicOnly != NULL) { 3937426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn *outPublicOnly = false; 3938426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3939426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn } 3940426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn 39419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (packageEnd) { 39429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outPackage = String16(p, packageEnd-p); 39439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = packageEnd+1; 39449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 39459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defPackage) { 39469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 39479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "No resource package specified"; 39489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outPackage = *defPackage; 39529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeEnd) { 39549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = String16(p, typeEnd-p); 39559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = typeEnd+1; 39569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 39579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!defType) { 39589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 39599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "No resource type specified"; 39609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 39629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = *defType; 39649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outName = String16(p, end-p); 3966ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outPackage == 0) { 3967ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3968ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource package cannot be an empty string"; 3969ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3970ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3971ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3972ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outType == 0) { 3973ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3974ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource type cannot be an empty string"; 3975ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3976ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3977ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3978ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(**outName == 0) { 3979ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev if(outErrorMsg) { 3980ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev *outErrorMsg = "Resource id cannot be an empty string"; 3981ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 3982ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev return false; 3983ddcafcbd62c4efdc70bc626ab210a3c41dd1333cKonstantin Lopyrev } 39849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 39859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 39869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t get_hex(char c, bool* outError) 39889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 39899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c >= '0' && c <= '9') { 39909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - '0'; 39919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (c >= 'a' && c <= 'f') { 39929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - 'a' + 0xa; 39939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (c >= 'A' && c <= 'F') { 39949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c - 'A' + 0xa; 39959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outError = true; 39979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 39989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 39999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct unit_entry 40019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 40029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* name; 40039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 40049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t type; 40059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t unit; 40069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale; 40079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 40089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const unit_entry unitNames[] = { 40109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f }, 40119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f }, 40129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f }, 40139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f }, 40149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f }, 40159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f }, 40169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f }, 40179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 }, 40189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 }, 40199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { NULL, 0, 0, 0, 0 } 40209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 40219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool parse_unit(const char* str, Res_value* outValue, 40239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* outScale, const char** outEnd) 40249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 40259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* end = str; 40269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*end != 0 && !isspace((unsigned char)*end)) { 40279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project end++; 40289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t len = end-str; 40309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* realEnd = end; 40329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*realEnd != 0 && isspace((unsigned char)*realEnd)) { 40339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project realEnd++; 40349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*realEnd != 0) { 40369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const unit_entry* cur = unitNames; 40409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cur->name) { 40419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == cur->len && strncmp(cur->name, str, len) == 0) { 40429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = cur->type; 40439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT; 40449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outScale = cur->scale; 40459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outEnd = end; 40469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Found unit %s for %s\n", cur->name, str); 40479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 40489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cur++; 40509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 40549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) 40579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 40589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 40599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 40609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 40619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len <= 0) { 40649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t i = 0; 40689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t val = 0; 40699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool neg = false; 40709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '-') { 40729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project neg = true; 40739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 40749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] < '0' || s[i] > '9') { 40779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Decimal or hex? 40819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] == '0' && s[i+1] == 'x') { 40829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 40839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_HEX; 40849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i += 2; 40859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool error = false; 40869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len && !error) { 40879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val = (val*16) + get_hex(s[i], &error); 40889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 40899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (error) { 40919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 40949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 40959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_DEC; 40969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len) { 40979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s[i] < '0' || s[i] > '9') { 40989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 40999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val = (val*10) + s[i]-'0'; 41019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 41029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) val = -val; 41069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len && isspace16(s[i])) { 41089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 41099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == len) { 41129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) 41139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = val; 41149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 41199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) 41219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 41229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 41239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 41249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 41259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len <= 0) { 41289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 41329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i=0; 41339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && *s != 0 && i < 126) { 41349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s > 255) { 41359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[i++] = *s++; 41389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 41399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) { 41429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') { 41459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[i] = 0; 41499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* end; 41509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = strtof(buf, (char**)&end); 41519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*end != 0 && !isspace((unsigned char)*end)) { 41539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Might be a unit... 41549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float scale; 41559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parse_unit(end, outValue, &scale, &end)) { 41569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= scale; 41579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool neg = f < 0; 41589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) f = -f; 41599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint64_t bits = (uint64_t)(f*(1<<23)+.5f); 41609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t radix; 41619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t shift; 41629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((bits&0x7fffff) == 0) { 41639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always use 23p0 if there is no fraction, just to make 41649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // things easier to read. 41659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_23p0; 41669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 23; 41679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffffffff800000LL) == 0) { 41689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude is zero -- can fit in 0 bits of precision. 41699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_0p23; 41709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 0; 41719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffffff80000000LL) == 0) { 41729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude can fit in 8 bits of precision. 41739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_8p15; 41749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 8; 41759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((bits&0xffffff8000000000LL) == 0) { 41769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude can fit in 16 bits of precision. 41779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_16p7; 41789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 16; 41799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 41809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Magnitude needs entire range, so no fractional part. 41819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radix = Res_value::COMPLEX_RADIX_23p0; 41829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shift = 23; 41839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t mantissa = (int32_t)( 41859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK); 41869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (neg) { 41879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK; 41889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data |= 41909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (radix<<Res_value::COMPLEX_RADIX_SHIFT) 41919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT); 41929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n", 41939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // f * (neg ? -1 : 1), bits, f*(1<<23), 41949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // radix, shift, outValue->data); 41959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 41969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 41989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 41999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*end != 0 && isspace((unsigned char)*end)) { 42019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project end++; 42029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*end == 0) { 42059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue) { 42069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_FLOAT; 42079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *(float*)(&outValue->data) = f; 42089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 42099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 42139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 42149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::stringToValue(Res_value* outValue, String16* outString, 42169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s, size_t len, 42179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool preserveSpaces, bool coerceType, 42189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrID, 42199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defType, 42209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const String16* defPackage, 42219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Accessor* accessor, 42229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* accessorCookie, 42239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrType, 42249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool enforcePrivate) const 42259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 42269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting(); 42279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* errorMsg = NULL; 42289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->size = sizeof(Res_value); 42309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->res0 = 0; 42319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First strip leading/trailing whitespace. Do this before handling 42339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // escapes, so they can be used to force whitespace into the string. 42349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces) { 42359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(*s)) { 42369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s++; 42379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 42389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0 && isspace16(s[len-1])) { 42409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 42419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the string ends with '\', then we keep the space after it. 42439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0 && s[len-1] == '\\' && s[len] != 0) { 42449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len++; 42459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Value for: %s\n", String8(s, len).string()); 42499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED; 42519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff; 42529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool fromAccessor = false; 42539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attrID != 0 && !Res_INTERNALID(attrID)) { 42549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 42559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 42569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 42579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("For attr 0x%08x got bag of %d\n", attrID, cnt); 42589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 42599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cnt > 0) { 42609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data); 42619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (bag->map.name.ident) { 42629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_TYPE: 42639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrType = bag->map.value.data; 42649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 42659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_MIN: 42669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrMin = bag->map.value.data; 42679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 42689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_MAX: 42699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrMax = bag->map.value.data; 42709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 42719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ResTable_map::ATTR_L10N: 42729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l10nReq = bag->map.value.data; 42739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 42749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 42769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 42779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 42799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (accessor && accessor->getAttributeType(attrID, &attrType)) { 42809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fromAccessor = true; 42819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attrType == ResTable_map::TYPE_ENUM 42829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || attrType == ResTable_map::TYPE_FLAGS 42839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || attrType == ResTable_map::TYPE_INTEGER) { 42849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getAttributeMin(attrID, &attrMin); 42859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getAttributeMax(attrID, &attrMax); 42869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localizationSetting) { 42889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l10nReq = accessor->getAttributeL10N(attrID); 42899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool canStringCoerce = 42949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project coerceType && (attrType&ResTable_map::TYPE_STRING) != 0; 42959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '@') { 42979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_REFERENCE; 42989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: we don't check attrType here because the reference can 43009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be to any other type; we just need to count on the client making 43019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sure the referenced type is correct. 43029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Looking up ref: %s\n", String8(s, len).string()); 43049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's a reference! 43069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') { 43079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 43089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 43109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool createIfNotFound = false; 43119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* resourceRefName; 43129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int resourceNameLen; 43139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 2 && s[1] == '+') { 43149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound = true; 43159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 2; 43169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 2; 43179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len > 2 && s[1] == '*') { 43189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforcePrivate = false; 43199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 2; 43209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 2; 43219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 43229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound = false; 43239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceRefName = s + 1; 43249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resourceNameLen = len - 1; 43259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 package, type, name; 43279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name, 43289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defType, defPackage, &errorMsg)) { 43299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 43319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t specFlags = 0; 43369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = identifierForName(name.string(), name.size(), type.string(), 43379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type.size(), package.string(), package.size(), &specFlags); 43389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 43399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enforcePrivate) { 43409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) { 43419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Resource is not public."); 43439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!accessor) { 43489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rid = Res_MAKEID( 43529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getRemappedPackage(Res_GETPACKAGE(rid)), 43539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_GETTYPE(rid), Res_GETENTRY(rid)); 43549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n", 43559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package).string(), String8(type).string(), 43569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name).string(), rid)); 43579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor) { 43629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name, 43639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createIfNotFound); 43649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 43659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n", 43669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(package).string(), String8(type).string(), 43679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(name).string(), rid)); 43689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 43699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 43709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "No resource found that matches the given name"); 43769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 43789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we got to here, and localization is required and it's not a reference, 43819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // complain and bail. 43829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l10nReq == ResTable_map::L10N_SUGGESTED) { 43839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localizationSetting) { 43849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 43859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "This attribute must be localized."); 43869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '#') { 43919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's a color! Convert to an integer of the form 0xaarrggbb. 43929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t color = 0; 43939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool error = false; 43949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 4) { 43959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_RGB4; 43969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= 0xFF000000; 43979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 20; 43989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 16; 43999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 12; 44009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 8; 44019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 4; 44029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error); 44039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 5) { 44049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4; 44059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 28; 44069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 24; 44079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 20; 44089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 16; 44099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 12; 44109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 8; 44119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 4; 44129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error); 44139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 7) { 44149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_RGB8; 44159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= 0xFF000000; 44169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 20; 44179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 16; 44189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 12; 44199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 8; 44209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[5], &error) << 4; 44219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[6], &error); 44229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 9) { 44239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8; 44249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[1], &error) << 28; 44259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[2], &error) << 24; 44269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[3], &error) << 20; 44279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[4], &error) << 16; 44289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[5], &error) << 12; 44299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[6], &error) << 8; 44309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[7], &error) << 4; 44319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color |= get_hex(s[8], &error); 44329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 44339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error = true; 44349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!error) { 44369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_COLOR) == 0) { 44379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 44389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, 44409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Color types not allowed"); 44419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 44439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 44459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = color; 44469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color); 44479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 44489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 44509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_COLOR) != 0) { 44519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Color value not valid --" 44539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " must be #rgb, #argb, #rrggbb, or #aarrggbb"); 44549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 44569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "%s: Color ID %s value %s is not valid\n", 44579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Resource File", //(const char*)in->getPrintableSource(), 44589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(*curTag).string(), 44599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s, len).string()); 44609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 44619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 44629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*s == '?') { 44679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_ATTRIBUTE; 44689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: we don't check attrType here because the reference can 44709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be to any other type; we just need to count on the client making 44719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sure the referenced type is correct. 44729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Looking up attr: %s\n", String8(s, len).string()); 44749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static const String16 attr16("attr"); 44769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 package, type, name; 44779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!expandResourceRef(s+1, len-1, &package, &type, &name, 44789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &attr16, defPackage, &errorMsg)) { 44799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 44819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 44839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Pkg: %s, Type: %s, Name: %s\n", 44869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 44879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string()); 44889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t specFlags = 0; 44899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = 44909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project identifierForName(name.string(), name.size(), 44919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type.string(), type.size(), 44929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package.string(), package.size(), &specFlags); 44939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 44949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enforcePrivate) { 44959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) { 44969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 44979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Attribute is not public."); 44989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!accessor) { 45039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 45049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rid = Res_MAKEID( 45079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->getRemappedPackage(Res_GETPACKAGE(rid)), 45089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Res_GETTYPE(rid), Res_GETENTRY(rid)); 45099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Incl %s:%s/%s: 0x%08x\n", 45109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 45119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string(), rid); 45129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 45139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor) { 45179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t rid = accessor->getCustomResource(package, type, name); 45189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rid != 0) { 45199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Mine %s:%s/%s: 0x%08x\n", 45209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(package).string(), String8(type).string(), 45219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // String8(name).string(), rid); 45229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = rid; 45239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "No resource found that matches the given name"); 45299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stringToInt(s, len, outValue)) { 45349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_INTEGER) == 0) { 45359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this type does not allow integers, but does allow floats, 45369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through on this error case because the float type should 45379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be able to accept any integer value. 45389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) { 45399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Integer types not allowed"); 45419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 45459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((int32_t)outValue->data) < ((int32_t)attrMin) 45469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || ((int32_t)outValue->data) > ((int32_t)attrMax)) { 45479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Integer value out of range"); 45499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 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 Project 45569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stringToFloat(s, len, outValue)) { 45579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outValue->dataType == Res_value::TYPE_DIMENSION) { 45589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) { 45599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 45629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Dimension types not allowed"); 45649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (outValue->dataType == Res_value::TYPE_FRACTION) { 45689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_FRACTION) != 0) { 45699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 45729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Fraction types not allowed"); 45749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) { 45789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 45799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Float types not allowed"); 45819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 45839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 45859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 45869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 4) { 45909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((s[0] == 't' || s[0] == 'T') && 45919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[1] == 'r' || s[1] == 'R') && 45929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[2] == 'u' || s[2] == 'U') && 45939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[3] == 'e' || s[3] == 'E')) { 45949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) { 45959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 45969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 45979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Boolean types not allowed"); 45989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 46009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_BOOLEAN; 46039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = (uint32_t)-1; 46049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 46059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 5) { 46109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((s[0] == 'f' || s[0] == 'F') && 46119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[1] == 'a' || s[1] == 'A') && 46129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[2] == 'l' || s[2] == 'L') && 46139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[3] == 's' || s[3] == 'S') && 46149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (s[4] == 'e' || s[4] == 'E')) { 46159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) { 46169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!canStringCoerce) { 46179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 46189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "Boolean types not allowed"); 46199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 46219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 46239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_INT_BOOLEAN; 46249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 46259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 46269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_ENUM) != 0) { 46319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 46329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 46339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 46349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Got %d for enum\n", cnt); 46359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 46369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name rname; 46379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (cnt > 0) { 46389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!Res_INTERNALID(bag->map.name.ident)) { 46399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Trying attr #%08x\n", bag->map.name.ident); 4640d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (getResourceName(bag->map.name.ident, false, &rname)) { 46419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 46429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Matching %s against %s (0x%08x)\n", 46439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(s, len).string(), 46449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(rname.name, rname.nameLen).string(), 46459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag->map.name.ident); 46469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 46479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) { 46489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = bag->map.value.dataType; 46499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = bag->map.value.data; 46509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 46519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 46529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bag++; 46579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cnt--; 46589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 46609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fromAccessor) { 46639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor->getAttributeEnum(attrID, s, len, outValue)) { 46649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 46659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_FLAGS) != 0) { 46709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ssize_t p = getResourcePackageIndex(attrID); 46719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bag; 46729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1; 46739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Got %d for flags\n", cnt); 46749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cnt >= 0) { 46759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool failed = false; 46769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name rname; 46779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = Res_value::TYPE_INT_HEX; 46789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data = 0; 46799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* end = s + len; 46809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* pos = s; 46819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < end && !failed) { 46829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* start = pos; 46834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project pos++; 46849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (pos < end && *pos != '|') { 46859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 46869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Looking for: %s\n", String8(start, pos-start).string()); 46889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bag_entry* bagi = bag; 46894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ssize_t i; 46909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0; i<cnt; i++, bagi++) { 46919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!Res_INTERNALID(bagi->map.name.ident)) { 46929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Trying attr #%08x\n", bagi->map.name.ident); 4693d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (getResourceName(bagi->map.name.ident, false, &rname)) { 46949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #if 0 46959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Matching %s against %s (0x%08x)\n", 46969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(start,pos-start).string(), 46979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(rname.name, rname.nameLen).string(), 46989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bagi->map.name.ident); 46999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 47009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) { 47019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->data |= bagi->map.value.data; 47029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i >= cnt) { 47089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Didn't find this flag identifier. 47099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failed = true; 47109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos < end) { 47129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos++; 47139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unlockBag(bag); 47169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!failed) { 47174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Final flag value: 0x%lx\n", outValue->data); 47189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 47199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fromAccessor) { 47249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor->getAttributeFlags(attrID, s, len, outValue)) { 47254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project //printf("Final flag value: 0x%lx\n", outValue->data); 47269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 47279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((attrType&ResTable_map::TYPE_STRING) == 0) { 47329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 47339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, "String types not allowed"); 47349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 47369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Generic string handling... 47399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outValue->dataType = outValue->TYPE_STRING; 47409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outString) { 47419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg); 47429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accessor != NULL) { 47439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project accessor->reportError(accessorCookie, errorMsg); 47449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return failed; 47469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 47499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 47509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResTable::collectString(String16* outString, 47529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* s, size_t len, 47539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool preserveSpaces, 47549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char** outErrorMsg, 47559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool append) 47569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String16 tmp; 47589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char quoted = 0; 47609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t* p = s; 47619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len)) { 47629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len)) { 47639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char16_t c = *p; 47649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '\\') { 47659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces) { 47689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (quoted == 0 && isspace16(c) 47699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (c != ' ' || isspace16(*(p+1)))) { 47709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '"' && (quoted == 0 || quoted == '"')) { 47739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 47749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == '\'' && (quoted == 0 || quoted == '\'')) { 4776c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer /* 4777c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * In practice, when people write ' instead of \' 4778c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * in a string, they are doing it by accident 4779c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * instead of really meaning to use ' as a quoting 4780c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer * character. Warn them so they don't lose it. 4781c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer */ 4782c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer if (outErrorMsg) { 4783c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer *outErrorMsg = "Apostrophe not preceded by \\"; 4784c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer } 4785c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer return false; 47869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 47899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < (s+len)) { 47919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p > s) { 47929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(s, p-s)); 47939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 47949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!preserveSpaces && (*p == '"' || *p == '\'')) { 47959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (quoted == 0) { 47969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project quoted = *p; 47979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 47989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project quoted = 0; 47999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!preserveSpaces && isspace16(*p)) { 48029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Space outside of a quote -- consume all spaces and 48039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // leave a single plain space char. 48049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(" ")); 48059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p < (s+len) && isspace16(*p)) { 48079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p == '\\') { 48109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < (s+len)) { 48129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (*p) { 48139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 't': 48149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\t")); 48159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'n': 48179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\n")); 48189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '#': 48209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("#")); 48219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '@': 48239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("@")); 48249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '?': 48269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("?")); 48279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '"': 48299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\"")); 48309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\'': 48329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("'")); 48339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\\': 48359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16("\\")); 48369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'u': 48389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 48399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t chr = 0; 48409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 48419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < 4 && p[1] != 0) { 48429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 48449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c; 48459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*p >= '0' && *p <= '9') { 48469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - '0'; 48479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p >= 'a' && *p <= 'f') { 48489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - 'a' + 10; 48499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (*p >= 'A' && *p <= 'F') { 48509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = *p - 'A' + 10; 48519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 48529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outErrorMsg) { 48539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outErrorMsg = "Bad character in \\u unicode escape sequence"; 48549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 48569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chr = (chr<<4) | c; 48589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(&chr, 1)); 48609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 48619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 48629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore unknown escape chars. 48639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 48649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++; 48669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len -= (p-s); 48699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = p; 48709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tmp.size() != 0) { 48749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) { 48759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp.append(String16(s, len)); 48769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (append) { 48789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->append(tmp); 48799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 48809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->setTo(tmp); 48819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 48839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (append) { 48849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->append(String16(s, len)); 48859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 48869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outString->setTo(s, len); 48879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 48919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 48929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResTable::getBasePackageCount() const 48949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 48959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 48969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 48979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups.size(); 48999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char16_t* ResTable::getBasePackageName(size_t idx) const 49029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 49049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 49059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(idx >= mPackageGroups.size(), 49079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requested package index %d past package count %d", 49089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)mPackageGroups.size()); 49099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups[idx]->name.string(); 49109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResTable::getBasePackageId(size_t idx) const 49139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mError != NO_ERROR) { 49159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 49169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(idx >= mPackageGroups.size(), 49189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requested package index %d past package count %d", 49199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)idx, (int)mPackageGroups.size()); 49209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPackageGroups[idx]->id; 49219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResTable::getTableCount() const 49249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeaders.size(); 49269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResStringPool* ResTable::getTableStringBlock(size_t index) const 49299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return &mHeaders[index]->values; 49319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* ResTable::getTableCookie(size_t index) const 49349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeaders[index]->cookie; 49369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getConfigurations(Vector<ResTable_config>* configs) const 49399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t I = mPackageGroups.size(); 49419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<I; i++) { 49429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* packageGroup = mPackageGroups[i]; 49439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t J = packageGroup->packages.size(); 49449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t j=0; j<J; j++) { 49459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* package = packageGroup->packages[j]; 49469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t K = package->types.size(); 49479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t k=0; k<K; k++) { 49489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* type = package->types[k]; 49499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == NULL) continue; 49509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t L = type->configs.size(); 49519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t l=0; l<L; l++) { 49529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* config = type->configs[l]; 49539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_config* cfg = &config->config; 49549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only insert unique 49559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t M = configs->size(); 49569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t m; 49579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (m=0; m<M; m++) { 49589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == (*configs)[m].compare(*cfg)) { 49599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 49609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we didn't find it 49639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m == M) { 49649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project configs->add(*cfg); 49659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResTable::getLocales(Vector<String8>* locales) const 49739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 49749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Vector<ResTable_config> configs; 497571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("calling getConfigurations"); 49769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getConfigurations(&configs); 497771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("called getConfigurations size=%d", (int)configs.size()); 49789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t I = configs.size(); 49799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<I; i++) { 49809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char locale[6]; 49819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project configs[i].getLocale(locale); 49829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t J = locales->size(); 49839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t j; 49849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (j=0; j<J; j++) { 49859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strcmp(locale, (*locales)[j].string())) { 49869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 49879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (j == J) { 49909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locales->add(String8(locale)); 49919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 49949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResTable::getEntry( 49969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* package, int typeIndex, int entryIndex, 49979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_config* config, 49989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type** outType, const ResTable_entry** outEntry, 49999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type** outTypeClass) const 50009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 500171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Getting entry from package %p\n", package); 50029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_package* const pkg = package->package; 50039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* allTypes = package->getType(typeIndex); 500571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("allTypes=%p\n", allTypes); 50069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (allTypes == NULL) { 500771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex); 50089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 50099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size_t)entryIndex >= allTypes->entryCount) { 50128564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d", 50139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entryIndex, (int)allTypes->entryCount); 50149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 50159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = NULL; 50189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t offset = ResTable_type::NO_ENTRY; 50199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config bestConfig; 50209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up 50219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NT = allTypes->configs.size(); 50239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<NT; i++) { 50249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* const thisType = allTypes->configs[i]; 50259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisType == NULL) continue; 50269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 50289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(thisType->config); 50299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50305c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n", 50319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entryIndex, typeIndex+1, dtohl(thisType->config.size), 50326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn thisConfig.toString().string())); 50339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check to make sure this one is valid for the current parameters. 50359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (config && !thisConfig.match(*config)) { 50365c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Does not match config!\n")); 50379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 50389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if there is the desired entry in this type. 50419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)thisType) 50439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohl(thisType->header.size); 50449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 50459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize)); 50469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t thisOffset = dtohl(eindex[entryIndex]); 50489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisOffset == ResTable_type::NO_ENTRY) { 50495c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n")); 50509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 50519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != NULL) { 50549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if this one is less specific than the last found. If so, 50559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we will skip it. We check starting with things we most care 50569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // about to those we least care about. 50579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!thisConfig.isBetterThan(bestConfig, config)) { 50585c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("This config is worse than last!\n")); 50599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 50609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type = thisType; 50649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = thisOffset; 50659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bestConfig = thisConfig; 50665c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n")); 50679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!config) break; 50689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == NULL) { 50715c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_GETENTRY(ALOGI("No value found for requested entry!\n")); 50729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_INDEX; 50739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset += dtohl(type->entriesStart); 50769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_NOISY(aout << "Looking in resource table " << package->header->header 50779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << ", typeOff=" 50789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << (void*)(((const char*)type)-((const char*)package->header->header)) 50799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project << ", offset=" << (void*)offset << endl); 50809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) { 50828564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x", 50839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset, dtohl(type->header.size)); 50849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 50859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset&0x3) != 0) { 50878564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry at 0x%x is not on an integer boundary", 50889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset); 50899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 50909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* const entry = (const ResTable_entry*) 50939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + offset); 50949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(entry->size) < sizeof(*entry)) { 50958564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size)); 50969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BAD_TYPE; 50979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outType = type; 51009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outEntry = entry; 51019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outTypeClass != NULL) { 51029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outTypeClass = allTypes; 51039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return offset + dtohs(entry->size); 51059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 51069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResTable::parsePackage(const ResTable_package* const pkg, 510857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Header* const header, uint32_t idmap_id) 51099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 51109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* base = (const uint8_t*)pkg; 51119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(&pkg->header, sizeof(*pkg), 51129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd, "ResTable_package"); 51139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 51149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t pkgSize = dtohl(pkg->header.size); 51189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(pkg->typeStrings) >= pkgSize) { 51208564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package type strings at %p are past chunk size %p.", 51219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->typeStrings), (void*)pkgSize); 51229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(pkg->typeStrings)&0x3) != 0) { 51258564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package type strings at %p is not on an integer boundary.", 51269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->typeStrings)); 51279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(pkg->keyStrings) >= pkgSize) { 51308564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package key strings at %p are past chunk size %p.", 51319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->keyStrings), (void*)pkgSize); 51329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(pkg->keyStrings)&0x3) != 0) { 51358564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_package key strings at %p is not on an integer boundary.", 51369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(pkg->keyStrings)); 51379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 51389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Package* package = NULL; 51419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageGroup* group = NULL; 514257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t id = idmap_id != 0 ? idmap_id : dtohl(pkg->id); 514357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // If at this point id == 0, pkg is an overlay package without a 514457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // corresponding idmap. During regular usage, overlay packages are 514557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // always loaded alongside their idmaps, but during idmap creation 514657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // the package is temporarily loaded by itself. 514757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (id < 256) { 514878c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 514978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn package = new Package(this, header, pkg); 515078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn if (package == NULL) { 515178c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn return (mError=NO_MEMORY); 515278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn } 515378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 51549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t idx = mPackageMap[id]; 51559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx == 0) { 51569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project idx = mPackageGroups.size()+1; 51579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)]; 51599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t)); 516078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn group = new PackageGroup(this, String16(tmpName), id); 51619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group == NULL) { 516278c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 51639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=NO_MEMORY); 51649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 516678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings), 51679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd-(base+dtohl(pkg->typeStrings))); 51689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 516978c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete group; 517078c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 51719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 517378c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings), 51749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header->dataEnd-(base+dtohl(pkg->keyStrings))); 51759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 517678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete group; 517778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn delete package; 51789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //printf("Adding new package id %d at index %d\n", id, idx); 51829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = mPackageGroups.add(group); 51839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 51849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 518678c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn group->basePackage = package; 518778c405178c57bb45e40f1e2839d6a18d91f7f02cDianne Hackborn 51889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPackageMap[id] = (uint8_t)idx; 51899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 51909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group = mPackageGroups.itemAt(idx-1); 51919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group == NULL) { 51929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=UNKNOWN_ERROR); 51939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = group->packages.add(package); 51969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < NO_ERROR) { 51979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 51989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 520057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad LOG_ALWAYS_FATAL("Package id out of range"); 52019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 52029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Iterate through all chunks. 52069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t curPackage = 0; 52079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResChunk_header* chunk = 52099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (const ResChunk_header*)(((const uint8_t*)pkg) 52109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohs(pkg->header.headerSize)); 52119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size); 52129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) && 52139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) { 52145c6dfeb1fb47102ffce415ea7898b33dd1290d54Dianne Hackborn TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n", 52159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size), 52169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)))); 52179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t csize = dtohl(chunk->size); 52189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint16_t ctype = dtohs(chunk->type); 52199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ctype == RES_TABLE_TYPE_SPEC_TYPE) { 52209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk); 52219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = validate_chunk(&typeSpec->header, sizeof(*typeSpec), 52229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_typeSpec"); 52239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 52249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 52259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t typeSpecSize = dtohl(typeSpec->header.size); 52289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n", 52309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(base-(const uint8_t*)chunk), 52319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(typeSpec->header.type), 52329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(typeSpec->header.headerSize), 52339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize)); 52349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // look for block overrun or int overflow when multiplying by 4 52359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t)) 52369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount)) 52379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > typeSpecSize)) { 52388564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.", 52399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dtohs(typeSpec->header.headerSize) 52409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))), 52419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSpecSize); 52429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeSpec->id == 0) { 52468564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type has an id of 0."); 52479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (package->types.size() < typeSpec->id) { 52519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.add(NULL); 52529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type* t = package->types[typeSpec->id-1]; 52549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == NULL) { 52559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = new Type(header, package, dtohl(typeSpec->entryCount)); 52569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.editItemAt(typeSpec->id-1) = t; 52579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (dtohl(typeSpec->entryCount) != t->entryCount) { 52588564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d", 52599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(typeSpec->entryCount), (int)t->entryCount); 52609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->typeSpecFlags = (const uint32_t*)( 52639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize)); 52649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->typeSpec = typeSpec; 52659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (ctype == RES_TABLE_TYPE_TYPE) { 52679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = (const ResTable_type*)(chunk); 52689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4, 52699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_type"); 52709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 52719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 52729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t typeSize = dtohl(type->header.size); 52759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n", 52779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(base-(const uint8_t*)chunk), 52789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(type->header.type), 52799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dtohs(type->header.headerSize), 52809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize)); 52819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount)) 52829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project > typeSize) { 52838564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entry index to %p extends beyond chunk end %p.", 52849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(dtohs(type->header.headerSize) 52859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project +(sizeof(uint32_t)*dtohl(type->entryCount))), 52869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize); 52879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dtohl(type->entryCount) != 0 52909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) { 52918564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.", 52929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)dtohl(type->entriesStart), (void*)typeSize); 52939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type->id == 0) { 52968564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type has an id of 0."); 52979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 52989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 52999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (package->types.size() < type->id) { 53019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.add(NULL); 53029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Type* t = package->types[type->id-1]; 53049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == NULL) { 53059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = new Type(header, package, dtohl(type->entryCount)); 53069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project package->types.editItemAt(type->id-1) = t; 53079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (dtohl(type->entryCount) != t->entryCount) { 53088564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("ResTable_type entry count inconsistent: given %d, previously %d", 53099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)dtohl(type->entryCount), (int)t->entryCount); 53109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=BAD_TYPE); 53119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TABLE_GETENTRY( 53149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResTable_config thisConfig; 53159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thisConfig.copyFromDtoH(type->config); 53166c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ALOGI("Adding config to type %d: %s\n", 53176c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn type->id, thisConfig.toString().string())); 53189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->configs.add(type); 53199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 53209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = validate_chunk(chunk, sizeof(ResChunk_header), 53219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endPos, "ResTable_package:unknown"); 53229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 53239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mError=err); 53249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project chunk = (const ResChunk_header*) 53279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)chunk) + csize); 53289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (group->typeCount == 0) { 53319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group->typeCount = package->types.size(); 53329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 53359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 53369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 533757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadstatus_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc, 533857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad void** outData, size_t* outSize) const 533957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 534057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // see README for details on the format of map 534157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mPackageGroups.size() == 0) { 534257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 534357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 534457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mPackageGroups[0]->packages.size() == 0) { 534557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return UNKNOWN_ERROR; 534657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 534757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 534857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Vector<Vector<uint32_t> > map; 534957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const PackageGroup* pg = mPackageGroups[0]; 535057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Package* pkg = pg->packages[0]; 535157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t typeCount = pkg->types.size(); 535257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // starting size is header + first item (number of types in map) 535357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t); 535457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name); 535557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t pkg_id = pkg->package->id << 24; 535657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 535757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) { 5358249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ssize_t first = -1; 5359249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ssize_t last = -1; 536057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Type* typeConfigs = pkg->getType(typeIndex); 536157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad ssize_t mapIndex = map.add(); 536257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (mapIndex < 0) { 536357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 536457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 536557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad Vector<uint32_t>& vector = map.editItemAt(mapIndex); 536657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) { 5367c761d8b0086f9e92eb1e4b3a5683ae6afb84036aMårten Kongstad uint32_t resID = pkg_id 536857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad | (0x00ff0000 & ((typeIndex+1)<<16)) 536957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad | (0x0000ffff & (entryIndex)); 537057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resource_name resName; 5371d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (!this->getResourceName(resID, true, &resName)) { 53728564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID); 5373249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // add dummy value, or trimming leading/trailing zeroes later will fail 5374249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.push(0); 5375fcaba1464ef010ba0e3fdcbce2af74e45daec627Mårten Kongstad continue; 537657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 537757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 537857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayType(resName.type, resName.typeLen); 537957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const String16 overlayName(resName.name, resName.nameLen); 538057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t overlayResID = overlay.identifierForName(overlayName.string(), 538157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayName.size(), 538257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayType.string(), 538357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayType.size(), 538457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayPackage.string(), 538557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad overlayPackage.size()); 538657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (overlayResID != 0) { 5387c761d8b0086f9e92eb1e4b3a5683ae6afb84036aMårten Kongstad overlayResID = pkg_id | (0x00ffffff & overlayResID); 5388249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad last = Res_GETENTRY(resID); 5389249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (first == -1) { 5390249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad first = Res_GETENTRY(resID); 5391249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad } 539257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 539357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad vector.push(overlayResID); 539457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#if 0 539557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (overlayResID != 0) { 53965baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("%s/%s 0x%08x -> 0x%08x\n", 539757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad String8(String16(resName.type)).string(), 539857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad String8(String16(resName.name)).string(), 539957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad resID, overlayResID); 540057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 540157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad#endif 540257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 540357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 5404249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (first != -1) { 5405249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // shave off trailing entries which lack overlay values 5406249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad const size_t last_past_one = last + 1; 5407249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (last_past_one < vector.size()) { 5408249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.removeItemsAt(last_past_one, vector.size() - last_past_one); 540957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 5410249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // shave off leading entries which lack overlay values 5411249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.removeItemsAt(0, first); 5412249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad // store offset to first overlaid resource ID of this type 5413249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad vector.insertAt((uint32_t)first, 0, 1); 541457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // reserve space for number and offset of entries, and the actual entries 541557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize += (2 + vector.size()) * sizeof(uint32_t); 541657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 541757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // no entries of current type defined in overlay package 541857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad vector.clear(); 541957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad // reserve space for type offset 542057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *outSize += 1 * sizeof(uint32_t); 542157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 542257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 542357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 542457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if ((*outData = malloc(*outSize)) == NULL) { 542557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_MEMORY; 542657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 542757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* data = (uint32_t*)*outData; 542857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(IDMAP_MAGIC); 542957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(originalCrc); 543057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(overlayCrc); 543157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t mapSize = map.size(); 543257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(mapSize); 543357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad size_t offset = mapSize; 543457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t i = 0; i < mapSize; ++i) { 543557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Vector<uint32_t>& vector = map.itemAt(i); 543657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t N = vector.size(); 543757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (N == 0) { 543857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(0); 543957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } else { 544057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad offset++; 544157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(offset); 544257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad offset += N; 544357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 544457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 544557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t i = 0; i < mapSize; ++i) { 544657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const Vector<uint32_t>& vector = map.itemAt(i); 544757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const size_t N = vector.size(); 544857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (N == 0) { 544957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad continue; 545057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 5451249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad if (N == 1) { // vector expected to hold (offset) + (N > 0 entries) 5452249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i); 5453249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad return UNKNOWN_ERROR; 5454249e3ed5400e5c7ab2e9aa8017f612d79d2e8089Mårten Kongstad } 545557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(N - 1); // do not count the offset (which is vector's first element) 545657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad for (size_t j = 0; j < N; ++j) { 545757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t& overlayResID = vector.itemAt(j); 545857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *data++ = htodl(overlayResID); 545957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 546057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 546157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 546257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return NO_ERROR; 546357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 546457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 546557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstadbool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes, 546657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad uint32_t* pOriginalCrc, uint32_t* pOverlayCrc) 546757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad{ 546857f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad const uint32_t* map = (const uint32_t*)idmap; 546957f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad if (!assertIdmapHeader(map, sizeBytes)) { 547057f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return false; 547157f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad } 547257f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *pOriginalCrc = map[1]; 547357f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad *pOverlayCrc = map[2]; 547457f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad return true; 547557f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad} 547657f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 547757f4b77c89bafedf9468f9a636561c0c193405c9Mårten Kongstad 54789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string()) 54799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define CHAR16_ARRAY_EQ(constant, var, len) \ 54819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len)))) 54829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54839d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brownstatic void print_complex(uint32_t complex, bool isFraction) 5484e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn{ 5485e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const float MANTISSA_MULT = 5486e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT); 5487e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn const float RADIX_MULTS[] = { 5488e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT, 5489e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT 5490e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn }; 5491e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5492e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK 5493e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn <<Res_value::COMPLEX_MANTISSA_SHIFT)) 5494e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT) 5495e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn & Res_value::COMPLEX_RADIX_MASK]; 5496e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("%f", value); 5497e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5498de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (!isFraction) { 5499e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) { 5500e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_PX: printf("px"); break; 5501e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break; 5502e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_SP: printf("sp"); break; 5503e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_PT: printf("pt"); break; 5504e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_IN: printf("in"); break; 5505e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_MM: printf("mm"); break; 5506e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn default: printf(" (unknown unit)"); break; 5507e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5508e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } else { 5509e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) { 5510e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break; 5511e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break; 5512e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn default: printf(" (unknown unit)"); break; 5513e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5514e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5515e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn} 5516e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 55179872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh// Normalize a string for output 55189872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar ShemeshString8 ResTable::normalizeForOutput( const char *input ) 55199872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh{ 55209872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh String8 ret; 55219872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh char buff[2]; 55229872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh buff[1] = '\0'; 55239872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 55249872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh while (*input != '\0') { 55259872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh switch (*input) { 55269872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh // All interesting characters are in the ASCII zone, so we are making our own lives 55279872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh // easier by scanning the string one byte at a time. 55289872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '\\': 55299872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\\\"; 55309872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 55319872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '\n': 55329872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\n"; 55339872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 55349872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh case '"': 55359872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += "\\\""; 55369872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 55379872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh default: 55389872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh buff[0] = *input; 55399872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh ret += buff; 55409872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh break; 55419872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh } 55429872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 55439872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh input++; 55449872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh } 55459872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 55469872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh return ret; 55479872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh} 55489872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh 5549de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornvoid ResTable::print_value(const Package* pkg, const Res_value& value) const 5550de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn{ 5551de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (value.dataType == Res_value::TYPE_NULL) { 5552de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(null)\n"); 5553de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_REFERENCE) { 5554de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(reference) 0x%08x\n", value.data); 5555de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) { 5556de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(attribute) 0x%08x\n", value.data); 5557de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_STRING) { 5558de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn size_t len; 5559780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const char* str8 = pkg->header->values.string8At( 5560de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.data, &len); 5561780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (str8 != NULL) { 55629872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh printf("(string8) \"%s\"\n", normalizeForOutput(str8).string()); 5563de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else { 5564780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root const char16_t* str16 = pkg->header->values.stringAt( 5565780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root value.data, &len); 5566780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root if (str16 != NULL) { 5567780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root printf("(string16) \"%s\"\n", 55689872bf4a2d4ae1e7ded170c8e74d400fe6be9bfbShachar Shemesh normalizeForOutput(String8(str16, len).string()).string()); 5569780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } else { 5570780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root printf("(string) null\n"); 5571780d2a1b714724d85227141c76b3c64f543f00b4Kenny Root } 5572de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5573de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_FLOAT) { 5574de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(float) %g\n", *(const float*)&value.data); 5575de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_DIMENSION) { 5576de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(dimension) "); 5577de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_complex(value.data, false); 5578de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("\n"); 5579de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_FRACTION) { 5580de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(fraction) "); 5581de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_complex(value.data, true); 5582de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("\n"); 5583de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT 5584de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) { 5585de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(color) #%08x\n", value.data); 5586de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) { 5587de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(boolean) %s\n", value.data ? "true" : "false"); 5588de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (value.dataType >= Res_value::TYPE_FIRST_INT 5589de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn || value.dataType <= Res_value::TYPE_LAST_INT) { 5590de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(int) 0x%08x or %d\n", value.data, value.data); 5591de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else { 5592de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n", 5593de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.dataType, (int)value.data, 5594de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.size, (int)value.res0); 5595de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5596de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn} 5597de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 5598e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackbornvoid ResTable::print(bool inclValues) const 55999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5600e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn if (mError != 0) { 5601e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf("mError=0x%x (%s)\n", mError, strerror(mError)); 5602e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 56039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 56049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("mParams=%c%c-%c%c,\n", 56059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams.language[0], mParams.language[1], 56069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams.country[0], mParams.country[1]); 56079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 56089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t pgCount = mPackageGroups.size(); 56099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Package Groups (%d)\n", (int)pgCount); 56109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) { 56119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const PackageGroup* pg = mPackageGroups[pgIndex]; 56129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("Package Group %d id=%d packageCount=%d name=%s\n", 56139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)pgIndex, pg->id, (int)pg->packages.size(), 56149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8(pg->name).string()); 56159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t pkgCount = pg->packages.size(); 56179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) { 56189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Package* pkg = pg->packages[pkgIndex]; 56199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t typeCount = pkg->types.size(); 56209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex, 56219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pkg->package->id, String8(String16(pkg->package->name)).string(), 56229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)typeCount); 56239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) { 56249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Type* typeConfigs = pkg->getType(typeIndex); 56259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs == NULL) { 56269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" type %d NULL\n", (int)typeIndex); 56279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 56289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t NTC = typeConfigs->configs.size(); 56309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" type %d configCount=%d entryCount=%d\n", 56319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount); 56329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (typeConfigs->typeSpecFlags != NULL) { 56339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) { 56349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) 56359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x00ff0000 & ((typeIndex+1)<<16)) 56369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x0000ffff & (entryIndex)); 56379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name resName; 5638d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (this->getResourceName(resID, true, &resName)) { 5639d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 type8; 5640d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 name8; 5641d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (resName.type8 != NULL) { 5642d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8 = String8(resName.type8, resName.typeLen); 5643d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 5644d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8 = String8(resName.type, resName.typeLen); 5645d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 5646d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (resName.name8 != NULL) { 5647d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn name8 = String8(resName.name8, resName.nameLen); 5648d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 5649d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn name8 = String8(resName.name, resName.nameLen); 5650d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 56513379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" spec resource 0x%08x %s:%s/%s: flags=0x%08x\n", 56523379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root resID, 56533379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.package, resName.packageLen), 5654d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8.string(), name8.string(), 56553379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root dtohl(typeConfigs->typeSpecFlags[entryIndex])); 56563379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } else { 56573379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID); 56583379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 56599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t configIndex=0; configIndex<NTC; configIndex++) { 56629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_type* type = typeConfigs->configs[configIndex]; 56639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((((uint64_t)type)&0x3) != 0) { 56649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); 56659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 56669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn String8 configStr = type->config.toString(); 56686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn printf(" config %s:\n", configStr.size() > 0 56696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn ? configStr.string() : "(default)"); 56709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t entryCount = dtohl(type->entryCount); 56719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t entriesStart = dtohl(type->entriesStart); 56729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((entriesStart&0x3) != 0) { 56739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart); 56749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 56759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t typeSize = dtohl(type->header.size); 56779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((typeSize&0x3) != 0) { 56789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize); 56799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 56809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) { 56829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t* const end = ((const uint8_t*)type) 56849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dtohl(type->header.size); 56859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t* const eindex = (const uint32_t*) 56869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + dtohs(type->header.headerSize)); 56879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t thisOffset = dtohl(eindex[entryIndex]); 56899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thisOffset == ResTable_type::NO_ENTRY) { 56909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 56919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) 56949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x00ff0000 & ((typeIndex+1)<<16)) 56959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | (0x0000ffff & (entryIndex)); 56969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resource_name resName; 5697d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (this->getResourceName(resID, true, &resName)) { 5698d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 type8; 5699d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn String8 name8; 5700d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (resName.type8 != NULL) { 5701d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8 = String8(resName.type8, resName.typeLen); 5702d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 5703d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8 = String8(resName.type, resName.typeLen); 5704d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 5705d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn if (resName.name8 != NULL) { 5706d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn name8 = String8(resName.name8, resName.nameLen); 5707d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } else { 5708d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn name8 = String8(resName.name, resName.nameLen); 5709d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn } 57103379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" resource 0x%08x %s:%s/%s: ", resID, 57113379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root CHAR16_TO_CSTR(resName.package, resName.packageLen), 5712d45c68dd24fe3dd510af5a9591b5e2f509b56772Dianne Hackborn type8.string(), name8.string()); 57133379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } else { 57143379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root printf(" INVALID RESOURCE 0x%08x: ", resID); 57153379195a76fff85a13ffd3c443edeb8fde48b085Kenny Root } 57169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((thisOffset&0x3) != 0) { 57179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset); 57189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 57199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((thisOffset+sizeof(ResTable_entry)) > typeSize) { 57219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n", 57229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)entriesStart, (void*)thisOffset, 57239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)typeSize); 57249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 57259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ResTable_entry* ent = (const ResTable_entry*) 57289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)type) + entriesStart + thisOffset); 57299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((entriesStart + thisOffset)&0x3) != 0) { 57309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("NON-INTEGER ResTable_entry OFFSET: %p\n", 57319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)(entriesStart + thisOffset)); 57329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 57339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5734e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5735de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn uint16_t esize = dtohs(ent->size); 5736de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if ((esize&0x3) != 0) { 5737de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize); 5738de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn continue; 5739de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5740de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if ((thisOffset+esize) > typeSize) { 5741de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n", 5742de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (void*)entriesStart, (void*)thisOffset, 5743de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (void*)esize, (void*)typeSize); 5744de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn continue; 5745de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 5746de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 5747de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const Res_value* valuePtr = NULL; 5748de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const ResTable_map_entry* bagPtr = NULL; 5749de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn Res_value value; 57509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) { 57519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("<bag>"); 5752de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn bagPtr = (const ResTable_map_entry*)ent; 57539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5754de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn valuePtr = (const Res_value*) 57559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (((const uint8_t*)ent) + esize); 5756de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.copyFrom_dtoh(*valuePtr); 57579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)", 5758de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.dataType, (int)value.data, 5759de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn (int)value.size, (int)value.res0); 57609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) { 57639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf(" (PUBLIC)"); 57649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\n"); 5766e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn 5767e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn if (inclValues) { 5768de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (valuePtr != NULL) { 5769e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn printf(" "); 5770de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_value(pkg, value); 5771de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else if (bagPtr != NULL) { 5772de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const int N = dtohl(bagPtr->count); 577306983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root const uint8_t* baseMapPtr = (const uint8_t*)ent; 577406983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root size_t mapOffset = esize; 577506983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset); 5776de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf(" Parent=0x%08x, Count=%d\n", 5777de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn dtohl(bagPtr->parent.ident), N); 577806983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) { 5779de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn printf(" #%i (Key=0x%08x): ", 5780de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn i, dtohl(mapPtr->name.ident)); 5781de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn value.copyFrom_dtoh(mapPtr->value); 5782de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn print_value(pkg, value); 5783de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn const size_t size = dtohs(mapPtr->value.size); 578406983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value); 578506983bc566eca6dc3ef477baaa1520bfa95cee52Kenny Root mapPtr = (ResTable_map*)(baseMapPtr+mapOffset); 5786e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5787e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 5788e17086ba346009a26cc2299b133a0fe602acb6ecDianne Hackborn } 57899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 57959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace android 5797