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

Copyright (c) 2004 Open Mobile Alliance, Ltd.  All Rights Reserved.

This software is made available under the usage and distribution terms 
covered by the Common Public License 1.0 and by using this software you
are bound by the terms and conditions of the same.

EXCEPT AS EXPRESSLY SET FORTH IN THE COMMON PUBLIC LICENSE,
THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
   
Each recipient is solely responsible for determining the 
appropriateness of using and distributing this program and assumes 
all risks associated with its exercise of rights under the Common 
Public License, including but not limited to the risks and 
costs of program errors, compliance with applicable laws, 
damage to or loss of data, programs or equipment, and 
unavailability or interruption of operations.

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

#include "SctsPlatformLib.h"
#include "SctsCommonElements.h"
#include "SctsAuth.h"
#include "stdlib.h"

#ifdef __SCTS_USING_RTK__

/*****************************************************************
Helper Functions
******************************************************************/

SmlPcdataPtr_t sctsInt2Pcdata(int i)
{
	char buffer[20];
	return smlString2Pcdata(sctsInt2Str(i,buffer,10));
}

int sctsPcdata2Int(SmlPcdataPtr_t pPcdata)
{
	int i;
	char *pStr=smlPcdata2String(pPcdata);
	SCTSASSERT(pStr);
	i=sctsStr2Int(pStr);
	sctsFree(pStr);
	return i;
}
	

/*****************************************************************
SctsPcdata Definition
******************************************************************/
bool SctsPcdata::operator!()
{
	return !rawData;
}

SctsPcdata::operator bool()
{
	if (rawData) return true;
	return false;
}

bool operator==(SctsPcdata& pcdata,char *pStr)
{
	if (!pStr && !pcdata.rawData) return true;
	if (!pStr || !pcdata.IsString()) return false;
	if (sctsStrlen(pStr)!=pcdata.rawData->length) return false;
	if (sctsMemcmp(pcdata.rawData->content,pStr,pcdata.rawData->length)) return false;
	return true;
}

bool operator==(SctsPcdata& pcdata,int i)
{
	char buffer[15];
	return (pcdata==itoa(i,buffer,10));
}

bool operator==(SctsPcdata& pcdata1,SctsPcdata& pcdata2)
{
	if (!pcdata1.IsString() || !pcdata2.IsString()) return false;
	if (pcdata1.rawData->length!=pcdata1.rawData->length) return false;
	if (sctsMemcmp(pcdata1.rawData->content,pcdata2.rawData->content,pcdata1.rawData->length)) return false;
	return true;
}

SctsPcdata& SctsPcdata::operator=(SctsPcdata& pcdata)
{
	if (pcdata.IsString())
		rawData=smlString2Pcdata((char *)pcdata.rawData->content);
	else
		rawData=0;

	return *this;
}

SctsPcdata::operator char *()
{
	if (!IsString()) return 0;
	return (char *)rawData->content;
}

int SctsPcdata::GetLength()
{
	if (!rawData) return 0;
	return rawData->length;
}

bool SctsPcdata::IsUndef()
{
	if (!rawData) return false;
	return (rawData->contentType==SML_PCDATA_UNDEFINED);
}

bool SctsPcdata::IsMeta()
{
	if (!rawData) return false;
	return (rawData->content && rawData->contentType==SML_PCDATA_EXTENSION && rawData->extension==SML_EXT_METINF);
}

bool SctsPcdata::IsString()
{
	if (!rawData) return false;
	return (rawData->content && rawData->contentType==SML_PCDATA_OPAQUE || rawData->contentType==SML_PCDATA_STRING || rawData->contentType==SML_PCDATA_CDATA);
}

SctsMeta& SctsPcdata::GetMeta(SctsMeta& meta)
{
	if (IsMeta())
		meta.rawData=(SmlMetInfMetInfPtr_t)rawData->content;
	else
		meta.rawData=0;
	return meta;
}

char *SctsPcdata::GetString()
{
	char *pStr;
	if (!IsString()) return 0;

    /* Allocate the String */
    pStr=(char *)sctsMalloc((MemSize_t)(rawData->length+1));
    if (!pStr) return 0;
    
    /* Copy the string into the allocated data structure */
    sctsMemcpy(pStr,rawData->content,rawData->length);
    *(pStr + rawData->length) = '\0'; 
	return pStr;
}

int SctsPcdata::GetInt()
{
	if (!IsString()) return 0;
	return sctsStr2Int((char *)rawData->content);
}

