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

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.

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

/*
 * Copyright Notice
 * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication 
 * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., 
 * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001).
 * All Rights Reserved.
 * Implementation of all or part of any Specification may require 
 * licenses under third party intellectual property rights, 
 * including without limitation, patent rights (such a third party 
 * may or may not be a Supporter). The Sponsors of the Specification 
 * are not responsible and shall not be held responsible in any 
 * manner for identifying or failing to identify any or all such 
 * third party intellectual property rights.
 * 
 * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED 
 * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, 
 * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, 
 * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML 
 * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 
 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 
 * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., 
 * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY 
 * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF 
 * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF 
 * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, 
 * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH 
 * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
 * 
 * The above notice and this paragraph must be included on all copies 
 * of this document that are made.
 * 
 */


/*************************************************************************
 *  Definitions
 *************************************************************************/

/* Include Headers */
#include <smldef.h>
#include <sml.h>
#include <smlerr.h>
#include "libmem.h"
#include "libstr.h"
#include "wsm.h"
#include "mgr.h"



/* Used external functions */
#ifndef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
  extern Ret_t addInfo(InstanceInfoPtr_t pInfo);
  extern InstanceInfoPtr_t findInfo(InstanceID_t id);
  extern Ret_t removeInfo(InstanceID_t id);
#endif
SyncMLInfoPtr_t mgrGetSyncMLAnchor(void);


/* Prototypes of exported SyncML API functions */
SML_API Ret_t smlInitInstance(SmlCallbacksPtr_t callbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID);
SML_API Ret_t smlTerminateInstance (InstanceID_t id);
SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize);
SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes);
SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize);
SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes);
SML_API Ret_t smlSetCallbacks (InstanceID_t id, SmlCallbacksPtr_t pCallbacks);
SML_API Ret_t smlSetUserData (InstanceID_t id, VoidPtr_t pUserData);
#ifndef __SML_LITE__  /* these API calls are NOT included in the Toolkit lite version */
  SML_API Ret_t smlSetEncoding (InstanceID_t id, SmlEncoding_t encoding);
#endif



/* Private function prototypes */
Ret_t freeInstanceOptions (InstanceInfoPtr_t pInstanceInfo);
static Ret_t freeInstanceInfo (InstanceInfoPtr_t pInfo);
Ret_t mgrResetWorkspace (InstanceID_t id);
Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions);


/*************************************************************************
 *  Public SyncML API Functions
 *************************************************************************/


/**
 * FUNCTION:   smlInitInstance
 *
 * Creates a SyncML instance and assigns a corresponding workspace buffer in
 * which XML documents are assembled or parsed.
 * All callback functions implemented by a particular application are defined.
 * Instance specific options can be passed. This function has to be called 
 * before the first synchronization tasks can be performed. A reference valid
 * for a SyncML instance is returned.
 * An instance is active when processing a synchronization request
 * otherwise it is idle. An instance is terminated when smlTerminateInstance 
 * is called.
 *
 * IN:              SmlCallbacks_t
 *                  A structure holding references to the callback functions
 *                  implemented by the application
 *
 * IN:              SmlInstanceOptionsPtr_t
 *                  Option settings of a particular SyncML instance
 *
 * IN:              VoidPtr_t
 *                  UserData is a pointer to a void structure the application 
 *                  can pass into the SyncML Toolkit instance info. 
 *                  It will be returned to the application with every called 
 *                  callback function call!
 *                  NOTE: This is only a pointer, the memory object itself 
 *                  remains within the responsibility of the calling application.
 *                  The memory object will not be copied, moved or freed by the 
 *                  Toolkit.
 *
 * OUT:             InstanceID_t
 *                  Instance ID assigned to the initialized instance
 *
 * RETURN:          Ret_t
 *                  Error Code
 */
