/*
 * @Description: 工具模块-数据处理子模块
 * @Author: yangsw
 * @Date: 2021-04-28 17:23:18
 * @LastEditTime: 2022-05-30 15:09:55
 * @LastEditors: yangsw
 * @Reference:
 */

#include "util_data.h"
#include "../com/svc/svc_com.h"
#include "../log/svc/svc_log.h"
#include <string.h>

/**
 * @brief: 不保留小数的四舍五入
 * @return {int32_t} 转换结果
 * @note:
 * @see:
 * @param {double} num 待转换的数据
 * @param
 */
int32_t Util_Data_Round(double num)
{
    if (num > 0)
    {
        return (int32_t)(num + 0.5);
    }
    else
    {
        return (int32_t)(num - 0.5);
    }
}

/**
 * @brief: 校验和计算
 * @return {gw_u8} 和校验结果
 * @note:
 * @see:
 * @param {gw_u8} *data 待计算的数据
 * @param {gw_u16} len 待计算数据长度
 */
gw_u8 Util_Data_Check_Sum(gw_u8 *data, gw_u16 len)
{
    gw_u8 sum = 0;
    gw_u16 i;

    for (i = 0; i < len; i++)
    {
        sum += data[i];
    }

    return sum;
}

/**
 * @brief: 字符串转unsigned char型
 * @return {gw_u8} 转换结果
 * @note:
 * @see:
 * @param {gw_u8} *str 待转换的字符串
 * @param {gw_u8} len 待转换的字符串长度
 */
gw_u8 Util_Data_String_To_Uint8(gw_u8 *str, gw_u8 len)
{
    gw_u8 i;
    gw_u8 sum = 0;
    if (len > 3)
    {
        return 0;
    }
    for (i = 0; i < len; i++)
    {
        if ((str[i] >= '0') && (str[i] <= '9'))
        {
            sum = sum * 10;
            sum = sum + (str[i] - '0');
        }
    }
    return sum;
}

/**
 * @brief: 字符串转unsigned short型
 * @return {gw_u16} 转换结果
 * @note:
 * @see:
 * @param {gw_u8} *str 待转换的字符串
 * @param {gw_u8} len 待转换的字符串长度
 */
gw_u16 Util_Data_String_To_Uint16(gw_u8 *str, gw_u8 len)
{
    gw_u8 i;
    gw_u16 sum = 0;
    if (len > 5)
    {
        return 0;
    }
    for (i = 0; i < len; i++)
    {
        if ((str[i] >= '0') && (str[i] <= '9'))
        {
            sum = sum * 10;
            sum = sum + (str[i] - '0');
        }
    }
    return sum;
}

/**
 * @brief: 字符转换为十六进制数据
 * @return {gw_u8} 转换结果
 * @note: 示例：'0'->0x00，'A'->0x0A
 * @see:
 * @param {gw_u8} data 待转换数据
 */
gw_u8 Util_Data_Char2_To_Byte(gw_u8 data)
{
    if ((data >= '0') && (data <= '9'))
    {
        data -= '0';
    }
    else if ((data >= 'a') && (data <= 'f'))
    {
        data = (data - 'a') + 10;
    }
    else if ((data >= 'A') && (data <= 'F'))
    {
        data = (data - 'A') + 10;
    }
    return data;
}

/**
 * @brief: 字符串转成十六进制，每2个字符拼成一个字节
 * @return {gw_u16} 转换后的数据长度
 * @note: 示例：“0123ABCD”->0x01,0x23,0xAB,0xCD
 * @see:
 * @param {gw_u8} *in_str 待转换的数据指针
 * @param {gw_u16} len 待转换的数据长度
 * @param {gw_u8} *out_data 转换后的数据指针
 */
gw_u16 Util_Data_String2_To_Byte(gw_u8 *in_str, gw_u16 len, gw_u8 *out_data)
{
    gw_u16 i;
    gw_u16 out_len = len / 2;
    // memset(out_data,0,out_len);
    for (i = 0; i < out_len; i++)
    {
        out_data[i] = Util_Data_Char2_To_Byte(in_str[i * 2]);
        out_data[i] = (out_data[i] << 4) + Util_Data_Char2_To_Byte(in_str[i * 2 + 1]);
    }
    return out_len;
}

/**
 * @brief: 十六进制转换为十六进制字符串，单字节转换
 * @return {void}
 * @note: 示例：0x1A->"1A"
 * @see:
 * @param {gw_u8} hex 待转换数据
 * @param {gw_u8} *hexstr 转换后的数据指针
 */