void SctsPcdata::Clear()
{
	if (!rawData) return;
	sctsFree(rawData->content);
	rawData->content=0;
	rawData->length=0;
	rawData->contentType=SML_PCDATA_UNDEFINED;
}

SctsPcdata::SctsPcdata(SctsMeta& pMeta)
{
	rawData=(SmlPcdataPtr_t)sctsMalloc(sizeof(SmlPcdata_t));
	SCTSASSERT(rawData);
	rawData->contentType=SML_PCDATA_EXTENSION;
	rawData->extension=SML_EXT_METINF;
	rawData->content=pMeta.rawData;
}

SctsPcdata::SctsPcdata(char *pStr)
{
	SCTSASSERT(pStr);
	rawData=(SmlPcdataPtr_t)sctsMalloc(sizeof(SmlPcdata_t));
	rawData->contentType=SML_PCDATA_STRING;
	rawData->length=sctsStrlen(pStr);
	rawData->content=sctsStrdup(pStr);
	SCTSASSERT(rawData->content);
}

SctsPcdata::SctsPcdata(char *pStr,unsigned int size,SctsEncoding encoding)
{
	SCTSASSERT(pStr);
	rawData=(SmlPcdataPtr_t)sctsMalloc(sizeof(SmlPcdata_t));
	rawData->contentType=encoding==XML?SML_PCDATA_CDATA:SML_PCDATA_OPAQUE;
	rawData->length=size;
	rawData->content=sctsMalloc(sizeof(char)*size);
	sctsMemcpy(rawData->content,pStr,size);
	SCTSASSERT(rawData->content);
}

SctsPcdata::SctsPcdata(int i)
{
	char buffer[15];
	sctsInt2Str(i,buffer,10);
	rawData=smlString2Pcdata(buffer);
}

SctsPcdata::SctsPcdata(SmlPcdataPtr_t pPcdata)
{
	rawData=pPcdata;
}

/*****************************************************************
SctsTargetSource Definition
******************************************************************/
bool SctsTargetSource::operator!()
{
	return !rawData;
}

SctsTargetSource::operator bool()
{
	if (rawData) return true;
	return false;
}

void SctsTargetSource::SetLocURI(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->locURI,pPcdata);
}

SctsPcdata& SctsTargetSource::GetLocURI(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->locURI,pcdata);
}

void SctsTargetSource::SetLocName(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->locName,pPcdata);
}

SctsPcdata& SctsTargetSource::GetLocName(SctsPcdata &pcdata)
{
	SCTSRTKGETPCDATA(rawData->locName,pcdata);
}

SctsTargetSource::SctsTargetSource(sml_source_or_target_s *pTargetSource)
{
	rawData=pTargetSource;
}

SctsTargetSource::SctsTargetSource(char *pLocURI,char *pLocName)
{
	SCTSASSERT(pLocURI);
	rawData=(sml_source_or_target_s *)sctsMalloc(sizeof(sml_source_or_target_s));
	SCTSASSERT(rawData);
	rawData->locURI=smlString2Pcdata(pLocURI);
	if (pLocName)
		rawData->locName=smlString2Pcdata(pLocName);
	else
		rawData->locName=0;
}

/*****************************************************************
SctsMeta Definition
******************************************************************/
bool SctsMeta::operator!()
{
	return !rawData;
}

SctsMeta::operator bool()
{
	if (rawData) return true;
	return false;
}

void SctsMeta::SetType(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->type,pPcdata);
}

SctsPcdata& SctsMeta::GetType(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->type,pcdata);
}

void SctsMeta::SetFormat(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->format,pPcdata);
}

SctsPcdata& SctsMeta::GetFormat(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->format,pcdata);
}

void SctsMeta::SetMark(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->mark,pPcdata);
}

SctsPcdata& SctsMeta::GetMark(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->mark,pcdata);
}
void SctsMeta::SetVersion(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->version,pPcdata);
}

SctsPcdata& SctsMeta::GetVersion(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->version,pcdata);
}

void SctsMeta::SetNextNonce(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->nextnonce,pPcdata);
}

SctsPcdata& SctsMeta::GetNextNonce(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->nextnonce,pcdata);
}

void SctsMeta::SetAnchorLast(SctsPcdata *pPcdata)
{
	SCTSASSERT(rawData);
	if (rawData->anchor && rawData->anchor->last) smlFreePcdata(rawData->anchor->last);
	if (!pPcdata || !pPcdata->rawData)
	{
		if (rawData->anchor)
		{
			rawData->anchor->last=0;
			if (!rawData->anchor->next) 
			{
				smlFreeMetinfAnchor(rawData->anchor);
				rawData->anchor=0;
			}
		}
		return;
	}
	if (!rawData->anchor)
	{
		rawData->anchor=(SmlMetInfAnchorPtr_t)sctsMalloc(sizeof(SmlMetInfAnchor_t));
		rawData->anchor->next=0;
	}
	rawData->anchor->last=pPcdata->rawData;
}