SML_API Ret_t smlInitInstance(SmlCallbacksPtr_t pCallbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t pInstanceInfo;
  Ret_t             rc;
  

  /* --- Check pOptions, which have been passed by the application --- */
  if (!pOptions || !pOptions->workspaceName)
	  return SML_ERR_WRONG_USAGE;

  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    /* if ONE instance is already initialized */
    if (mgrGetInstanceListAnchor()!=NULL) 
      return SML_ERR_WRONG_USAGE;
  #endif 
  
  /* --- check wether we already know about this instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
  pInstanceInfo = mgrGetInstanceListAnchor();
  #else
   pInstanceInfo = (InstanceInfoPtr_t) findInfo(*pInstanceID); 
  #endif

  /* --- bail outh when we already have a instance with that id --- */
  if (pInstanceInfo != NULL) return SML_ERR_WRONG_USAGE;


  /* --- Create a workspace for this instance --- */ 
  if ((rc = wsmCreate(pOptions->workspaceName, pOptions->workspaceSize, pInstanceID)) != SML_ERR_OK)
  	return rc;

  /* --- Create an instance info memory object --- */
  pInstanceInfo = (InstanceInfoPtr_t)smlLibMalloc((MemSize_t)sizeof(InstanceInfo_t));
  if (pInstanceInfo==NULL){
   wsmDestroy(pOptions->workspaceName);   
   return SML_ERR_NOT_ENOUGH_SPACE;
   }
   
  smlLibMemset(pInstanceInfo,0,(MemSize_t)sizeof(InstanceInfo_t));


  /* --- Set mandatory instance infos for this instance to defaults --- */
  pInstanceInfo->id=*pInstanceID;
  pInstanceInfo->status=MGR_IDLE;
  pInstanceInfo->encoderState=NULL;                  // no encoding in progress, currently not used
  pInstanceInfo->decoderState=NULL;                  // no decoding in progress, currently not used
  pInstanceInfo->workspaceState=NULL;                // to do: some workspace status info
  pInstanceInfo->nextInfo=NULL;


  /* --- Add instance infos memory object to the instance info list --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    mgrSetInstanceListAnchor(pInstanceInfo);
  #else
    rc = addInfo( pInstanceInfo );
    if (rc!=SML_ERR_OK) return rc;
  #endif 



  /* --- Set the values of instance Infos as defined by the calling application ---*/

  /* Set user data pointer */
  pInstanceInfo->userData=pUserData;
  /* Set callback functions implemented by applications */
  if (smlSetCallbacks(*pInstanceID, pCallbacks) != SML_ERR_OK) {
	  wsmDestroy(pOptions->workspaceName);
	  return rc;
   }

  smlSetCallbacks(*pInstanceID, pCallbacks);
  /* Set other application defined options for that instance */
  if (setInstanceOptions (*pInstanceID, pOptions) != SML_ERR_OK) {
 	  wsmDestroy(pOptions->workspaceName);
 	  return rc;
   }

   


  return SML_ERR_OK;
  
}



/**
 * FUNCTION:   smlTerminateInstance
 *
 * Terminates a SyncML instance. The instance info is removed from the instances
 * list. Allmemory allocated for the workspace and the options variables is freed.
 *
 * IN:              InstanceID_t
 *                  ID of the instance to be terminated
 *
 * RETURN:          Ret_t
 *                  Error Code
 */