void Util_Data_Hex_To_Hexstr(gw_u8 hex, gw_u8 *hexstr)
{
    gw_u8 h, l;
    h = (hex >> 4) & 0x0f;
    l = (hex & 0x0f);
    if (h <= 9) // if((h>=0)&&(h<=9))
        hexstr[0] = h + '0';
    else if ((h >= 10) && (h <= 15))
    {
        hexstr[0] = h + 'A' - 10;
    }
    else
    {
        hexstr[0] = 0xff;
    }

    if (l <= 9) // if((l>=0)&&(l<=9))
        hexstr[1] = l + '0';
    else if ((l >= 10) && (l <= 15))
    {
        hexstr[1] = l + 'A' - 10;
    }
    else
    {
        hexstr[1] = 0xff;
    }
}

/**
 * @brief: 十六进制数据转换为十六进制字符串
 * @return {gw_u16} 转换后的数据长度
 * @note: 示例：大端模式：0x12 0xAB->"12AB",小端模式：0x12 0xAB->"AB12"
 * @see:
 * @param {gw_u8} *hexs 待转换数据指针
 * @param {gw_u8} *hexstr 转换后的数据指针
 * @param {gw_u16} len 待转换的数据长度
 * @param {gw_u8} a_litt 大小端模式选择
 */
gw_u16 Util_Data_Hexs_To_Hexstr(gw_u8 *hexs, gw_u8 *hexstr, gw_u16 len, gw_u8 a_litt)
{
    gw_u16 j = 0;
    gw_u16 i;
    if (a_litt == 0) // 大端数据
    {
        for (i = 0; i < len; i++)
        {
            Util_Data_Hex_To_Hexstr(hexs[i], hexstr + j);
            j += 2;
        }
    }
    else if (a_litt == 1) // 小端数据
    {
        for (i = 0; i < len; i++)
        {
            Util_Data_Hex_To_Hexstr(hexs[len - i - 1], hexstr + j);
            j += 2;
        }
    }
    return j;
}

/**
 * @brief: 按字符对字符串进行分割
 * @return {gw_u16} 分割字符串的最后位置
 * @note: 例如“aa,bb,cc”按','分割后变为"aa","bb","cc",此函数会改变源字符串，源字符串的','变为'\0'
 * @see:
 * @param {gw_s8} *in_str 待分割的字符串
 * @param {gw_s8} regex 分割字符
 * @param {gw_s8} **out_str 分割后的二维数据指针
 * @param {gw_u16} out_size 分割后的字符串组数
 */
gw_u16 Util_Data_String_Split(gw_s8 *in_str, gw_s8 regex, gw_s8 **out_str, gw_u16 out_size)
{
    gw_u16 index = 0;
    gw_s16 i = 0;
    gw_s8 *str = in_str;
    while (str[i] != '\0')
    {
        if (str[i] == regex)
        {
            out_str[index] = str;
            out_str[index++][i] = '\0';
            str = (str + i + 1);
            i = -1;
        }
        if (index >= out_size)
        {
            return index;
        }
        i++;
    }
    if (strlen((const char *)str) > 0)
    {
        out_str[index++] = str;
    }
    return index;
}

/**
 * @brief: BCD码转十进制函数，输入BCD，返回十进制
 * @return {gw_u8} 转换结果
 * @note: 示例：0x10->0x0A
 * @see:
 * @param {gw_u8} bcd 待转换的数据
 */
gw_u8 Util_Data_Bcd_To_Decimal(gw_u8 bcd)
{
    gw_u8 Decimal;
    Decimal = bcd >> 4;
    return (Decimal = Decimal * 10 + (bcd &= 0x0F));
}

/**
 * @brief: 十进制转BCD码
 * @return {gw_u8}
 * @note: 示例：0x0A->0x10
 * @see:
 * @param {gw_u8} decimal 待转换的数据
 */
gw_u8 Util_Data_Decimal_To_Bcd(gw_u8 decimal)
{
    gw_u8 sum = 0, i; // i计数变量，sum返回的BCD码
    for (i = 0; decimal > 0; i++)
    {
        sum |= ((decimal % 10) << (4 * i));
        decimal /= 10;
    }
    return sum;
}

/**
 * @brief: 求两个正数差的绝对值
 * @return {gw_u32} a和b差的绝对值
 * @note:
 * @see:
 * @param {gw_u32} a
 * @param {gw_u32} b
 */