SctsPcdata& SctsMeta::GetAnchorLast(SctsPcdata& pcdata)
{
	if (rawData && rawData->anchor && rawData->anchor->last)
		pcdata.rawData=rawData->anchor->last;
	else
		pcdata.rawData=0;
	return pcdata;
}

void SctsMeta::SetAnchorNext(SctsPcdata *pPcdata)
{
	SCTSASSERT(rawData);
	if (rawData->anchor && rawData->anchor->next) smlFreePcdata(rawData->anchor->next);
	if (!pPcdata || !pPcdata->rawData)
	{
		if (rawData->anchor)
		{
			rawData->anchor->next=0;
			if (!rawData->anchor->last) 
			{
				smlFreeMetinfAnchor(rawData->anchor);
				rawData->anchor=0;
			}
		}
		return;
	}
	if (!rawData->anchor)
	{
		rawData->anchor=(SmlMetInfAnchorPtr_t)sctsMalloc(sizeof(SmlMetInfAnchor_t));
		rawData->anchor->last=0;
	}
	rawData->anchor->next=pPcdata->rawData;
}

SctsPcdata& SctsMeta::GetAnchorNext(SctsPcdata& pcdata)
{
	if (rawData && rawData->anchor && rawData->anchor->next)
		pcdata.rawData=rawData->anchor->next;
	else
		pcdata.rawData=0;
	return pcdata;
}

void SctsMeta::SetMemFreeMem(int freeMem)
{
	SCTSASSERT(rawData);
	if (rawData->mem && rawData->mem->free) smlFreePcdata(rawData->mem->free);
	if (freeMem==-1)
	{
		if (rawData->mem)
		{
			rawData->mem->free=0;
			if (!rawData->mem->freeid && !rawData->mem->shared) 
			{
				smlFreeMetinfMem(rawData->mem);
				rawData->mem=0;
			}
		}
		return;
	}
	if (!rawData->mem)
	{
		rawData->mem=(SmlMetInfMemPtr_t)sctsMalloc(sizeof(SmlMetInfMem_t));
		rawData->mem->freeid=0;
		rawData->mem->shared=0;
	}
	rawData->mem->free=sctsInt2Pcdata(freeMem);
}

int SctsMeta::GetMemFreeMem()
{
	SCTSASSERT(rawData);
	if (!rawData->mem || !rawData->mem->free) return -1;
	return sctsPcdata2Int(rawData->mem->free);
}


void SctsMeta::SetMemFreeID(int freeID)
{
	SCTSASSERT(rawData);
	if (rawData->mem && rawData->mem->freeid) smlFreePcdata(rawData->mem->freeid);
	if (freeID==-1)
	{
		if (rawData->mem)
		{
			rawData->mem->freeid=0;
			if (!rawData->mem->free && !rawData->mem->shared) 
			{
				smlFreeMetinfMem(rawData->mem);
				rawData->mem=0;
			}
		}
		return;
	}
	if (!rawData->mem)
	{
		rawData->mem=(SmlMetInfMemPtr_t)sctsMalloc(sizeof(SmlMetInfMem_t));
		rawData->mem->free=0;
		rawData->mem->shared=0;
	}
	rawData->mem->freeid=sctsInt2Pcdata(freeID);
}

int SctsMeta::GetMemFreeID()
{
	SCTSASSERT(rawData);
	if (!rawData->mem || !rawData->mem->freeid) return -1;
	return sctsPcdata2Int(rawData->mem->freeid);
}

void SctsMeta::SetMaxMsgSize(int maxMsgSize)
{
	SCTSASSERT(rawData);
	if (rawData->maxmsgsize) smlFreePcdata(rawData->maxmsgsize);
	if (maxMsgSize==-1)
	{
		rawData->maxmsgsize=0;
		return;
	}
	rawData->maxmsgsize=sctsInt2Pcdata(maxMsgSize);
}

int SctsMeta::GetMaxMsgSize()
{
	if (!rawData || !rawData->maxmsgsize) return -1;
	return sctsPcdata2Int(rawData->maxmsgsize);
}

