//---------------------------------------------------------------------------
#include "stdafx.h"
#include "extra.h"
#include "OS_types.h"
//---------------------------------------------------------------------------
/*knihovna obsahuje funkce optimalizované pro použití s AVR a ARM*/

char text_buff[BUFF_SIZE];


/****************************************************************************
	Funkce pro zjištění délky řetězce ukončeného nulovým znakem

	Vstup: 
		input:	Zkoumaný řetězec

	Výstup:
		Délka řetězce

*****************************************************************************/
int get_length(unsigned char* input)
{
	int i = 0;
	while(input[i++]!='\0');
	
	return i-1;
}


/****************************************************************************
	Funkce vrací hodnotu funkce 10^j

	Vstup: 
		j:		mocnina

	Výstup:
		hodnota 10^j

*****************************************************************************/
int mocnina10(int j){
	int mocnina = 1;
	int i = 0;
	for (i=1; i < j; i++) {
		mocnina*=10;
	}
return mocnina;
}

/****************************************************************************
	Funkce převede číslo na řetězec

	Vstup: 
		cislo:	Hodnota převáděného čísla

	Výstup:
		ukazatel na řetězec - knihovna obsahuje jeden buffer pro všechny funkce
		tohoto typu, proto je třeba před dalším použitím výsledek zkopírovat
		někam jinam

*****************************************************************************/

char* int2char(int cislo)
{
	//Inicializace
	int j = 0;
	int i;
	int pwr;
	char tmp;
	
	//Zjištění řádové velikosti čísla
	while (cislo/mocnina10(++j)>=10);
	
	//zjištění, jestli se číslo vejde do bufferu
	j = j>=BUFF_SIZE?BUFF_SIZE:j;
	text_buff[j]= '\0';

	//Samotný převod na char[]
	for (i = 0; i < j; i++) 
	{
		pwr = mocnina10(j-i);
		tmp =  (char)(cislo/pwr);
		text_buff[i]=tmp+'0';
		cislo -= (tmp*pwr);
	}

return text_buff;
}


/****************************************************************************
	Funkce převedetextový řetězec na číslo. Pokud je v řetězci nalezen nečíselný
	znak, je převod automaticky ukončen

	Vstup: 
		input:	ukazatel na převáděný řetězec

	Výstup:
		číslo nalezené v řetězci

*****************************************************************************/
int char2int(char * input)
{
	//Inicializace
	int delka = 0;
	int cislo = 0;
	int tmp;
	//Dokud není nalezen ukončovací znak
	while(input[delka]!='\0')
	{
		//Převeď znak na číslo
		tmp = input[delka++]-'0';
		//Pokud není číslicí, ukonči
		if ((tmp>9)||(tmp<0)) 
		{
			return cislo;
		}
		//jinak aktualizuj výstupní číslo
		cislo = (cislo*10)+tmp;
	};
	return cislo;
}

/****************************************************************************
	Funkce porovná dva řetězce

	Vstup: 
		in1:	První převáděný řetězec
		in2:	Druhý převáděný řetězec

	Výstup:
		vrací 1, pokud jsou řetězce shodné.

*****************************************************************************/
int strcomp(unsigned char* in1, unsigned char* in2){
	int i = 0;
	do 
	{
		//Pokud se znaky na pozici liší
		if (in1[i]!=in2[i]) 
		{
			//Vrať 0
			return 0;
		}
	}  while((in1[i]!='\0')&&(in2[i++]!='\0'));
	
	return 1;
}

/****************************************************************************
	Zkopíruje řetězec na zadanou adresu

	Vstup: 
		input:	Vstupní řetězec
		output:	Výstupní řetězec

	Výstup:
		Není

*****************************************************************************/
void strcopy(unsigned char*input,unsigned char*output){
	int i = 0;
	do 
	{
		output[i] = input[i];

	} while ((input[i++]!='\0'));
}



/****************************************************************************
	Funkce připojí na konec řetězce další řetězec

	Vstup: 
		output:	Cílový řetězec
		input:	Zdrojový řetězec

	Výstup:
		není

*****************************************************************************/
void str_append(unsigned char* output,unsigned char*input)
{
	//Zjisti délku řetězců
	int output_delka = get_length(output);
	int input_delka = get_length(input);
	int i;
	//Na konec prvního připoj druhý
	for (i = 0; i <input_delka; i++) {
		  output[i+output_delka] = input[i];
	}
	//korektní ukončení
	output[i+output_delka] = '\0';
}


/****************************************************************************
	Celočíselné dělení bez použtí operátoru "/"

	Vstup: 
		num:		dělenec
		divisor:	dělitel

	Výstup:
		výsledek dělení

*****************************************************************************/
int integerDiv(int num,int divisor)
{
	int ctr = -1;
	
	int tmp = num;

	if (num < 0)
		return -1;
	if (num < divisor)
		return 0;
	//Dokud je číslo větší než nula
	while (tmp > 0)
	{
		ctr++;
		//odečni dělitele
		tmp-=divisor;
	}
	return ctr;
}

/****************************************************************************
	Vloží znak na zadanou pozici do řetězce

	Vstup: 
		input:		řetězec
		C:			znak, který má být vložen
		pos:		pozice

	Výstup:
		1 pokud byla operace úspěšná

*****************************************************************************/
char strPutChar(unsigned char* input, unsigned char C, int pos)
{
	int length = get_length(input), i;
	//Kontrola, jestli je pozice uvnitř řetězce
	if (pos >= length)
		return 0;
	//přeskládej řetězec, aby vzniklo volné místo
	for (i = length; i > pos; i--)
	{
		input[i] = input[i-1]; 
	}
	//vlož znak
	input[pos] = C;
	return 1;
}

