Home | History | Annotate | Download | only in libdex
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * Functions for dealing with method prototypes
     19  */
     20 
     21 #ifndef LIBDEX_DEXPROTO_H_
     22 #define LIBDEX_DEXPROTO_H_
     23 
     24 #include "DexFile.h"
     25 
     26 /*
     27  * Single-thread single-string cache. This structure holds a pointer to
     28  * a string which is semi-automatically manipulated by some of the
     29  * method prototype functions. Functions which use in this struct
     30  * generally return a string that is valid until the next
     31  * time the same DexStringCache is used.
     32  */
     33 struct DexStringCache {
     34     char* value;          /* the latest value */
     35     size_t allocatedSize; /* size of the allocated buffer, if allocated */
     36     char buffer[120];     /* buffer used to hold small-enough results */
     37 };
     38 
     39 /*
     40  * Make sure that the given cache can hold a string of the given length,
     41  * including the final '\0' byte.
     42  */
     43 void dexStringCacheAlloc(DexStringCache* pCache, size_t length);
     44 
     45 /*
     46  * Initialize the given DexStringCache. Use this function before passing
     47  * one into any other function.
     48  */
     49 void dexStringCacheInit(DexStringCache* pCache);
     50 
     51 /*
     52  * Release the allocated contents of the given DexStringCache, if any.
     53  * Use this function after your last use of a DexStringCache.
     54  */
     55 void dexStringCacheRelease(DexStringCache* pCache);
     56 
     57 /*
     58  * If the given DexStringCache doesn't already point at the given value,
     59  * make a copy of it into the cache. This always returns a writable
     60  * pointer to the contents (whether or not a copy had to be made). This
     61  * function is intended to be used after making a call that at least
     62  * sometimes doesn't populate a DexStringCache.
     63  */
     64 char* dexStringCacheEnsureCopy(DexStringCache* pCache, const char* value);
     65 
     66 /*
     67  * Abandon the given DexStringCache, and return a writable copy of the
     68  * given value (reusing the string cache's allocation if possible).
     69  * The return value must be free()d by the caller. Use this instead of
     70  * dexStringCacheRelease() if you want the buffer to survive past the
     71  * scope of the DexStringCache.
     72  */
     73 char* dexStringCacheAbandon(DexStringCache* pCache, const char* value);
     74 
     75 /*
     76  * Method prototype structure, which refers to a protoIdx in a
     77  * particular DexFile.
     78  */
     79 struct DexProto {
     80     const DexFile* dexFile;     /* file the idx refers to */
     81     u4 protoIdx;                /* index into proto_ids table of dexFile */
     82 };
     83 
     84 /*
     85  * Set the given DexProto to refer to the prototype of the given MethodId.
     86  */
     87 DEX_INLINE void dexProtoSetFromMethodId(DexProto* pProto,
     88     const DexFile* pDexFile, const DexMethodId* pMethodId)
     89 {
     90     pProto->dexFile = pDexFile;
     91     pProto->protoIdx = pMethodId->protoIdx;
     92 }
     93 
     94 /*
     95  * Get the short-form method descriptor for the given prototype. The
     96  * prototype must be protoIdx-based.
     97  */
     98 const char* dexProtoGetShorty(const DexProto* pProto);
     99 
    100 /*
    101  * Get the full method descriptor for the given prototype.
    102  */
    103 const char* dexProtoGetMethodDescriptor(const DexProto* pProto,
    104     DexStringCache* pCache);
    105 
    106 /*
    107  * Get a copy of the descriptor string associated with the given prototype.
    108  * The returned pointer must be free()ed by the caller.
    109  */
    110 char* dexProtoCopyMethodDescriptor(const DexProto* pProto);
    111 
    112 /*
    113  * Get the parameter descriptors for the given prototype. This is the
    114  * concatenation of all the descriptors for all the parameters, in
    115  * order, with no other adornment.
    116  */
    117 const char* dexProtoGetParameterDescriptors(const DexProto* pProto,
    118     DexStringCache* pCache);
    119 
    120 /*
    121  * Return the utf-8 encoded descriptor string from the proto of a MethodId.
    122  */
    123 DEX_INLINE const char* dexGetDescriptorFromMethodId(const DexFile* pDexFile,
    124         const DexMethodId* pMethodId, DexStringCache* pCache)
    125 {
    126     DexProto proto;
    127 
    128     dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
    129     return dexProtoGetMethodDescriptor(&proto, pCache);
    130 }
    131 
    132 /*
    133  * Get a copy of the utf-8 encoded method descriptor string from the
    134  * proto of a MethodId. The returned pointer must be free()ed by the
    135  * caller.
    136  */
    137 DEX_INLINE char* dexCopyDescriptorFromMethodId(const DexFile* pDexFile,
    138     const DexMethodId* pMethodId)
    139 {
    140     DexProto proto;
    141 
    142     dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
    143     return dexProtoCopyMethodDescriptor(&proto);
    144 }
    145 
    146 /*
    147  * Get the type descriptor for the return type of the given prototype.
    148  */
    149 const char* dexProtoGetReturnType(const DexProto* pProto);
    150 
    151 /*
    152  * Get the parameter count of the given prototype.
    153  */
    154 size_t dexProtoGetParameterCount(const DexProto* pProto);
    155 
    156 /*
    157  * Compute the number of parameter words (u4 units) required by the
    158  * given prototype. For example, if the method takes (int, long) and
    159  * returns double, this would return 3 (one for the int, two for the
    160  * long, and the return type isn't relevant).
    161  */
    162 int dexProtoComputeArgsSize(const DexProto* pProto);
    163 
    164 /*
    165  * Compare the two prototypes. The two prototypes are compared
    166  * with the return type as the major order, then the first arguments,
    167  * then second, etc. If two prototypes are identical except that one
    168  * has extra arguments, then the shorter argument is considered the
    169  * earlier one in sort order (similar to strcmp()).
    170  */
    171 int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2);
    172 
    173 /*
    174  * Compare the two prototypes, ignoring return type. The two
    175  * prototypes are compared with the first argument as the major order,
    176  * then second, etc. If two prototypes are identical except that one
    177  * has extra arguments, then the shorter argument is considered the
    178  * earlier one in sort order (similar to strcmp()).
    179  */
    180 int dexProtoCompareParameters(const DexProto* pProto1,
    181         const DexProto* pProto2);
    182 
    183 /*
    184  * Compare a prototype and a string method descriptor. The comparison
    185  * is done as if the descriptor were converted to a prototype and compared
    186  * with dexProtoCompare().
    187  */
    188 int dexProtoCompareToDescriptor(const DexProto* proto, const char* descriptor);
    189 
    190 /*
    191  * Compare a prototype and a concatenation of type descriptors. The
    192  * comparison is done as if the descriptors were converted to a
    193  * prototype and compared with dexProtoCompareParameters().
    194  */
    195 int dexProtoCompareToParameterDescriptors(const DexProto* proto,
    196         const char* descriptors);
    197 
    198 /*
    199  * Single-thread prototype parameter iterator. This structure holds a
    200  * pointer to a prototype and its parts, along with a cursor.
    201  */
    202 struct DexParameterIterator {
    203     const DexProto* proto;
    204     const DexTypeList* parameters;
    205     int parameterCount;
    206     int cursor;
    207 };
    208 
    209 /*
    210  * Initialize the given DexParameterIterator to be at the start of the
    211  * parameters of the given prototype.
    212  */
    213 void dexParameterIteratorInit(DexParameterIterator* pIterator,
    214         const DexProto* pProto);
    215 
    216 /*
    217  * Get the type_id index for the next parameter, if any. This returns
    218  * kDexNoIndex if the last parameter has already been consumed.
    219  */
    220 u4 dexParameterIteratorNextIndex(DexParameterIterator* pIterator);
    221 
    222 /*
    223  * Get the type descriptor for the next parameter, if any. This returns
    224  * NULL if the last parameter has already been consumed.
    225  */
    226 const char* dexParameterIteratorNextDescriptor(
    227         DexParameterIterator* pIterator);
    228 
    229 #endif  // LIBDEX_DEXPROTO_H_
    230