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