/* (documented in header file) */ const char* dexProtoGetParameterDescriptors(const DexProto* pProto, DexStringCache* pCache) { DexParameterIterator iterator; size_t length = 1; /* +1 for the terminating '\0' */ dexParameterIteratorInit(&iterator, pProto); for (;;) { const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); if (descriptor == NULL) { break; } length += strlen(descriptor); } dexParameterIteratorInit(&iterator, pProto); dexStringCacheAlloc(pCache, length); char *at = (char*) pCache->value; for (;;) { const char* descriptor = dexParameterIteratorNextDescriptor(&iterator); if (descriptor == NULL) { break; } strcpy(at, descriptor); at += strlen(descriptor); } return pCache->value; }
/* * 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) { if (value != pCache->value) { size_t length = strlen(value) + 1; dexStringCacheAlloc(pCache, length); memcpy(pCache->value, value, length); } return pCache->value; }
/* * Fills targetDescriptorCache with the descriptors of the classes in args. * This is the concatenation of the descriptors with no other adornment, * consistent with dexProtoGetParameterDescriptors. */ static void createTargetDescriptor(ArrayObject* args, DexStringCache* targetDescriptorCache) { ClassObject** argsArray = (ClassObject**)(void*)args->contents; size_t length = 1; /* +1 for the terminating '\0' */ for (size_t i = 0; i < args->length; ++i) { length += strlen(argsArray[i]->descriptor); } dexStringCacheAlloc(targetDescriptorCache, length); char* at = (char*) targetDescriptorCache->value; for (size_t i = 0; i < args->length; ++i) { const char* descriptor = argsArray[i]->descriptor; strcpy(at, descriptor); at += strlen(descriptor); } }
/* (documented in header file) */ const char* dexProtoGetMethodDescriptor(const DexProto* pProto, DexStringCache* pCache) { const DexFile* dexFile = pProto->dexFile; #ifdef FASTIVA if (FASTIVA_IS_FASTIVA_PROTO(pProto)) { //const fastiva_MethodInfo* pMethod = (const fastiva_MethodInfo*)pProto->protoIdx; int args = FASTIVA_ARG_LIST_ID(pProto); int ret_t = FASTIVA_RET_TTYPE_ID(pProto); char buff[1024]; char* dst = buff; *dst ++ = '('; JNI_ArgIterator it; const char* sig; for (int i = it.init(args); --i >= -1; ) { if (i < 0) { *dst++ = ')'; sig = d2f_getTypeDescriptor(ret_t); } else { sig = d2f_getTypeDescriptor(it.nextID()); } int len = strlen(sig); memcpy(dst, sig, len); dst += len; } *dst++ = 0; int len = dst - buff; dexStringCacheAlloc(pCache, len); char *at = (char*) pCache->value; memcpy(at, buff, len); return pCache->value; } #endif const DexProtoId* protoId = getProtoId(pProto); const DexTypeList* typeList = dexGetProtoParameters(dexFile, protoId); size_t length = 3; // parens and terminating '\0' u4 paramCount = (typeList == NULL) ? 0 : typeList->size; u4 i; for (i = 0; i < paramCount; i++) { u4 idx = dexTypeListGetIdx(typeList, i); length += strlen(dexStringByTypeIdx(dexFile, idx)); } length += strlen(dexStringByTypeIdx(dexFile, protoId->returnTypeIdx)); dexStringCacheAlloc(pCache, length); char *at = (char*) pCache->value; *(at++) = '('; for (i = 0; i < paramCount; i++) { u4 idx = dexTypeListGetIdx(typeList, i); const char* desc = dexStringByTypeIdx(dexFile, idx); strcpy(at, desc); at += strlen(desc); } *(at++) = ')'; strcpy(at, dexStringByTypeIdx(dexFile, protoId->returnTypeIdx)); return pCache->value; }