#ifndef  COMMON_SIP_MSRP_H
#define  COMMON_SIP_MSRP_H

#include "gen_classes.h"
#include "Regex.h"

namespace t3devlib { namespace gen {

//WSP: space, htab, vtab, form feed
#define SIPCHARS_WSP		" \t\v\f"
#define SIPREG_LWS		"(?:[" SIPCHARS_WSP "]*\\r\\n)?[" SIPCHARS_WSP "]+"
#define SIPREG_SWS		"(?:" SIPREG_LWS ")?"

#define SIPREG_HCOLON		"[ 	]*:" SIPREG_SWS
#define SIPREG_COMMA		SIPREG_SWS "[,]" SIPREG_SWS
#define SIPREG_SEMI			SIPREG_SWS "[;]" SIPREG_SWS
#define SIPREG_EQUAL		SIPREG_SWS "[=]" SIPREG_SWS
#define SIPREG_SLASH		SIPREG_SWS "[/]" SIPREG_SWS
#define SIPREG_COLON		SIPREG_SWS "[:]" SIPREG_SWS

#define SIPCHARS_ALFA		"A-Za-z"
#define SIPCHARS_ALFANUM	"0-9" SIPCHARS_ALFA
#define SIPCHARS_HEXA	"0-9A-Fa-f"

// host name
#define SIPREG_TOPLABEL	"[" SIPCHARS_ALFA "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPREG_DOMAINLABEL	"[" SIPCHARS_ALFANUM "]([" SIPCHARS_ALFANUM "\\-]*[" SIPCHARS_ALFANUM "])?"
#define SIPREG_HOSTNAME	"(" SIPREG_DOMAINLABEL "\\.)*" SIPREG_TOPLABEL "\\.?"

//quoted-string
// without leading and trailing whitespace
#define SIPCHARS_UTF8_NONASCII	"\x80-\xFD"
#define SIPREG_QUOTED_PAIR	"[\\x5C][\\x00-\\x09\\x0B\\x0C\\x0E-\\x7F]"
#define SIPREG_QUOTED_STRING	"[\"]((" SIPREG_LWS ")|[]!#-[^-~" SIPCHARS_UTF8_NONASCII"]|(" SIPREG_QUOTED_PAIR "))*[\"]"

//CRLF 
#define CRLF "\r\n"

//SP = %x20
#define SP "\x20"

//HTAB = %x09; horizontal tab
#define HTAB "\x09"

//DQUOTE = %x22; " (Double Quote)
#define DQUOTE "\x22"

//HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
#define HEXDIG_IN_SET DIGIT_IN_SET "A" "B" "C" "D" "E" "F"

// IPv6
#define SIPREG_HEX4		"[" SIPCHARS_HEXA "]{1,4}"
#define SIPREG_HEXSEQ		SIPREG_HEX4 "([:]" SIPREG_HEX4 ")*"
#define SIPREG_HEXPART	"(((" SIPREG_HEXSEQ ")?[:]{2}(" SIPREG_HEXSEQ ")?)|(" SIPREG_HEXSEQ  "))"
#define SIPREG_IP6_INTERNAL SIPREG_HEXPART "([:]" SIPREG_IP4 ")?"
#define SIPREG_IP6		"[[]" SIPREG_IP6_INTERNAL "[]]"

//IPv4
#define SIPREG_IP4	"([0-9]{1,3}\\.){3}[0-9]{1,3}"

	void normalise_quoted_string (Charstring& cs, bool remove_quotes = false) throw (DecodeError);
	void read_sp(Buffer & buffer, Variable* v);
	bool detect_separator(Regex & reg_separator, Buffer & buffer);
	bool detect_semi(Buffer & buffer) throw (DecodeError);
	bool detect_comma(Buffer & buffer);
}}
#endif
