| /* |
| * 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 |
| #define _LIBDEX_DEXPROTO |
| |
| #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. |
| */ |
| typedef 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 */ |
| } DexStringCache; |
| |
| /* |
| * 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. |
| */ |
| typedef struct DexProto { |
| const DexFile* dexFile; /* file the idx refers to */ |
| u4 protoIdx; /* index into proto_ids table of dexFile */ |
| } DexProto; |
| |
| /* |
| * 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. 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); |
| |
| /* |
| * Single-thread prototype parameter iterator. This structure holds a |
| * pointer to a prototype and its parts, along with a cursor. |
| */ |
| typedef struct DexParameterIterator { |
| const DexProto* proto; |
| const DexTypeList* parameters; |
| int parameterCount; |
| int cursor; |
| } DexParameterIterator; |
| |
| /* |
| * 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*/ |