/*
 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Created in Samsung Ukraine R&D Center (SRK) under a contract between
 * LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
 * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
 *
 * Created on: Dec 18, 2017
 * Author: Kostiantyn Volobuiev <k.volobuyev@samsung.com>
 * Brief: Module that responds for string operations.
 */

#include "TzwString.h"

#if defined(TZ_MODEL_QCOM)
    #include <gpTypes.h>
    #include <qsee_heap.h>
    #include <qsee_comstr.h>
    #include <stdlib.h>
#endif

#include "ta_logger.h"

void tzwMemMove(void *dest, const void *src, uint32_t size) {
#if defined(TZ_MODEL_BLOWFISH)
    TEE_MemMove(dest, (void* )src, size);
#elif defined(TZ_MODEL_QCOM)
    memmove(dest, src, size);
#elif defined(TZ_MODEL_Kinibi)
    memmove(dest, src, size);
#endif
}

void tzwMemFill(void *buffer, uint32_t x, uint32_t size) {
#if defined(TZ_MODEL_BLOWFISH)
    TEE_MemFill(buffer, x, size);
#elif defined(TZ_MODEL_QCOM)
    memset(buffer, x, size);
#elif defined(TZ_MODEL_Kinibi)
    memset(buffer, x, size);
#endif
}

int32_t tzwMemCompare(const void *buffer1, const void *buffer2, uint32_t size) {
#if defined(TZ_MODEL_BLOWFISH)
    return TEE_MemCompare((void* )buffer1, (void* )buffer2, size);
#elif defined(TZ_MODEL_QCOM)
   return memcmp(buffer1, buffer2, size);
#elif defined(TZ_MODEL_Kinibi)
   return memcmp(buffer1, buffer2, size);
#endif
}

unsigned long tzwStrtoul(const char* uidStr, int uidStrBase) {
#if defined(TZ_MODEL_BLOWFISH)
    unsigned long n = 0;
    const size_t max_uid_len = 10; // maximum number of digits in uint32_t
    size_t len = strlen(uidStr);
    if (len > max_uid_len) {
        LOG_E("Not c-string passed to %s", __func__);
        return 0;
    }

    for (size_t i = 0; i < len; ++i) {
        // multiply by uidStrBase(10) to next digit.
        n *= uidStrBase;
        // Add difference beetween ASCII code of '0' and curr character.
        n += (uidStr[i] - '0');
    }
    return n;
#elif defined(TZ_MODEL_QCOM)
    return strtoul(uidStr, NULL, uidStrBase);
#elif defined(TZ_MODEL_Kinibi)
    return strtoul(uidStr, NULL, uidStrBase);
#endif
}

char* tzwStrncat(char* dest, const char* src, size_t srcLen, uint32_t destLen) {
#if defined(TZ_MODEL_BLOWFISH)
    S_VAR_NOT_USED(destLen);
    return strncat(dest, src, srcLen);
#elif defined(TZ_MODEL_QCOM)
    S_VAR_NOT_USED(srcLen);
    qsee_strlcat(dest, src, destLen + 1); // take into account that qsee_srnlcat guarantees that result string is NULL-terminated
    return dest;
#elif defined(TZ_MODEL_Kinibi)
    S_VAR_NOT_USED(destLen);
    return strncat(dest, src, srcLen);
#endif
}
