1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Functions for dealing with method prototypes 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "DexProto.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * String Cache 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure that the given cache can hold a string of the given length, 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * including the final '\0' byte. 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 363c6f4c012e0a314dc9f9f540b9374dbf530d03b0Jesse Wilsonvoid dexStringCacheAlloc(DexStringCache* pCache, size_t length) { 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCache->allocatedSize != 0) { 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCache->allocatedSize >= length) { 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free((void*) pCache->value); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length <= sizeof(pCache->buffer)) { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->value = pCache->buffer; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->allocatedSize = 0; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 48a70a3d8faa8f7332549fa0c9ae2008d428e28606Dan Bornstein pCache->value = (char*) malloc(length); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->allocatedSize = length; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the given DexStringCache. Use this function before passing 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one into any other function. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dexStringCacheInit(DexStringCache* pCache) { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->value = pCache->buffer; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->allocatedSize = 0; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->buffer[0] = '\0'; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release the allocated contents of the given DexStringCache, if any. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use this function after your last use of a DexStringCache. 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dexStringCacheRelease(DexStringCache* pCache) { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCache->allocatedSize != 0) { 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free((void*) pCache->value); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->value = pCache->buffer; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->allocatedSize = 0; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the given DexStringCache doesn't already point at the given value, 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * make a copy of it into the cache. This always returns a writable 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pointer to the contents (whether or not a copy had to be made). This 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function is intended to be used after making a call that at least 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sometimes doesn't populate a DexStringCache. 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dexStringCacheEnsureCopy(DexStringCache* pCache, const char* value) { 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (value != pCache->value) { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = strlen(value) + 1; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheAlloc(pCache, length); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(pCache->value, value, length); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pCache->value; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Abandon the given DexStringCache, and return a writable copy of the 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given value (reusing the string cache's allocation if possible). 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The return value must be free()d by the caller. Use this instead of 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dexStringCacheRelease() if you want the buffer to survive past the 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * scope of the DexStringCache. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dexStringCacheAbandon(DexStringCache* pCache, const char* value) { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((value == pCache->value) && (pCache->allocatedSize != 0)) { 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* result = pCache->value; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->allocatedSize = 0; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCache->value = pCache->buffer; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strdup(value); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Method Prototypes 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the DexProtoId from the given DexProto. The DexProto must 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * actually refer to a DexProtoId. 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline const DexProtoId* getProtoId(const DexProto* pProto) { 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexGetProtoId(pProto->dexFile, pProto->protoIdx); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 12575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dexProtoGetShorty(const DexProto* pProto) { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId = getProtoId(pProto); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexStringById(pProto->dexFile, protoId->shortyIdx); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 13275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dexProtoGetMethodDescriptor(const DexProto* pProto, 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexStringCache* pCache) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* dexFile = pProto->dexFile; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId = getProtoId(pProto); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexTypeList* typeList = dexGetProtoParameters(dexFile, protoId); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = 3; // parens and terminating '\0' 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 paramCount = (typeList == NULL) ? 0 : typeList->size; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 i; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < paramCount; i++) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx = dexTypeListGetIdx(typeList, i); 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += strlen(dexStringByTypeIdx(dexFile, idx)); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += strlen(dexStringByTypeIdx(dexFile, protoId->returnTypeIdx)); 148de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheAlloc(pCache, length); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *at = (char*) pCache->value; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(at++) = '('; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < paramCount; i++) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx = dexTypeListGetIdx(typeList, i); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* desc = dexStringByTypeIdx(dexFile, idx); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcpy(at, desc); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at += strlen(desc); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *(at++) = ')'; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcpy(at, dexStringByTypeIdx(dexFile, protoId->returnTypeIdx)); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pCache->value; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 16775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dexProtoCopyMethodDescriptor(const DexProto* pProto) { 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexStringCache cache; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheInit(&cache); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexStringCacheAbandon(&cache, 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexProtoGetMethodDescriptor(pProto, &cache)); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dexProtoGetParameterDescriptors(const DexProto* pProto, 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexStringCache* pCache) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexParameterIterator iterator; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length = 1; /* +1 for the terminating '\0' */ 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexParameterIteratorInit(&iterator, pProto); 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += strlen(descriptor); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexParameterIteratorInit(&iterator, pProto); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringCacheAlloc(pCache, length); 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *at = (char*) pCache->value; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (descriptor == NULL) { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcpy(at, descriptor); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at += strlen(descriptor); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pCache->value; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21175144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dexProtoGetReturnType(const DexProto* pProto) { 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId = getProtoId(pProto); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexStringByTypeIdx(pProto->dexFile, protoId->returnTypeIdx); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsize_t dexProtoGetParameterCount(const DexProto* pProto) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId = getProtoId(pProto); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexTypeList* typeList = 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexGetProtoParameters(pProto->dexFile, protoId); 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (typeList == NULL) ? 0 : typeList->size; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dexProtoComputeArgsSize(const DexProto* pProto) { 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* shorty = dexProtoGetShorty(pProto); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = 0; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip the return type. */ 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shorty++; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*(shorty++)) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\0': { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return count; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count += 2; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Common implementation for dexProtoCompare() and dexProtoCompareParameters(). 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int protoCompare(const DexProto* pProto1, const DexProto* pProto2, 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool compareReturnType) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pProto1 == pProto2) { 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* dexFile1 = pProto1->dexFile; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId1 = getProtoId(pProto1); 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexTypeList* typeList1 = 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexGetProtoParameters(dexFile1, protoId1); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int paramCount1 = (typeList1 == NULL) ? 0 : typeList1->size; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexFile* dexFile2 = pProto2->dexFile; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProtoId* protoId2 = getProtoId(pProto2); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexTypeList* typeList2 = 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexGetProtoParameters(dexFile2, protoId2); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int paramCount2 = (typeList2 == NULL) ? 0 : typeList2->size; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (protoId1 == protoId2) { 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Another easy out. 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Compare return types. 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (compareReturnType) { 281de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro int result = 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcmp(dexStringByTypeIdx(dexFile1, protoId1->returnTypeIdx), 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(dexFile2, protoId2->returnTypeIdx)); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != 0) { 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Compare parameters. 291de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int minParam = (paramCount1 > paramCount2) ? paramCount2 : paramCount1; 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < minParam; i++) { 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx1 = dexTypeListGetIdx(typeList1, i); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx2 = dexTypeListGetIdx(typeList2, i); 298de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro int result = 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strcmp(dexStringByTypeIdx(dexFile1, idx1), 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexStringByTypeIdx(dexFile2, idx2)); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != 0) { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (paramCount1 < paramCount2) { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (paramCount1 > paramCount2) { 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2) { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return protoCompare(pProto1, pProto2, true); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dexProtoCompareParameters(const DexProto* pProto1, const DexProto* pProto2){ 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return protoCompare(pProto1, pProto2, false); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for dexProtoCompareToDescriptor(), which gets the return type 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor from a method descriptor string. 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* methodDescriptorReturnType(const char* descriptor) { 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* result = strchr(descriptor, ')'); 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == NULL) { 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 338de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The return type is the character just past the ')'. 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result + 1; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for dexProtoCompareToDescriptor(), which indicates the end 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of an embedded argument type descriptor, which is also the 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * beginning of the next argument type descriptor. Since this is for 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument types, it doesn't accept 'V' as a valid type descriptor. 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* methodDescriptorNextType(const char* descriptor) { 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Skip any array references. 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*descriptor == '[') { 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor++; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 355de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*descriptor) { 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': case 'C': case 'D': case 'F': 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': case 'J': case 'S': case 'Z': { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return descriptor + 1; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': { 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* result = strchr(descriptor + 1, ';'); 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result != NULL) { 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The type ends just past the ';'. 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result + 1; 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 37475144030732a492207f594ae6bf73f0308d6be6cDan Bornstein * Common implementation for dexProtoCompareToDescriptor() and 37575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein * dexProtoCompareToParameterDescriptors(). The descriptor argument 37675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein * can be either a full method descriptor (with parens and a return 37775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein * type) or an unadorned concatenation of types (e.g. a list of 37875144030732a492207f594ae6bf73f0308d6be6cDan Bornstein * argument types). 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 38075144030732a492207f594ae6bf73f0308d6be6cDan Bornsteinstatic int protoCompareToParameterDescriptors(const DexProto* proto, 38175144030732a492207f594ae6bf73f0308d6be6cDan Bornstein const char* descriptor, bool expectParens) { 38275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein char expectedEndChar = expectParens ? ')' : '\0'; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexParameterIterator iterator; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexParameterIteratorInit(&iterator, proto); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein if (expectParens) { 38775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein // Skip the '('. 38875144030732a492207f594ae6bf73f0308d6be6cDan Bornstein assert (*descriptor == '('); 38975144030732a492207f594ae6bf73f0308d6be6cDan Bornstein descriptor++; 39075144030732a492207f594ae6bf73f0308d6be6cDan Bornstein } 391de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* protoDesc = dexParameterIteratorNextDescriptor(&iterator); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein if (*descriptor == expectedEndChar) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It's the end of the descriptor string. 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (protoDesc == NULL) { 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It's also the end of the prototype's arguments. 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The prototype still has more arguments. 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (protoDesc == NULL) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The prototype doesn't have arguments left, but the 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor string does. 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Both prototype and descriptor have arguments. Compare them. 415de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* nextDesc = methodDescriptorNextType(descriptor); 41775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein assert(nextDesc != NULL); 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c1 = *(protoDesc++); 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c2 = (descriptor < nextDesc) ? *(descriptor++) : '\0'; 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c1 < c2) { 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This includes the case where the proto is shorter. 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (c1 > c2) { 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This includes the case where the desc is shorter. 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (c1 == '\0') { 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The two types are equal in length. (c2 necessarily == '\0'.) 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 434de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we made it here, the two arguments matched, and 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor == nextDesc. 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 44375144030732a492207f594ae6bf73f0308d6be6cDan Bornsteinint dexProtoCompareToDescriptor(const DexProto* proto, 44475144030732a492207f594ae6bf73f0308d6be6cDan Bornstein const char* descriptor) { 44575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein // First compare the return types. 44675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 44775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein const char *returnType = methodDescriptorReturnType(descriptor); 44875144030732a492207f594ae6bf73f0308d6be6cDan Bornstein assert(returnType != NULL); 44975144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 45075144030732a492207f594ae6bf73f0308d6be6cDan Bornstein int result = strcmp(dexProtoGetReturnType(proto), returnType); 45175144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 45275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein if (result != 0) { 45375144030732a492207f594ae6bf73f0308d6be6cDan Bornstein return result; 45475144030732a492207f594ae6bf73f0308d6be6cDan Bornstein } 45575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 45675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein // The return types match, so we have to check arguments. 45775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein return protoCompareToParameterDescriptors(proto, descriptor, true); 45875144030732a492207f594ae6bf73f0308d6be6cDan Bornstein} 45975144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 46075144030732a492207f594ae6bf73f0308d6be6cDan Bornstein/* (documented in header file) */ 46175144030732a492207f594ae6bf73f0308d6be6cDan Bornsteinint dexProtoCompareToParameterDescriptors(const DexProto* proto, 46275144030732a492207f594ae6bf73f0308d6be6cDan Bornstein const char* descriptors) { 46375144030732a492207f594ae6bf73f0308d6be6cDan Bornstein return protoCompareToParameterDescriptors(proto, descriptors, false); 46475144030732a492207f594ae6bf73f0308d6be6cDan Bornstein} 46575144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 46675144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 46775144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 46875144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 46975144030732a492207f594ae6bf73f0308d6be6cDan Bornstein 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parameter Iterators 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 475de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro */ 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize the given DexParameterIterator to be at the start of the 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * parameters of the given prototype. 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dexParameterIteratorInit(DexParameterIterator* pIterator, 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DexProto* pProto) { 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pIterator->proto = pProto; 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pIterator->cursor = 0; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pIterator->parameters = 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexGetProtoParameters(pProto->dexFile, getProtoId(pProto)); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pIterator->parameterCount = (pIterator->parameters == NULL) ? 0 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : pIterator->parameters->size; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type_id index for the next parameter, if any. This returns 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * kDexNoIndex if the last parameter has already been consumed. 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dexParameterIteratorNextIndex(DexParameterIterator* pIterator) { 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cursor = pIterator->cursor; 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parameterCount = pIterator->parameterCount; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cursor >= parameterCount) { 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The iteration is complete. 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kDexNoIndex; 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx = dexTypeListGetIdx(pIterator->parameters, cursor); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pIterator->cursor++; 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return idx; 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type descriptor for the next parameter, if any. This returns 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NULL if the last parameter has already been consumed. 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dexParameterIteratorNextDescriptor( 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexParameterIterator* pIterator) { 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 idx = dexParameterIteratorNextIndex(pIterator); 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idx == kDexNoIndex) { 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dexStringByTypeIdx(pIterator->proto->dexFile, idx); 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 524