#include "_string.h"

/*******************************************************************************
  * @函数名称		strlen
  * @函数说明   string长度统计
  * @输入参数   需计算字符串首地址
  * @输出参数   字符串长度，不包括'\0'
  * @返回参数   无
*******************************************************************************/
int _strlen(const char *str)
{
    int count=0;
    while(*str!='\0')
    {
      count++;
      str++;
    }
    return count;
}

void _strcpynum(char *dest,const char *src,uint8_t num)
{
    while(num--)
    {
      *dest++=*src++;
    }
}

int _strcopy(char *str,const char *value)
{
    int count=0;
    while(*value!='\0')
    {
      *str++=*value++;
      count++;
    }
    *str='\0';
    return count;
}

char *_strcat(char *dest,const char *src)
{
    int len=0,idx=0;
    idx=_strlen(dest);
    len=idx+_strlen(src)+1;
    dest=(char *)realloc(dest,len*sizeof(char));
    _strcopy(&dest[idx],src);
    return dest;
}

char *_strcatint(char *dest, int num)
{
    int len=0,idx=0;
	char src[12]={0};
    idx=_strlen(dest);
    sprintf(src, "%d", num);
	len=idx+_strlen(src)+1;
    dest=(char *)realloc(dest,len*sizeof(char));
    _strcopy(&dest[idx],src);
    return dest;
}

//查找字符c在字符串str中第num次出现的位置
int _strfindnum(char *str,char c,uint8_t num)
{
    int count=0;
    while(*str!='\0')
    {
      if(*str++==c)
      {
        num--;
        if(num==0)
        {
          return count;
        }
      }
      count++;
    }
    return -1;
}

/*******************************************************************************
  * @函数名称		_strfind
  * @函数说明   查找字符c在字符串str中第一次出现的位置
  * @输入参数   需查找字符串首地址
  * @输出参数   找到的字符的位置下标
  * @返回参数   无
*******************************************************************************/
int _strfind(char *str,char c)
{
    int count=0;
    while(*str!='\0')
    {
      if(*str++==c)
      {
        return count;
      }
      count++;
    }
    return -1;
}

/*******************************************************************************
  * @函数名称		_strfindchar
  * @函数说明   查找字符c在字符串str中第一次出现的位置
  * @输入参数   1：参数个数，2：需查找字符串首地址，3：需查找的字符，4：查找长度限制
  * @输出参数   找到的字符的位置下标
  * @返回参数   无
*******************************************************************************/
int _strfindchar(int count,...)
{
	if(count<2 || count>3)
	{
		return -1;
	}
	va_list valist;
	/* 为 num 个参数初始化 valist */
  	va_start(valist, count);
	
	char *str=va_arg(valist, char*);
	char c = va_arg(valist, int);
	int len=0;
	if(count==3)
	{
		len=va_arg(valist, int);
	}

	/* 清理为 valist 保留的内存 */
  	va_end(valist);
	
	int idx=0;
	while(*str!='\0')
	{
		if(*str++==c)
		{
			return idx;
		}
		if(idx>=len-1)
		{
			return -1;
		}
		else{
			idx++;
		}
	}
  return -1;
}

/*******************************************************************************
  * @函数名称		_strcount
  * @函数说明   string长度统计
  * @输入参数   需计算字符串首地址
  * @输出参数   字符串长度，不包括'\0','\r','\n'
  * @返回参数   无
*******************************************************************************/
int _strcount(const char *str)
{
    int count=0;
    while(*str!='\0' && *str!='\r' && *str!='\n')
    {
      count++;
      str++;
    }
    return count;
}

/*******************************************************************************
  * @函数名称		strCompare
  * @函数说明   比较字符串1和字符串2是否相同
  * @输入参数   *str1：第一个字符串
								*str2：第二个字符串
	* @输出参数   相同为0，不同为-1
  * @返回参数   无
*******************************************************************************/
int _strCompare(char *str1,const char *str2)
{
	const char * p1=str1;
	const char * p2=str2;
	
	while(*p1!='\0' || *p2!='\0')
	{
		if(*p1!=*p2)
		{
			return -1;
		}
		p1++;
		p2++;
	}
	return 0;
}

