You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
7.4 KiB
229 lines
7.4 KiB
/* |
|
* Copyright (C) 2008 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
/* |
|
* Functions for dealing with method prototypes |
|
*/ |
|
|
|
#ifndef LIBDEX_DEXPROTO_H_ |
|
#define LIBDEX_DEXPROTO_H_ |
|
|
|
#include "DexFile.h" |
|
|
|
/* |
|
* Single-thread single-string cache. This structure holds a pointer to |
|
* a string which is semi-automatically manipulated by some of the |
|
* method prototype functions. Functions which use in this struct |
|
* generally return a string that is valid until the next |
|
* time the same DexStringCache is used. |
|
*/ |
|
struct DexStringCache { |
|
char* value; /* the latest value */ |
|
size_t allocatedSize; /* size of the allocated buffer, if allocated */ |
|
char buffer[120]; /* buffer used to hold small-enough results */ |
|
}; |
|
|
|
/* |
|
* Make sure that the given cache can hold a string of the given length, |
|
* including the final '\0' byte. |
|
*/ |
|
void dexStringCacheAlloc(DexStringCache* pCache, size_t length); |
|
|
|
/* |
|
* Initialize the given DexStringCache. Use this function before passing |
|
* one into any other function. |
|
*/ |
|
void dexStringCacheInit(DexStringCache* pCache); |
|
|
|
/* |
|
* Release the allocated contents of the given DexStringCache, if any. |
|
* Use this function after your last use of a DexStringCache. |
|
*/ |
|
void dexStringCacheRelease(DexStringCache* pCache); |
|
|
|
/* |
|
* If the given DexStringCache doesn't already point at the given value, |
|
* make a copy of it into the cache. This always returns a writable |
|
* pointer to the contents (whether or not a copy had to be made). This |
|
* function is intended to be used after making a call that at least |
|
* sometimes doesn't populate a DexStringCache. |
|
*/ |
|
char* dexStringCacheEnsureCopy(DexStringCache* pCache, const char* value); |
|
|
|
/* |
|
* Abandon the given DexStringCache, and return a writable copy of the |
|
* given value (reusing the string cache's allocation if possible). |
|
* The return value must be free()d by the caller. Use this instead of |
|
* dexStringCacheRelease() if you want the buffer to survive past the |
|
* scope of the DexStringCache. |
|
*/ |
|
char* dexStringCacheAbandon(DexStringCache* pCache, const char* value); |
|
|
|
/* |
|
* Method prototype structure, which refers to a protoIdx in a |
|
* particular DexFile. |
|
*/ |
|
struct DexProto { |
|
const DexFile* dexFile; /* file the idx refers to */ |
|
u4 protoIdx; /* index into proto_ids table of dexFile */ |
|
}; |
|
|
|
/* |
|
* Set the given DexProto to refer to the prototype of the given MethodId. |
|
*/ |
|
DEX_INLINE void dexProtoSetFromMethodId(DexProto* pProto, |
|
const DexFile* pDexFile, const DexMethodId* pMethodId) |
|
{ |
|
pProto->dexFile = pDexFile; |
|
pProto->protoIdx = pMethodId->protoIdx; |
|
} |
|
|
|
/* |
|
* Get the short-form method descriptor for the given prototype. The |
|
* prototype must be protoIdx-based. |
|
*/ |
|
const char* dexProtoGetShorty(const DexProto* pProto); |
|
|
|
/* |
|
* Get the full method descriptor for the given prototype. |
|
*/ |
|
const char* dexProtoGetMethodDescriptor(const DexProto* pProto, |
|
DexStringCache* pCache); |
|
|
|
/* |
|
* Get a copy of the descriptor string associated with the given prototype. |
|
* The returned pointer must be free()ed by the caller. |
|
*/ |
|
char* dexProtoCopyMethodDescriptor(const DexProto* pProto); |
|
|
|
/* |
|
* Get the parameter descriptors for the given prototype. This is the |
|
* concatenation of all the descriptors for all the parameters, in |
|
* order, with no other adornment. |
|
*/ |
|
const char* dexProtoGetParameterDescriptors(const DexProto* pProto, |
|
DexStringCache* pCache); |
|
|
|
/* |
|
* Return the utf-8 encoded descriptor string from the proto of a MethodId. |
|
*/ |
|
DEX_INLINE const char* dexGetDescriptorFromMethodId(const DexFile* pDexFile, |
|
const DexMethodId* pMethodId, DexStringCache* pCache) |
|
{ |
|
DexProto proto; |
|
|
|
dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); |
|
return dexProtoGetMethodDescriptor(&proto, pCache); |
|
} |
|
|
|
/* |
|
* Get a copy of the utf-8 encoded method descriptor string from the |
|
* proto of a MethodId. The returned pointer must be free()ed by the |
|
* caller. |
|
*/ |
|
DEX_INLINE char* dexCopyDescriptorFromMethodId(const DexFile* pDexFile, |
|
const DexMethodId* pMethodId) |
|
{ |
|
DexProto proto; |
|
|
|
dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); |
|
return dexProtoCopyMethodDescriptor(&proto); |
|
} |
|
|
|
/* |
|
* Get the type descriptor for the return type of the given prototype. |
|
*/ |
|
const char* dexProtoGetReturnType(const DexProto* pProto); |
|
|
|
/* |
|
* Get the parameter count of the given prototype. |
|
*/ |
|
size_t dexProtoGetParameterCount(const DexProto* pProto); |
|
|
|
/* |
|
* Compute the number of parameter words (u4 units) required by the |
|
* given prototype. For example, if the method takes (int, long) and |
|
* returns double, this would return 3 (one for the int, two for the |
|
* long, and the return type isn't relevant). |
|
*/ |
|
int dexProtoComputeArgsSize(const DexProto* pProto); |
|
|
|
/* |
|
* Compare the two prototypes. The two prototypes are compared |
|
* with the return type as the major order, then the first arguments, |
|
* then second, etc. If two prototypes are identical except that one |
|
* has extra arguments, then the shorter argument is considered the |
|
* earlier one in sort order (similar to strcmp()). |
|
*/ |
|
int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2); |
|
|
|
/* |
|
* Compare the two prototypes, ignoring return type. The two |
|
* prototypes are compared with the first argument as the major order, |
|
* then second, etc. If two prototypes are identical except that one |
|
* has extra arguments, then the shorter argument is considered the |
|
* earlier one in sort order (similar to strcmp()). |
|
*/ |
|
int dexProtoCompareParameters(const DexProto* pProto1, |
|
const DexProto* pProto2); |
|
|
|
/* |
|
* Compare a prototype and a string method descriptor. The comparison |
|
* is done as if the descriptor were converted to a prototype and compared |
|
* with dexProtoCompare(). |
|
*/ |
|
int dexProtoCompareToDescriptor(const DexProto* proto, const char* descriptor); |
|
|
|
/* |
|
* Compare a prototype and a concatenation of type descriptors. The |
|
* comparison is done as if the descriptors were converted to a |
|
* prototype and compared with dexProtoCompareParameters(). |
|
*/ |
|
int dexProtoCompareToParameterDescriptors(const DexProto* proto, |
|
const char* descriptors); |
|
|
|
/* |
|
* Single-thread prototype parameter iterator. This structure holds a |
|
* pointer to a prototype and its parts, along with a cursor. |
|
*/ |
|
struct DexParameterIterator { |
|
const DexProto* proto; |
|
const DexTypeList* parameters; |
|
int parameterCount; |
|
int cursor; |
|
}; |
|
|
|
/* |
|
* Initialize the given DexParameterIterator to be at the start of the |
|
* parameters of the given prototype. |
|
*/ |
|
void dexParameterIteratorInit(DexParameterIterator* pIterator, |
|
const DexProto* pProto); |
|
|
|
/* |
|
* Get the type_id index for the next parameter, if any. This returns |
|
* kDexNoIndex if the last parameter has already been consumed. |
|
*/ |
|
u4 dexParameterIteratorNextIndex(DexParameterIterator* pIterator); |
|
|
|
/* |
|
* Get the type descriptor for the next parameter, if any. This returns |
|
* NULL if the last parameter has already been consumed. |
|
*/ |
|
const char* dexParameterIteratorNextDescriptor( |
|
DexParameterIterator* pIterator); |
|
|
|
#endif // LIBDEX_DEXPROTO_H_
|
|
|