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

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.

********************************************************************/
/*************************************************************************/
/* module:          The XML Encoder source file                          */
/* file:            xltencxml.c                                          */
/* target system:   All                                                  */
/* target OS:       All                                                  */   
/*************************************************************************/

#include <define.h>
#ifdef __SML_XML__
/*************************************************************************/
/*  Definitions                                                          */
/*************************************************************************/

#include "xltencxml.h"
#include <libstr.h>
#include "xlttags.h"
#include <libmem.h>

/**
 * FUNCTION: xmlGenerateTag
 *
 * Generates a XML tag
 *
 * PRE-Condition:   valid parameters 
 *
 * POST-Condition:  the XML tag is written to the XML buffer
 *
 * IN:              tagId, the ID for the tag to generate (TN_ADD, ...)
 *                  tagType, the tag type (e.g. Begin Tag -> TT_BEG, ...)
 *                  attFlag, indicates if the encoded tag contain Attributes in namespace extensions
 *
 * IN/OUT:          pBufMgr, pointer to a structure containing buffer management elements
 * 
 * RETURN:          shows error codes of function, 
 *                  0, if OK
 */
Ret_t xmlGenerateTag(XltTagID_t tagId, XltTagType_t tagType, BufferMgmtPtr_t pBufMgr, SmlPcdataExtension_t attFlag)
{
  Ret_t _err;

  MemByte_t _begpar = XML_BEGPAR;
  MemByte_t _tagdel = XML_TAGDEL;
  MemByte_t _endpar = XML_ENDPAR;
  MemByte_t _nstagstart[] = XML_NSSTART;
  MemByte_t _nstagend[]   = XML_NSEND;


  String_t _tagstr;
  String_t _tagnsattr = NULL;

  if ((_tagstr = (String_t)smlLibMalloc(XML_MAX_TAGLEN)) == NULL) return SML_ERR_NOT_ENOUGH_SPACE;

  if ((_err = getTagString(tagId, _tagstr, attFlag)) != SML_ERR_OK)  { 
    smlLibFree(_tagstr);
    return _err;
  }

  if (!_tagstr)  {  // check again as _tagstr might be alterd in getTagString
    smlLibFree(_tagstr);
    return SML_ERR_XLT_INVAL_TAG_TYPE;
  }

    /* the <SyncML> tag _must_ have an xmlns attribute */
  if (attFlag != pBufMgr->smlActiveExt || tagId == TN_SYNCML) {
	  if (getExtName(attFlag, &_tagnsattr) != SML_ERR_OK) {
		  smlLibFree(_tagstr);
		  return  SML_ERR_XLT_INVAL_TAG_TYPE;
	  }
  }
  pBufMgr->smlActiveExt = attFlag;
  //check if content byte has to be added to the tag
  switch (tagType)
  {
    // set the end tag
    case TT_END:
    {
      if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break;
      if ((_err = xltAddToBuffer((MemPtr_t)(&_tagdel), 1, pBufMgr)) != SML_ERR_OK) break;      
      if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break;
      if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break;
      if (tagId == pBufMgr->switchExtTag) {
        pBufMgr->smlActiveExt = pBufMgr->smlLastExt;
        pBufMgr->smlCurExt    = pBufMgr->smlLastExt;
        pBufMgr->smlLastExt   = attFlag;
      }
      // just forget the stored number ob bytes for this end-tag since written now
	  pBufMgr->endTagSize -= (3 + smlLibStrlen(_tagstr));
      break;
    }    
    //Empty tag 
    case TT_ALL:
    {
      if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break;
      if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break;
      if (_tagnsattr) {
			  if ((_err = xltAddToBuffer((MemPtr_t)(&_nstagstart), 8, pBufMgr)) != SML_ERR_OK) break;
			  if ((_err = xltAddToBuffer((MemPtr_t)_tagnsattr, smlLibStrlen(_tagnsattr), pBufMgr)) != SML_ERR_OK) break;
			  if ((_err = xltAddToBuffer((MemPtr_t)&_nstagend, 1, pBufMgr)) != SML_ERR_OK) break;
			}
      if ((_err = xltAddToBuffer((MemPtr_t)(&_tagdel), 1, pBufMgr)) != SML_ERR_OK) break;      
	  if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break;      

      break;
    }
    //Only Begin Tag -> content follows -> content byte has to be added
    case TT_BEG:
    {
      if ((_err = xltAddToBuffer((MemPtr_t)(&_begpar), 1, pBufMgr)) != SML_ERR_OK) break;
      if ((_err = xltAddToBuffer((MemPtr_t)_tagstr, smlLibStrlen(_tagstr), pBufMgr)) != SML_ERR_OK) break;
      if (_tagnsattr) {
				if ((_err = xltAddToBuffer((MemPtr_t)&_nstagstart, 8, pBufMgr)) != SML_ERR_OK) break;
				if ((_err = xltAddToBuffer((MemPtr_t)_tagnsattr, smlLibStrlen(_tagnsattr), pBufMgr)) != SML_ERR_OK) break;
				if ((_err = xltAddToBuffer((MemPtr_t)&_nstagend, 1, pBufMgr)) != SML_ERR_OK) break;
			}
      if ((_err = xltAddToBuffer((MemPtr_t)(&_endpar), 1, pBufMgr)) != SML_ERR_OK) break;

	  // remember the number of byte that must follow for the according  end-tag
	  pBufMgr->endTagSize += (3 + smlLibStrlen(_tagstr));
      break;
    }
    default: 
    {
      smlLibFree(_tagstr);
	  smlLibFree(_tagnsattr);
      return SML_ERR_XLT_INVAL_TAG_TYPE;
    }
  }
  smlLibFree(_tagstr);
  smlLibFree(_tagnsattr);
  return _err;
}
#endif