/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#include "apt_text_stream.h"

/* Navigate through the lines of the text stream (message) */
APT_DECLARE(char*) apt_read_line(apt_text_stream_t *text_stream)
{
	char *line = text_stream->pos;
	while(*text_stream->pos != '\0')	{
		if(*text_stream->pos == APT_TOKEN_CR) {
			*text_stream->pos = '\0';
			text_stream->pos++;
			if(*text_stream->pos != '\0' && *text_stream->pos == APT_TOKEN_LF) {
				text_stream->pos++;
			}
			break;
		}
		else if(*text_stream->pos == APT_TOKEN_LF) {
			*text_stream->pos = '\0';
			text_stream->pos++;
			break;
		}
		text_stream->pos++;
	}
	return line;
}

/* Navigate through the fields of the line */
APT_DECLARE(char*) apt_read_field(char **line, char separator, char skip_spaces)
{
	char *field;
	char *pos = *line;

	if(skip_spaces) {
		while(*pos != '\0' && *pos == APT_TOKEN_SP) {
			pos++;
		}
	}

	field = pos;
	while(*pos != '\0')	{
		if(*pos == separator) {
			*pos = '\0';
			pos++;
			break;
		}
		pos++;
	}
	*line = pos;
	return field;
}



#define TOKEN_BOOLEAN_VALUE_TRUE  "true"
#define TOKEN_BOOLEAN_VALUE_FALSE "false"

/* Parse boolean-value */
APT_DECLARE(apt_bool_t) apt_boolean_value_parse(const char *str, apt_bool_t *value)
{
	if(apt_str_compare(str,TOKEN_BOOLEAN_VALUE_TRUE) == TRUE) {
		*value = TRUE;
		return TRUE;
	}
	if(apt_str_compare(str,TOKEN_BOOLEAN_VALUE_FALSE) == TRUE) {
		*value = FALSE;
		return TRUE;
	}
	return FALSE;
}

/* Generate boolean-value */
APT_DECLARE(apr_size_t) apt_boolean_value_generate(apt_bool_t value, char *str)
{
	const char *token = (value == TRUE) ? TOKEN_BOOLEAN_VALUE_TRUE : TOKEN_BOOLEAN_VALUE_FALSE;
	apr_size_t length = strlen(token);
	memcpy(str,token,length);
	return length;
}

/** Generate value plus the length (number of digits) of the value itself. */
APT_DECLARE(apr_size_t) apt_var_length_value_generate(apr_size_t *value, apr_size_t max_count, char *str)
{
	/* (N >= (10^M-M)) ? N+M+1 : N+M */
	apr_size_t temp;
	apr_size_t count; /* M */
	apr_size_t bounds; /* 10^M */
	
	/* calculate count */
	temp = *value;
	count = 0;
	do{count++; temp /= 10;} while(temp);

	/* calculate bounds */
	temp = count;
	bounds = 1;
	do{bounds *= 10; temp--;} while(temp);

	if(*value >= bounds - count) {
		count++;
	}

	*value += count;
	if(count > max_count) {
		return 0;
	}
	return apt_size_value_generate(*value,str);
}


/* Parse generic name-value pair */
APT_DECLARE(apt_bool_t) apt_name_value_pair_parse(apt_name_value_pair_t *pair, char *line)
{
	pair->name = apt_read_field(&line,':',1);
	while(*line != '\0' && *line == APT_TOKEN_SP) line++;
	pair->value = line;
	return TRUE;
}

/* Generate generic name-value pair */
APT_DECLARE(apr_size_t) apt_name_value_pair_generate(const apt_name_value_pair_t *pair, char *line)
{
	return apt_name_value_generate(pair->name,pair->value,line);
}

/* Generate generic name-value */
APT_DECLARE(apr_size_t) apt_name_value_generate(const char *name, const char *value, char *line)
{
	int length = sprintf(line,"%s:%s",name,value);
	if(length < 0) {
		length = 0;
	}
	return length;
}

/* Generate only the name part of the name-value pair */
APT_DECLARE(apr_size_t) apt_name_value_generate_name(const char *name, char *line)
{
	int length = sprintf(line,"%s:",name);
	if(length < 0) {
		length = 0;
	}
	return length;
}
