uint32_t BUFFER_ReadString(BUFFER_t* Buffer, char* buff, uint32_t buffsize) {
	uint32_t i = 0, freeMem, fullMem;
	uint8_t ch;
	if (Buffer == NULL) {
		return 0;											/* Check value buffer */
	}
	
	freeMem = BUFFER_GetFree(Buffer);						/* Get free memory */
	fullMem = BUFFER_GetFull(Buffer);						/* Get full memory */
	if (													/* Check for any data in buffer */
		fullMem == 0 ||                                 	/* Buffer empty */
		(
			BUFFER_FindElement(Buffer, Buffer->StringDelimiter) < 0 && 	/* String delimiter is not in buffer */
			freeMem != 0 &&                                            	/* Buffer is not full */
			fullMem < buffsize                                         	/* User buffer size is larger than number of elements in buffer */
		)
	) {
		return 0;											/* Return with no elements read */
	}
	while (i < (buffsize - 1)) {							/* If available buffer size is more than 0 characters */
		BUFFER_Read(Buffer, &ch, 1);						/* We have available data */
		buff[i] = (char)ch;									/* Save character */
		if ((char)buff[i] == (char)Buffer->StringDelimiter) {	/* Check for end of string */
			break;											/* Done */
		}
		i++;												/* Increase */
	}
	if (i == (buffsize - 1)) {								/* Add zero to the end of string */
		buff[i] = 0;
	} else {
		buff[++i] = 0;
	}
	return i;												/* Return number of characters in buffer */
}
int32_t BUFFER_FindElement(BUFFER_t* Buffer, uint8_t Element) {
	uint32_t Num, Out, retval = 0;
	
	/* Check buffer structure */
	if (Buffer == NULL) {
		return -1;
	}
	
	/* Create temporary variables */
	Num = BUFFER_GetFull(Buffer);
	Out = Buffer->Out;
	
	/* Go through input elements */
	while (Num > 0) {
		/* Check output overflow */
		if (Out >= Buffer->Size) {
			Out = 0;
		}
		
		/* Check for element */
		if ((uint8_t)Buffer->Buffer[Out] == (uint8_t)Element) {
			/* Element found, return position in buffer */
			return retval;
		}
		
		/* Set new variables */
		Out++;
		Num--;
		retval++;
	}
	
	/* Element is not in buffer */
	return -1;
}
uint32_t BUFFER_Read(BUFFER_t* Buffer, uint8_t* Data, uint32_t count) {
	uint32_t i = 0, full;
#if BUFFER_FAST
	uint32_t tocopy;
#endif
	
	if (Buffer == NULL || count == 0) {						/* Check buffer structure */
		return 0;
	}
	if (Buffer->Out >= Buffer->Size) {						/* Check output pointer */
		Buffer->Out = 0;
	}
	full = BUFFER_GetFull(Buffer);							/* Get free memory */
	if (full < count) {										/* Check available memory */
		if (full == 0) {									/* If no memory, stop execution */
			return 0;
		}
		count = full;										/* Set values for write */
	}
#if BUFFER_FAST
	tocopy = Buffer->Size - Buffer->Out;					/* Calculate number of elements we can read from end of buffer */
	if (tocopy > count) {									/* Check for copy count */
		tocopy = count;
	}
	memcpy(Data, &Buffer->Buffer[Buffer->Out], tocopy);		/* Copy content from buffer */
	i += tocopy;											/* Increase number of bytes we copied already */
	Buffer->Out += tocopy;
	count -= tocopy;
	if (count > 0) {										/* Check if anything to read */
		memcpy(&Data[i], Buffer->Buffer, count);			/* Copy content */
		Buffer->Out = count;								/* Set input pointer */
	}
	if (Buffer->Out >= Buffer->Size) {						/* Check output overflow */
		Buffer->Out = 0;
	}
	return (i + count);										/* Return number of elements stored in memory */
#else
	while (count--) {										/* Go through all elements */
		*Data++ = Buffer->Buffer[Buffer->Out++];			/* Read from buffer */
		i++;												/* Increase pointers */
		if (Buffer->Out >= Buffer->Size) {					/* Check output overflow */
			Buffer->Out = 0;
		}
	}
	return i;												/* Return number of elements stored in memory */
#endif
}
int32_t BUFFER_Find(BUFFER_t* Buffer, uint8_t* Data, uint32_t Size) {
	uint32_t Num, Out, i, retval = 0;
	uint8_t found = 0;

	if (Buffer == NULL || (Num = BUFFER_GetFull(Buffer)) < Size) {	/* Check buffer structure and number of elements in buffer */
		return -1;
	}
	Out = Buffer->Out;										/* Create temporary variables */
	while (Num > 0) {										/* Go through input elements in buffer */
		if (Out >= Buffer->Size) {							/* Check output overflow */
			Out = 0;
		}
		if ((uint8_t)Buffer->Buffer[Out] == (uint8_t)Data[0]) {	/* Check if current element in buffer matches first element in data array */
			found = 1;
		}
		
		Out++;												/* Set new variables */
		Num--;
		retval++;
		if (found) {										/* We have found first element */
			i = 1;											/* First character found */
			while (i < Size && Num > 0) {					/* Check others */	
				if (Out >= Buffer->Size) {					/* Check output overflow */
					Out = 0;
				}
				if ((uint8_t)Buffer->Buffer[Out] != (uint8_t)Data[i]) {	/* Check if current character in buffer matches character in string */
					retval += i - 1;
					break;
				}
				Out++;										/* Set new variables */
				Num--;
				i++;
			}
			if (i == Size) {								/* We have found data sequence in buffer */
				return retval - 1;
			}
		}
	}
	return -1;												/* Data sequence is not in buffer */
}