/*
 * 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
 */

#include "DexProto.h"

#include <stdlib.h>
#include <string.h>

/*
 * ===========================================================================
 *      String Cache
 * ===========================================================================
 */

/*
 * Make sure that the given cache can hold a string of the given length,
 * including the final '\0' byte.
 */
static void dexStringCacheAlloc(DexStringCache* pCache, size_t length) {
    if (pCache->allocatedSize != 0) {
        if (pCache->allocatedSize >= length) {
            return;
        }
        free((void*) pCache->value);
    }

    if (length <= sizeof(pCache->buffer)) {
        pCache->value = pCache->buffer;
        pCache->allocatedSize = 0;
    } else {
        pCache->value = malloc(length);
        pCache->allocatedSize = length;
    }
}

/*
 * Initialize the given DexStringCache. Use this function before passing
 * one into any other function.
 */
void dexStringCacheInit(DexStringCache* pCache) {
    pCache->value = pCache->buffer;
    pCache->allocatedSize = 0;
    pCache->buffer[0] = '\0';
}

/*
 * 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 (pCache->allocatedSize != 0) {
        free((void*) pCache->value);
        pCache->value = pCache->buffer;
        pCache->allocatedSize = 0;
    }
}

/*
 * 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;
}

/*
 * 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) {
    if ((value == pCache->value) && (pCache->allocatedSize != 0)) {
        char* result = pCache->value;
        pCache->allocatedSize = 0;
        pCache->value = pCache->buffer;
        return result;
    } else {
        return strdup(value);
    }
}


/*
 * ===========================================================================
 *      Method Prototypes
 * ===========================================================================
 */

/*
 * Return the DexProtoId from the given DexProto. The DexProto must
 * actually refer to a DexProtoId.
 */
static inline const DexProtoId* getProtoId(const DexProto* pProto) {
    return dexGetProtoId(pProto->dexFile, pProto->protoIdx);
}

/*
 * Get the short-form method descriptor for the given prototype. The
 * prototype must be protoIdx-based.
 */
const char* dexProtoGetShorty(const DexProto* pProto) {
    const DexProtoId* protoId = getProtoId(pProto);

    return dexStringById(pProto->dexFile, protoId->shortyIdx);
}

/*
 * Get the full method descriptor for the given prototype.
 */
const char* dexProtoGetMethodDescriptor(const DexProto* pProto,
        DexStringCache* pCache) {
    const DexFile* dexFile = pProto->dexFile;
    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;
}

/*
 * 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) {
    DexStringCache cache;

    dexStringCacheInit(&cache);
    return dexStringCacheAbandon(&cache,
            dexProtoGetMethodDescriptor(pProto, &cache));
}

/*
 * 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) {
    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;
}

/*
 * Get the type descriptor for the return type of the given prototype.
 */
const char* dexProtoGetReturnType(const DexProto* pProto) {
    const DexProtoId* protoId = getProtoId(pProto);
    return dexStringByTypeIdx(pProto->dexFile, protoId->returnTypeIdx);
}

/*
 * Get the parameter count of the given prototype.
 */
size_t dexProtoGetParameterCount(const DexProto* pProto) {
    const DexProtoId* protoId = getProtoId(pProto);
    const DexTypeList* typeList =
        dexGetProtoParameters(pProto->dexFile, protoId);
    return (typeList == NULL) ? 0 : typeList->size;
}

/*
 * 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) {
    const char* shorty = dexProtoGetShorty(pProto);
    int count = 0;

    /* Skip the return type. */
    shorty++;

    for (;;) {
        switch (*(shorty++)) {
            case '\0': {
                return count;
            }
            case 'D':
            case 'J': {
                count += 2;
                break;
            }
            default: {
                count++;
                break;
            }
        }
    }
}

/*
 * Common implementation for dexProtoCompare() and dexProtoCompareParameters().
 */
static int protoCompare(const DexProto* pProto1, const DexProto* pProto2,
        bool compareReturnType) {

    if (pProto1 == pProto2) {
        // Easy out.
        return 0;
    } else {
        const DexFile* dexFile1 = pProto1->dexFile;
        const DexProtoId* protoId1 = getProtoId(pProto1);
        const DexTypeList* typeList1 =
            dexGetProtoParameters(dexFile1, protoId1);
        int paramCount1 = (typeList1 == NULL) ? 0 : typeList1->size;

        const DexFile* dexFile2 = pProto2->dexFile;
        const DexProtoId* protoId2 = getProtoId(pProto2);
        const DexTypeList* typeList2 =
            dexGetProtoParameters(dexFile2, protoId2);
        int paramCount2 = (typeList2 == NULL) ? 0 : typeList2->size;

        if (protoId1 == protoId2) {
            // Another easy out.
            return 0;
        }

        // Compare return types.

        if (compareReturnType) {
            int result =
                strcmp(dexStringByTypeIdx(dexFile1, protoId1->returnTypeIdx),
                        dexStringByTypeIdx(dexFile2, protoId2->returnTypeIdx));

            if (result != 0) {
                return result;
            }
        }

        // Compare parameters.

        int minParam = (paramCount1 > paramCount2) ? paramCount2 : paramCount1;
        int i;

        for (i = 0; i < minParam; i++) {
            u4 idx1 = dexTypeListGetIdx(typeList1, i);
            u4 idx2 = dexTypeListGetIdx(typeList2, i);
            int result =
                strcmp(dexStringByTypeIdx(dexFile1, idx1),
                        dexStringByTypeIdx(dexFile2, idx2));

            if (result != 0) {
                return result;
            }
        }

        if (paramCount1 < paramCount2) {
            return -1;
        } else if (paramCount1 > paramCount2) {
            return 1;
        } else {
            return 0;
        }
    }
}