void SctsMeta::SetMaxObjSize(int maxObjSize)
{
	SCTSASSERT(rawData);
	if (rawData->maxobjsize) smlFreePcdata(rawData->maxobjsize);
	if (maxObjSize==-1)
	{
		rawData->maxobjsize=0;
		return;
	}
	rawData->maxobjsize=sctsInt2Pcdata(maxObjSize);
}

int SctsMeta::GetMaxObjSize()
{
	if (!rawData || !rawData->maxobjsize) return -1;
	return sctsPcdata2Int(rawData->maxobjsize);
}

void SctsMeta::SetSize(int size)
{
	SCTSASSERT(rawData);
	if (rawData->size) smlFreePcdata(rawData->size);
	if (size==-1)
	{
		rawData->size=0;
		return;
	}
	rawData->size=sctsInt2Pcdata(size);
}

int SctsMeta::GetSize()
{
	if (!rawData || !rawData->size) return -1;
	return sctsPcdata2Int(rawData->size);
}

void SctsMeta::SetEMI(SctsPcdataList *pPcdataList)
{
	SCTSRTKSETPCDATALIST(rawData->emi,pPcdataList);
}

SctsPcdataList& SctsMeta::GetEMI(SctsPcdataList& pcdataList)
{
	SCTSRTKGETPCDATALIST(rawData->emi,pcdataList);
}

bool SctsMeta::IsMemSharedMem()
{
	SCTSASSERT(rawData);
	if (rawData->mem && rawData->mem->shared) return true;
	return false;
}

void SctsMeta::IsMemSharedMem(bool shared)
{
	SCTSASSERT(rawData);
	if (rawData->mem && rawData->mem->shared) smlFreePcdata(rawData->mem->shared);
	if (!shared)
	{
		if (rawData->mem)
		{
			rawData->mem->shared=0;
			if (!rawData->mem->free && !rawData->mem->freeid) 
			{
				smlFreeMetinfMem(rawData->mem);
				rawData->mem=0;
			}
		}
		return;
	}
	if (!rawData->mem)
	{
		rawData->mem=(SmlMetInfMemPtr_t)sctsMalloc(sizeof(SmlMetInfMem_t));
		rawData->mem->free=0;
		rawData->mem->freeid=0;
	}
	rawData->mem->shared=smlString2Pcdata("1");
}

SctsMeta::SctsMeta(SmlMetInfMetInfPtr_t pMeta)
{
	rawData=pMeta;
}

SctsMeta::SctsMeta()
{
	rawData=(SmlMetInfMetInfPtr_t)sctsMalloc(sizeof(SmlMetInfMetInf_t));
	sctsMemset(rawData,0,sizeof(SmlMetInfMetInf_t));
}

/*****************************************************************
SctsCred Definition
******************************************************************/
bool SctsCred::operator!()
{
	return !rawData;
}

SctsCred::operator bool()
{
	if (rawData) return true;
	return false;
}

void SctsCred::SetMeta(SctsMeta *pMeta)
{
	SCTSRTKSETMETA(rawData->meta,pMeta);
}

SctsMeta& SctsCred::GetMeta(SctsMeta& meta)
{
	SCTSRTKGETMETA(rawData->meta,meta);
}

void SctsCred::SetData(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->data,pPcdata);
}

SctsPcdata& SctsCred::GetData(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->data,pcdata);
}

SctsCred::SctsCred(SmlCredPtr_t pCred)
{
	rawData=pCred;
}

SctsCred::SctsCred(SctsMeta *pMeta,SctsPcdata *pPcdata)
{
	SCTSASSERT(pMeta || pPcdata);
	rawData=(SmlCredPtr_t)sctsMalloc(sizeof(SmlCred_t));
	if (pMeta)
	{
		rawData->meta=(SmlPcdataPtr_t)sctsMalloc(sizeof(SmlPcdata_t));
		rawData->meta->contentType=SML_PCDATA_EXTENSION;
		rawData->meta->extension=SML_EXT_METINF;
		rawData->meta->content=pMeta->rawData;
	}
	else
		rawData->meta=0;
	if (pPcdata)
		rawData->data=pPcdata->rawData;
	else
		rawData->data=0;
}

/*****************************************************************
SctsItem Definition
******************************************************************/
bool SctsItem::operator!()
{
	return !rawData;
}

SctsItem::operator bool()
{
	if (rawData) return true;
	return false;
}

void SctsItem::SetMeta(SctsMeta *pMeta)
{
	SCTSRTKSETMETA(rawData->meta,pMeta);
}

SctsMeta& SctsItem::GetMeta(SctsMeta& meta)
{
	SCTSRTKGETMETA(rawData->meta,meta);
}