SML_API Ret_t smlTerminateInstance (InstanceID_t id)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t pInstanceInfo;
  Ret_t             rc;


  /* --- Find that instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    pInstanceInfo = mgrGetInstanceListAnchor();
  #else
    pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
  #endif
  
  if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;

  /* --- Close the workspace --- */
  if (pInstanceInfo->instanceOptions != NULL) {
 	rc = wsmDestroy(pInstanceInfo->instanceOptions->workspaceName);
 	if (rc!=SML_ERR_OK) {
    //	  freeInstanceInfo(pInstanceInfo);
 	  return rc;
 	}
   }

  
  
  
  
  /* --- Delete instance info and options --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    mgrSetInstanceListAnchor(NULL);
  #else
    removeInfo(id);
  #endif
  
  freeInstanceInfo (pInstanceInfo);
  
  return SML_ERR_OK;
}



/**
 * FUNCTION:  smlSetCallbacks
 *
 * Sets new callback functions to an instance
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * IN:        SmlCallbacksPtr_t
 *            A structure holding references to the callback functions
 *            implemented by the application
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlSetCallbacks(InstanceID_t id, SmlCallbacksPtr_t pCallbacks)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t	pInstanceInfo;
  SmlCallbacksPtr_t    pCallbacksCopy;

  /* --- Check pCallbacks, which have been passed by the application --- */
  if (!pCallbacks)
    return SML_ERR_WRONG_USAGE;


  /* --- Find that instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    pInstanceInfo = mgrGetInstanceListAnchor();
  #else
    pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
  #endif

  if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;


  /* --- free old callback structure ---*/
  smlLibFree(pInstanceInfo->callbacks);


  /* --- Use a copy of pCoreOptions --- */
  pCallbacksCopy = (SmlCallbacksPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlCallbacks_t));
  if (pCallbacksCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE;
  smlLibMemcpy(pCallbacksCopy,pCallbacks,(MemSize_t)sizeof(SmlCallbacks_t));

  
	/* --- set new Callbacks --- */
	pInstanceInfo->callbacks = pCallbacksCopy;
  
	return SML_ERR_OK;
}



/**
 * FUNCTION:  smlSetUserData
 *
 * Sets a new Pointer to application specific user data, 
 * which is passed to all invoked callback functions
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * IN:        VoidPtr_t
 *            UserData is a pointer to a void structure the application 
 *            can pass into the SyncML Toolkit instance info. 
 *            It will be returned to the application with every called 
 *            callback function call!
 *            NOTE: This is only a pointer, the memory object itself 
 *            remains within the responsibility of the calling application.
 *            The memory object will not be copied, moved or freed by the 
 *            Toolkit.
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlSetUserData(InstanceID_t id, VoidPtr_t pUserData)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t	pInstanceInfo;


  /* --- Find that instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    pInstanceInfo = mgrGetInstanceListAnchor();
  #else
    pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
  #endif

  if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;


  /* --- free old callback structure ---*/
  pInstanceInfo->userData=pUserData;

	return SML_ERR_OK;
}


/**
 * FUNCTION:  smlSetEncoding
 *
 * Sets new encoding type for this Instance
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * IN:        SmlEncoding_t
 *            Type of Encoding to be used within this Instance
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
#ifndef __SML_LITE__  /* these API calls are NOT included in the Toolkit lite version */
SML_API Ret_t smlSetEncoding(InstanceID_t id, SmlEncoding_t encoding)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t	pInstanceInfo;

  /* --- Check pCallbacks, which have been passed by the application --- */
  if (encoding==SML_UNDEF)
    return SML_ERR_WRONG_USAGE;


  /* --- Find that instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    pInstanceInfo = mgrGetInstanceListAnchor();
  #else
    pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
  #endif

  if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;


  /* --- free old callback structure ---*/
  pInstanceInfo->instanceOptions->encoding = encoding;

  return SML_ERR_OK;
}
#endif




/**
 * FUNCTION:  smlLockReadBuffer
 *
 * Locks the workspace buffer, which is assigned to the given instance
 * for reading. After this function is called, the application has 
 * access to the workspace buffer, beginning at the address pReadPosition which 
 * is returned by this function. SyncML will not change the workspace 
 * buffer until smlUnlockReadBuffer is called.
 * pReadPosition returns a pointer to a valid position in the SyncML workspace 
 * buffer. The pointer can be used by the application for copying outgoing 
 * synchronization data from the buffer into some transport layer. usedSize 
 * retrieves the size of synchronization data currently stored in the 
 * workspace buffer beginning from the address to which pReadPosition points to. 
 * This information is needed by the application when copying XML code out 
 * of the buffer (while sending synchronization data)
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * OUT:       MemPtr_t              
 *            Workspace Pointer from which data can be read
 *
 * OUT:       MemSize_t              
 *            Size of used data in workspace which may be read
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize)
{
  /* --- Definitions --- */ 
  Ret_t rc;
  
  /* --- Lock Workspace exclusively for reading and get a "Read" pointer --- */
  rc = wsmLockH(id, SML_FIRST_DATA_ITEM, pReadPosition);
  if (rc!=SML_ERR_OK) return rc;
  
  /* --- Check, how much data has to be read ---*/
  rc = wsmGetUsedSize(id,usedSize);  

  if (rc!=SML_ERR_OK) return rc;
  
  return SML_ERR_OK;
}