/****************************************************************************
	Odstranění znaku na pozici

	Vstup: 
		input:		vstupní řetězec
		pos:		pozice

	Výstup:
		1 pokud byla operace úspěšná

*****************************************************************************/
char strDelChar(unsigned char *input, int pos)
{
	int length = get_length(input), i;
	//Zjištění, jestli je pozice uvnitř řetězce
	if (pos >= length)
		return 0;
	//Přeskládání řetězce
	for (i = pos; i < length; i++)
	{
		input[i] = input[i+1];
	}
	return 1;
}




/****************************************************************************
	Vyplní buffer o zadané délce nulami

	Vstup: 
		zásobník:		dělenec
		length:			délka

	Výstup:
		není

*****************************************************************************/
void clearBuffer(unsigned char* buffer, int length)
{
	int i = 0;
	for (i = 0; i < length; i++)
	{
		buffer[i] = 0;
	}
}

/****************************************************************************
	Vyplní buffer znakem zadané hodnoty

	Vstup: 
		buffer:		Zásobník
		length:		délka
		val:		hodnota na kterou má být zásobník nastaven

	Výstup:
		není

*****************************************************************************/
void setBuffer(unsigned char* buffer, int length, unsigned char val)
{
	int i = 0;
	for (i = 0; i < length; i++)
	{
		buffer[i] = val;
	}
}

/****************************************************************************
	vloží číslo do textu podle zadané masky. Pokud je v masce znak 'N', 
	lze na tuto pozici vložit číslici

	Vstup: 
		buffer:		textový řetězec
		mask:		maska
		C:			znak, který se má vložit
		pos:		pozice

	Výstup:
		výsledek dělení

*****************************************************************************/
int addNumToMaskedText(unsigned char *buffer, unsigned char * mask, unsigned char C, int pos)
{
	int i = pos-1, maskLength = get_length(mask);
	//Kontrola platnosti vstupních parametrů
	if (mask == 0 || buffer == 0 || pos >= maskLength || !IS_NUMBER(C))
		return pos;

	//Nalezení první vyplnitelné pozice od pozice pos
	while(mask[++i]!= NUMBER_ALIAS)
	{
		if (maskLength <= i)
			return pos;
	}
	//vložení znaku na pozici
	buffer[i] = C;

	//Nalezení další pozice pro umístění čísla
	while(mask[++i]!= NUMBER_ALIAS)
	{
		//pokud je dosaženo konce řetězce, ukonči
		if (maskLength <= i)
		{
			i--;
			break;
		}
	}
	return i;
}


/****************************************************************************
	Pokusí se vypreparovat IP adresu z řetězce, tkerý je ve formátu 
	NNN.NNN.NNN.NNN

	Vstup: 
		IPbuff:		cílový řetězec
		source:		zdrojový řetězec

	Výstup:
		PASSED/FAILED

*****************************************************************************/
RESULT tryToGetIP(unsigned char * IPbuff,unsigned char* source)
{
	unsigned char buff[4] = "";
	unsigned char * tmp = source;
	//Pro všechny čtyři bajty IP adresy
	for (int j = 0; j < 4; j++)
	{
		//znak po znaku zkontroluj platnost
		for (int i = 0; i < 3; i++)
		{
			if (!IS_NUMBER(tmp[i]))
			{
				return FAILED;
			}
			else
			{
				buff[i] = tmp[i];
			}
		}
		//převeď každou část IP adresy na číslo a zkontroluj rozsah
		if (char2int((char*)buff) > 255)
		{
			return FAILED;
		}
		if (tmp[3] != '.' && j < 3)
		{
			return FAILED;
		}
		tmp += 4;
	}

	//pokud je adresa platná, zkopíruj ji do výstupního bufferu
	for (int i = 0; i < 15; i++)
	{
		IPbuff[i] = source[i];
	}
	return PASSED;
}


/****************************************************************************
	Pokusí se vypreparovat počet bitů masky z řetězce 
	IP1.IP2.IP3.IP4/MM

	Vstup: 
		maskBUff:	cílový řetězec
		source:		zdrojový řetězec

	Výstup:
		PASSED/FAILED

*****************************************************************************/
RESULT tryToGetMask(unsigned char * Maskbuff,unsigned char* source)
{
	//Kontrola platnosti vstupních parametrů
	if (get_length(source) != 18 ||(source[15]!='/'&& source[15]!=':') )
		return FAILED;
	unsigned char * tmp = source+16;
	int mask = char2int((char*) tmp);
	//Kopie masky do výstupního bufferu
	if (mask >=1 && mask <= 31)
	{
		Maskbuff[0] = tmp[0];
		Maskbuff[1] = tmp[1];
		return PASSED;
	}
	return FAILED;

}

/****************************************************************************
	Získá číslo z textového řetězce

	Vstup: 
		input:		vstupní řetězec

	Výstup:
		číslo

*****************************************************************************/
int getNumber(unsigned char* input)
{
	char buff[10];
	int cntr = 0;

	//Dokud jsou znaky číslicemi
	while(IS_NUMBER(input[cntr]))
	{
		//kopíruj data do bufferu
		buff[cntr] = input[cntr];
		cntr++;
	}
	buff[cntr] = 0;
	//převeď řetězec na číslo
	return char2int(buff);
}