void SctsItem::SetData(SctsPcdata *pPcdata)
{
	SCTSRTKSETPCDATA(rawData->data,pPcdata);
}

SctsPcdata& SctsItem::GetData(SctsPcdata& pcdata)
{
	SCTSRTKGETPCDATA(rawData->data,pcdata);
}

void SctsItem::SetSource(char *pLocURI,char *pLocName)
{
	SCTSRTKSETTARGETSOURCE(rawData->source,pLocURI,pLocName);
}

SctsTargetSource& SctsItem::GetSource(SctsTargetSource& source)
{
	SCTSRTKGETTARGETSOURCE(rawData->source,source);
}

void SctsItem::SetTarget(char *pLocURI,char *pLocName)
{
	SCTSRTKSETTARGETSOURCE(rawData->target,pLocURI,pLocName);
}

SctsTargetSource& SctsItem::GetTarget(SctsTargetSource& target)
{
	SCTSRTKGETTARGETSOURCE(rawData->target,target);
}

void SctsItem::IsChunked(bool isChunked)
{
	if (rawData) 
	{
		if (isChunked)
			rawData->flags|=SmlMoreData_f;
		else
			rawData->flags^=SmlMoreData_f;
	}
}

bool SctsItem::IsChunked()
{
	return (rawData && (rawData->flags & SmlMoreData_f)==SmlMoreData_f);
}

SctsItem::SctsItem(SmlItemPtr_t pItem)
{
	rawData=pItem;
}

SctsItem::SctsItem(char *pSourceLocURI,char *pSourceLocName,char *pTargetLocURI,char *pTargetLocName,SctsMeta *pMeta,SctsPcdata *pData,bool isChunked)
{
	SCTSASSERT(pSourceLocURI || pTargetLocURI || pMeta || pData);
	rawData=(SmlItemPtr_t)sctsMalloc(sizeof(SmlItem_t));
	if (pSourceLocURI || pSourceLocName)
		rawData->source=SctsTargetSource(pSourceLocURI,pSourceLocName).rawData;
	else
		rawData->source=0;
	if (pTargetLocURI || pTargetLocName)
		rawData->target=SctsTargetSource(pTargetLocURI,pTargetLocName).rawData;
	else
		rawData->target=0;
	if (pMeta)
	{
		rawData->meta=(SmlPcdataPtr_t)sctsMalloc(sizeof(SmlPcdata_t));
		rawData->meta->contentType=SML_PCDATA_EXTENSION;
		rawData->meta->extension=SML_EXT_METINF;
		rawData->meta->content=pMeta->rawData;
	}
	else
		rawData->meta=0;
	if (pData)
		rawData->data=pData->rawData;
	else
		rawData->data=0;
	rawData->flags=0;
}

/*****************************************************************
SctsMapItem Definition
******************************************************************/
bool SctsMapItem::operator!()
{
	return !rawData;
}

SctsMapItem::operator bool()
{
	if (rawData) return true;
	return false;
}

void SctsMapItem::SetSource(char *pLocURI,char *pLocName)
{
	SCTSRTKSETTARGETSOURCE(rawData->source,pLocURI,pLocName);
}

SctsTargetSource& SctsMapItem::GetSource(SctsTargetSource& source)
{
	SCTSRTKGETTARGETSOURCE(rawData->source,source);
}

void SctsMapItem::SetTarget(char *pLocURI,char *pLocName)
{
	SCTSRTKSETTARGETSOURCE(rawData->target,pLocURI,pLocName);
}

SctsTargetSource& SctsMapItem::GetTarget(SctsTargetSource& target)
{
	SCTSRTKGETTARGETSOURCE(rawData->target,target);
}

SctsMapItem::SctsMapItem(SmlMapItemPtr_t pMapItem)
{
	rawData=pMapItem;
}

SctsMapItem::SctsMapItem(char *pSourceLocURI,char *pSourceLocName,char *pTargetLocURI,char *pTargetLocName)
{
	SCTSASSERT(pSourceLocURI && pTargetLocURI);
	rawData=(SmlMapItemPtr_t)sctsMalloc(sizeof(SmlMapItem_t));
	if (pSourceLocURI || pSourceLocName)
		rawData->source=SctsTargetSource(pSourceLocURI,pSourceLocName).rawData;
	else
		rawData->source=0;
	if (pTargetLocURI || pTargetLocName)
		rawData->target=SctsTargetSource(pTargetLocURI,pTargetLocName).rawData;
	else
		rawData->target=0;
}

#endif