/*
 * 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) {
    return protoCompare(pProto1, pProto2, true);
}

/*
 * 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){
    return protoCompare(pProto1, pProto2, false);
}


/*
 * Helper for dexProtoCompareToDescriptor(), which gets the return type
 * descriptor from a method descriptor string.
 */
static const char* methodDescriptorReturnType(const char* descriptor) {
    const char* result = strchr(descriptor, ')');

    if (result == NULL) {
        return NULL;
    }

    // The return type is the character just past the ')'.
    return result + 1;
}

/*
 * Helper for dexProtoCompareToDescriptor(), which indicates the end
 * of an embedded argument type descriptor, which is also the
 * beginning of the next argument type descriptor. Since this is for
 * argument types, it doesn't accept 'V' as a valid type descriptor.
 */
static const char* methodDescriptorNextType(const char* descriptor) {
    // Skip any array references.

    while (*descriptor == '[') {
        descriptor++;
    }

    switch (*descriptor) {
        case 'B': case 'C': case 'D': case 'F':
        case 'I': case 'J': case 'S': case 'Z': {
            return descriptor + 1;
        }
        case 'L': {
            const char* result = strchr(descriptor + 1, ';');
            if (result != NULL) {
                // The type ends just past the ';'.
                return result + 1;
            }
        }
    }

    return NULL;
}

/*
 * 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) {
    // First compare the return types.

    int result = strcmp(dexProtoGetReturnType(proto),
            methodDescriptorReturnType(descriptor));

    if (result != 0) {
        return result;
    }

    // The return types match, so we have to check arguments.

    DexParameterIterator iterator;
    dexParameterIteratorInit(&iterator, proto);

    // Skip the '('.
    assert (*descriptor == '(');
    descriptor++;

    for (;;) {
        const char* protoDesc = dexParameterIteratorNextDescriptor(&iterator);

        if (*descriptor == ')') {
            // It's the end of the descriptor string.
            if (protoDesc == NULL) {
                // It's also the end of the prototype's arguments.
                return 0;
            } else {
                // The prototype still has more arguments.
                return 1;
            }
        }

        if (protoDesc == NULL) {
            /*
             * The prototype doesn't have arguments left, but the
             * descriptor string does.
             */
            return -1;
        }

        // Both prototype and descriptor have arguments. Compare them.

        const char* nextDesc = methodDescriptorNextType(descriptor);

        for (;;) {
            char c1 = *(protoDesc++);
            char c2 = (descriptor < nextDesc) ? *(descriptor++) : '\0';

            if (c1 < c2) {
                // This includes the case where the proto is shorter.
                return -1;
            } else if (c1 > c2) {
                // This includes the case where the desc is shorter.
                return 1;
            } else if (c1 == '\0') {
                // The two types are equal in length. (c2 necessarily == '\0'.)
                break;
            }
        }

        /*
         * If we made it here, the two arguments matched, and
         * descriptor == nextDesc.
         */
    }
}


/*
 * ===========================================================================
 *      Parameter Iterators
 * ===========================================================================
 */

/*
 * Initialize the given DexParameterIterator to be at the start of the
 * parameters of the given prototype.
 */
void dexParameterIteratorInit(DexParameterIterator* pIterator,
        const DexProto* pProto) {
    pIterator->proto = pProto;
    pIterator->cursor = 0;

    pIterator->parameters =
        dexGetProtoParameters(pProto->dexFile, getProtoId(pProto));
    pIterator->parameterCount = (pIterator->parameters == NULL) ? 0
        : pIterator->parameters->size;
}

/*
 * 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) {
    int cursor = pIterator->cursor;
    int parameterCount = pIterator->parameterCount;

    if (cursor >= parameterCount) {
        // The iteration is complete.
        return kDexNoIndex;
    } else {
        u4 idx = dexTypeListGetIdx(pIterator->parameters, cursor);
        pIterator->cursor++;
        return idx;
    }
}

/*
 * 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) {
    u4 idx = dexParameterIteratorNextIndex(pIterator);

    if (idx == kDexNoIndex) {
        return NULL;
    }

    return dexStringByTypeIdx(pIterator->proto->dexFile, idx);
}