/**
 * FUNCTION:  smlUnlockReadBuffer
 *
 * End the read access of the application to the workspace buffer. 
 * SyncML is now owner of the buffer again and is able to manipulate its contents. 
 * processedBytes passes the number of bytes, which the application has 
 * successfully read and processed (e.g. when the application has copied 
 * outgoing synchronization data from the workspace into a communication module). 
 * SyncML removes the given number of bytes from the workspace!
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * IN:        MemSize_t              
 *            Actually read and processed bytes
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes)
{
  /* --- Definitions --- */ 
  Ret_t rc;
  
  /* --- Pass the number of bytes which have been read --- */
  rc = wsmProcessedBytes (id,processedBytes);
  if (rc!=SML_ERR_OK) return rc;

  /* --- Unlock Workspace --- */
  rc = wsmUnlockH(id);
  if (rc!=SML_ERR_OK) return rc;

  return SML_ERR_OK;
}





/**
 * FUNCTION:  smlLockWriteBuffer
 *
 * Locks the workspace buffer, which is assigned to the given 
 * instance for writing. After this function is called, the 
 * application has access to the workspace buffer, beginning 
 * at the address pWritePosition which is returned by this 
 * function. SyncML will not change the workspace buffer until 
 * smlUnlockWriteBuffer is called.
 * pWritePosition returns a pointer to a valid position in the 
 * SyncML workspace buffer. The pointer can be used by the application 
 * for copying incoming synchronization data from some transport 
 * layer into the buffer. freeSize retrieves the maximum usable 
 * size of the workspace buffer beginning from the address to 
 * which pWritePosition points to. This information is needed by 
 * the application when copying XML code into the buffer (while 
 * receiving synchronization data)
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * OUT:       MemPtr_t              
 *            Workspace Pointer to which data can be written
 *
 * OUT:       MemSize_t              
 *            Max free Size of available space for data
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize)
{
  /* --- Definitions --- */ 
  Ret_t rc;
  
  /* --- Lock Workspace exclusively for writing and get a "Write" pointer --- */
  rc = wsmLockH(id, SML_FIRST_FREE_ITEM, pWritePosition);
  if (rc!=SML_ERR_OK) return rc;

  /* --- Check, how much free space is available for writing --- */
  rc = wsmGetFreeSize(id, freeSize);
  if (rc!=SML_ERR_OK) return rc;
  
  return SML_ERR_OK;
}




/**
 * FUNCTION:  smlUnlockWriteBuffer
 *
 * End the write access of the application to the workspace buffer. 
 * SyncML is now owner of the buffer again and is able to manipulate its 
 * contents. writtenBytes passes the number of bytes which have been 
 * written into the workspace buffer (e.g. when the application has copied 
 * incoming synchronization data from a communication module into the 
 * workspace). This information is needed by SyncML when processing received 
 * synchronization data.
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 *
 * IN:        MemSize_t              
 *            Actually written bytes
 *
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes)
{
  /* --- Definitions --- */ 
  Ret_t rc;
  
  if (writtenBytes > 0)
  {
    /* --- Pass the number of bytes which have been written --- */
    rc = wsmSetUsedSize(id,writtenBytes);
    if (rc!=SML_ERR_OK) return rc;
  }
  /* --- Unlock Workspace --- */
  rc = wsmUnlockH(id);
  if (rc!=SML_ERR_OK) return rc;

  return SML_ERR_OK;
}




/*************************************************************************
 *  SyncML internal functions 
 *************************************************************************/