gw_u32 Util_Data_Absolute(gw_u32 a, gw_u32 b)
{
    if (a >= b)
        return a - b;
    else
        return b - a;
}

/**
 * @brief: 字符串转signed char型
 * @return {gw_u8} 转换结果
 * @note:
 * @see:
 * @param {gw_u8} *str 待转换的字符串
 * @param {gw_u8} len 待转换的字符串长度
 */
gw_s8 Util_Data_String_To_Sint8(gw_u8 *str, gw_u8 len)
{
    gw_u8 i;
    gw_u8 sum = 0;
    if (len > 4)
    {
        return 0;
    }
    if (str[0] == '0') // 负数
    {
        for (i = 1; i < len; i++)
        {
            if ((str[i] >= '0') && (str[i] <= '9'))
            {
                sum = sum * 10;
                sum = sum + (str[i] - '0');
            }
        }
        sum = 0 - sum;
    }
    else
    {
        for (i = 0; i < len; i++)
        {
            if ((str[i] >= '0') && (str[i] <= '9'))
            {
                sum = sum * 10;
                sum = sum + (str[i] - '0');
            }
        }
    }
    return sum;
}
/**
 * @brief: 字符串转signed short型
 * @return {gw_u16} 转换结果
 * @note:
 * @see:
 * @param {gw_u8} *str 待转换的字符串
 * @param {gw_u8} len 待转换的字符串长度
 */
gw_s16 Util_Data_String_To_Sint16(gw_u8 *str, gw_u8 len)
{
    gw_u8 i;
    gw_u16 sum = 0;
    if (len > 6)
    {
        return 0;
    }
    if (str[0] == '-') // 负数
    {
        for (i = 1; i < len; i++)
        {
            if ((str[i] >= '0') && (str[i] <= '9'))
            {
                sum = sum * 10;
                sum = sum + (str[i] - '0');
            }
        }
        sum = 0 - sum;
    }
    else
    {
        for (i = 0; i < len; i++)
        {
            if ((str[i] >= '0') && (str[i] <= '9'))
            {
                sum = sum * 10;
                sum = sum + (str[i] - '0');
            }
        }
    }
    return sum;
}
// 在帧头 DDH 和帧尾 DCH 之间的数据出现的 DBH、DCH、DDH 分别与 40H 异或，变成（9BH、9CH、9DH）再在前加 DBH，如收到一个字节是 DDH，经过转义后变为 DBH，9DH.
gw_s16 Change_Original_Data(gw_u8 *in_data, gw_u16 in_len, gw_u8 *out_data)
{
    gw_u8 *buff = Svc_Com_Get_Buf();
    if (buff == NULL)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->null buff!", __FUNCTION__);
        return -1;
    }
    buff[0] = in_data[0];
    gw_u16 j = 1;
    gw_u16 i;
    for (i = 1; i < in_len - 1; i++)
    {
        if (in_data[i] == 0xDB || in_data[i] == 0xDC || in_data[i] == 0xDD)
        {
            buff[j] = 0xDB;
            j++;
            buff[j] = (in_data[i] ^ 0x40);
        }
        else
        {
            buff[j] = in_data[i];
        }
        j++;
    }
    buff[j] = in_data[i];
    gw_u16 out_len = j + 1;
    memcpy(out_data, buff, out_len);
    return out_len;
}

// 在帧头 DDH 和帧尾 DCH 之间的数据出现的 DBH 9DH、DBH 9CH、DBH 9BH ,去掉DBH,（9BH、9CH、9DH）分别与 40H 异或，变成（DBH、DCH、DDH）,如收到数据是 DBH 9DH，经过反转义后变为 DDH.
gw_s16 Get_Original_Data(gw_u8 *in_data, gw_u16 in_len, gw_u8 *out_data)
{
    gw_u8 *buff = Svc_Com_Get_Buf();
    ;
    if (buff == NULL)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->null buff!", __FUNCTION__);
        return -1;
    }
    int j = 0;
    for (int i = 1; i < in_len - 1; i++)
    {
        if ((in_data[i] & 0xFF) == 0xDB)
        {
            if (in_data[i + 1] == 0x9B || in_data[i + 1] == 0x9C || in_data[i + 1] == 0x9D)
            {
                buff[j] = in_data[i + 1] ^ 0x40;
                i++;
            }
        }
        else
        {
            buff[j] = in_data[i];
        }
        j++;
    }
    gw_u16 out_len = j;
    memcpy(out_data, buff, out_len);
    return out_len;
}