/*******************************************************************************
  * @函数名称		strstr
  * @函数说明   在字符串1中找字符串2出现的第一次位置
  * @输入参数   *str1：第一个字符串
								*str2：第二个字符串
  * @输出参数   出现的位置
  * @返回参数   无
*******************************************************************************/
int _strstr(char *str1,const char *str2)
{
	char * p1=str1;
	const char * p2=str2;
	int size=0;
	
	if(*str1=='\0' || *str2=='\0')
	{
		return -1;
	}
	
	if(_strlen(str1)<_strlen(str2))
	{
		return -1;
	}
	
	while(*str1)
	{
		p1=str1;
		p2=str2;
		while(*p1==*p2 && *p1 && *p2)
		{
			p1++;
			p2++;
		}
		if(*p2=='\0')
		{
			return size;
		}
		
		str1++;
		size++;
	}
	return -1;
}

uint8_t _get_Hex(const char c)
{
	uint8_t value=0xFF;
	if(c>='0'&&c<='9'){
		value=c-'0';
	}
	else if(c>='A' && c<='F')
	{
		value=c-55;
	}
	else if(c>='a' && c<='f')
	{
		value=c-87;
	}
	return value;
}

char _get_HexChar(uint8_t hex)
{
	switch(hex)
	{
		case 0:return '0';
		case 1:return '1';
		case 2:return '2';
		case 3:return '3';
		case 4:return '4';
		case 5:return '5';
		case 6:return '6';
		case 7:return '7';
		case 8:return '8';
		case 9:return '9';
		case 10:return 'A';
		case 11:return 'B';
		case 12:return 'C';
		case 13:return 'D';
		case 14:return 'E';
		case 15:return 'F';
		default:return '0';
	}
}

int _HexToStr(char *data,uint8_t *byte,int size)
{
	char temp=0;
	
	for(int i=0;i<size;i++)
	{
		temp=_get_HexChar(*byte>>4);
		*data++=temp;
		temp=_get_HexChar(*byte++&0x0F);
		*data++=temp;
	}
	*data=0;
	return size*2;
}

int getIndexOfSigns(char ch)
{
    if(ch >= '0' && ch <= '9')
    {
        return ch - '0';
    }
    if(ch >= 'A' && ch <='F') 
    {
        return ch - 'A' + 10;
    }
    if(ch >= 'a' && ch <= 'f')
    {
        return ch - 'a' + 10;
    }
    return -1;
}

uint32_t _get_HexToDec(char *str)
{
	uint32_t sum=0;
	int temp=0;
	
	while(*str!=0)
	{
		temp=getIndexOfSigns(*str);
		if(temp==-1)
		{
			break;
		}
		sum*=16;
		sum+=temp;
		str++;
	}
	
	return sum;
}

static bool check_number_start(char c)
{
	if(c >= '0' && c <= '9')
  {
		return true;
  }
	
	if(c == '-' || c == '+')
	{
		return true;
	}
	return false;
}

int check_no_number(char *str)
{
	int idx=0;
	while(*str >= '0' && *str <= '9')
  {
		idx++;
		str++;
  }
	return idx;
}

int check_is_number(char *str)
{
	int idx=0;
	while(*str < '0' || *str > '9')
  {
		idx++;
		str++;
  }
	return idx;
}

float _my_atof(char *str)
{
	float f_num=0.0f;
	float decimal=0.0f;
	uint8_t decimal_count=0;
	bool neg=false;
	
	while(check_number_start(*str)==false)
	{
		str++;
	}
	
	if(*str=='-')
	{
		neg=true;
		str++;
	}
	
	while(*str >= '0' && *str <= '9')
	{
		f_num*=10.0f;
		f_num+=(float)_get_Hex(*str++);
	}
	
	if(*str=='.')
	{
		str++;
		while(*str >= '0' && *str <= '9')
		{
			decimal*=10.0f;
			decimal+=(float)_get_Hex(*str++);
			decimal_count++;
			if(decimal_count>6)
			{
				break;
			}
		}
		
		while(decimal_count--)
		{
			decimal/=10.0f;
		}
	}
	
	f_num=f_num+decimal;
	
	if(neg==true)
	{
		f_num=0-f_num;
	}

	return f_num;
}

int _my_atoi(char *str)
{
	int i_num=0;
	bool neg=false;
	
	while(check_number_start(*str)==false)
	{
		str++;
	}
	
	if(*str=='-')
	{
		neg=true;
		str++;
	}
	
	while(*str >= '0' && *str <= '9')
	{
		i_num*=10;
		i_num+=(int)_get_Hex(*str++);
	}
	
	if(neg==true)
	{
		i_num=0-i_num;
	}

	return i_num;
}

uint32_t _my_atou32(char *str)
{
	uint32_t u32_num=0;
	
	while(check_number_start(*str)==false)
	{
		str++;
	}
	
	while(*str >= '0' && *str <= '9')
	{
		u32_num*=10;
		u32_num+=(int)_get_Hex(*str++);
	}

	return u32_num;
}