/**
 * FUNCTION:  mgrResetWorkspace
 * Reset the Workspace Buffer position to the beginning of the workspace
 *
 * IN:        InstanceID_t              
 *            ID of the Instance
 * RETURN:    Return value,            
 *            SML_ERR_OK if successful
 */
Ret_t mgrResetWorkspace (InstanceID_t id) {
   return wsmReset (id);
}

/**
 * FUNCTION:   setInstanceOptions
 *
 * the options settings of an instance are set to a new value
 *
 * IN:              InstanceID_t
 *                  Instance ID assigned to the instance
 *
 * IN:              SmlInstanceOptionsPtr_t
 *                  New option settings of that particular SyncML instance
 *                  NOTE: only the encoding can be changed during life-time 
 *                  of an instance
 *                  The other parameters of the instance options 
 *                  (workspace size and name cannot be changed) 
 *
 * RETURN:          Ret_t
 *                  Error Code
 */
Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions)
{

  /* --- Definitions --- */
  InstanceInfoPtr_t         pInstanceInfo;
  SmlInstanceOptionsPtr_t      pOptionsCopy;


  /* --- Ckeck pOptions, which have been passed by the application --- */
  if (!pOptions || !pOptions->workspaceName|| (pOptions->encoding==SML_UNDEF))
	  return SML_ERR_WRONG_USAGE;


  /* --- Find that instance --- */
  #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    pInstanceInfo = mgrGetInstanceListAnchor();
  #else
    pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
  #endif

  if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;
  
  /* --- free old instance options ---*/
  freeInstanceOptions(pInstanceInfo);


  /* --- Use a copy of pCoreOptions --- */
  pOptionsCopy = (SmlInstanceOptionsPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlInstanceOptions_t));
  if (pOptionsCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE;
  smlLibMemcpy(pOptionsCopy,pOptions,(MemSize_t)sizeof(SmlInstanceOptions_t));
  pOptionsCopy->workspaceName=smlLibStrdup(pOptions->workspaceName);
  
  if (pOptionsCopy->workspaceName == NULL) {
	  pInstanceInfo->instanceOptions=NULL;
 	  smlLibFree(pOptionsCopy);
 	  return SML_ERR_NOT_ENOUGH_SPACE;
   }
   


  /* --- Assign the new options --- */
  pInstanceInfo->instanceOptions=pOptionsCopy;
  

  /* --- Let the new settingds take effect --- */
  /* --- Adjust workspace size ---*/
  /* --- Change workspace name ---*/
  // NOT SUPPORTED FOR YELLOW 

  return SML_ERR_OK;
}



/**
 * FUNCTION:  freeInstanceOptions
 * Free Instances Options
 *
 * RETURN:    InstanceInfoPtr_t         
 *            Pointer to the pInstance Info, which options should be freed
 */
Ret_t freeInstanceOptions (InstanceInfoPtr_t pInfo) {

  /* --- Delete instance options (if there are any) --- */
  if (pInfo->instanceOptions!=NULL) {
    if (pInfo->instanceOptions->workspaceName!=NULL) 
      smlLibFree(pInfo->instanceOptions->workspaceName);  // don't forget the substructures
    smlLibFree(pInfo->instanceOptions);    
  }

 return SML_ERR_OK;  
}

/**
 * FUNCTION: 
 * Free the memory of an removed Instance Info (including referenced sub structures) 
 *
 * IN:        InstanceID_t              
 *            ID of the InstanceInfo structure to be freed
 */
static Ret_t freeInstanceInfo(InstanceInfoPtr_t pInfo) {

	if (pInfo) {

		if (pInfo->workspaceState) 
			smlLibFree(pInfo->workspaceState);
		if (pInfo->encoderState) 
			smlLibFree(pInfo->encoderState);
		if (pInfo->decoderState)
			smlLibFree(pInfo->decoderState);
		if (pInfo->callbacks)
			smlLibFree(pInfo->callbacks);
      
   		freeInstanceOptions(pInfo);
    
		smlLibFree(pInfo);
	}
    
	return SML_ERR_OK;
}
