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

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:          SyncML WorkSpace Manager                             */
/* file:            WSM.h                                                */
/* target system:   All                                                  */
/* target OS:       All                                                  */   
/*************************************************************************/

/**
 * Workspace Manager API <BR>
 * Manages the SyncML document in memory.
 *
 * @version  @label
 *
 */

#ifndef _WSM_H
#define _WSM_H

#include "smlerr.h"
#include "smldef.h"
#include "wsm_sm.h"


typedef struct WsmOptions_s {
  MemSize_t maxAvailMem;   // maximum amount of memory available for all wsm buffers
} WsmOptions_t;


#ifdef __SML_LITE__
#define MAX_WSM_BUFFERS 1
#else
#define MAX_WSM_BUFFERS 10
#endif


/** WSM internal buffer structure */
typedef struct WsmBuf_s {
  String_t    bufName;     // external name of buffer
  MemHandle_t memH;        // memory handle
  MemPtr_t    pFirstFree;  // pointer to first free element in buffer
  MemPtr_t    pFirstData;  // pointer to first data element in buffer
  MemSize_t   size;        // size of buffer
  MemSize_t   usedBytes;   // used bytes in buffer
  Byte_t      flags;
} WsmBuf_t;


/** WSM globals for use with global Anchor */
typedef struct WsmGlobals_s {
  Ret_t           wsmRet;          // last WSM return code
  Byte_t          initWasCalled;   // was wsmInit() called?
  WsmBuf_t        wsmBuf[MAX_WSM_BUFFERS];   
  Short_t         wsmIndex;        // Index of actual buffer
  WsmSmGlobals_t  wsmSm;           // WSM_SM global; device dependent!
} *WsmGlobalsPtr_t, WsmGlobals_t;


/**
 * FUNCTION: wsmInit
 *
 * Initializes all Workspace Manager related resources.<BR>
 * Should only be called once!
 *
 * PRE-Condition:   This is the first function call to WSM
 *
 * POST-Condition:  All WSM resources are initialized
 *
 * IN:      wsmOpts
 *          WSM options, valid options are:
 *          <UL>
 *          <LI> tbd
 *          </UL>
 * 
 * OUT:     wsmH
 *          Handle to new buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_OPTIONS, if wsmOpts is not valid
 *          SML_ERR_NOT_ENOUGH_SPACE, if not enough available memory
 *          SML_ERR_WRONG_USAGE, if wsmInit was already called
 */
Ret_t wsmInit (const WsmOptions_t *wsmOpts);


/**
 * FUNCTION: wsmCreate
 *
 * Creates and opens a new buffer with name bufName and size bufSize.<BR> 
 * If a buffer with name bufName already exists, the existing buffer 
 * is resized to bufSize.
 *
 * PRE-Condition:   bufSize > 0
 *
 * POST-Condition:  handle refers to buffer bufName; BufferSize = size
 *
 * IN:      bufName
 *          Name of buffer to be created
 * IN:      bufSize
 *          Size of buffer to be created
 * 
 * OUT:     wsmH
 *          Handle to new buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_SIZE, if bufSize <= 0
 *          SML_ERR_NOT_ENOUGH_SPACE, if available memory < bufSize
 *          SML_ERR_WSM_BUF_TABLE_FULL, if buffer table is full
 *          SML_ERR_WRONG_USAGE, if wsmInit wasn't called before
 *
 * @see  wsmDestroy
 */
Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH);


/**
 * FUNCTION: wsmOpen
 *
 * Open existing buffer with name bufName.
 *
 * PRE-Condition:   WSM knows bufName
 *
 * POST-Condition:  wsmH refers to buffer bufName
 *
 * IN:      bufName
 *          Name of buffer to be opened
 * 
 * OUT:     wsmH
 *          Handle to new buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_WRONG_PARAM, if bufName is unknown
 *
 * @see  wsmClose
 */
Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH);

 
/**
 * FUNCTION: wsmClose
 *
 * Close an open buffer.
 *
 * PRE-Condition:   handle is valid; handle is unlocked
 *
 * POST-Condition:  handle is not known to WSM any more
 *
 * IN:      wsmH
 *          Handle to the open buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *          SML_ERR_WRONG_USAGE, if handle was still locked
 *
 * @see  wsmOpen
 */
Ret_t wsmClose (MemHandle_t wsmH);


/**
 * FUNCTION: wsmDestroy
 *
 * Destroy existing buffer with name bufName.
 *
 * PRE-Condition:   WSM knows bufName; handle is unlocked
 *
 * POST-Condition:  buffer is not known to WSM any more; all resources 
 *                  connected to this buffer are freed
 *
 * IN:      bufName
 *          Name of buffer to be opened
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_WRONG_PARAM, if bufName is unknown to WSM
 *          SML_ERR_WRONG_USAGE, if handle was still locked
 *
 * @see  wsmCreate
 */
Ret_t wsmDestroy (String_t bufName);


/**
 * FUNCTION: wsmTerminate
 *
 * Terminate WSM; free all buffers and resources.
 *
 * PRE-Condition: all handles must be unlocked
 *
 * POST-Condition: all resources are freed
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_WRONG_USAGE, if a handle was still locked
 *
 */
Ret_t wsmTerminate (void);

/**
 * FUNCTION: wsmProcessedBytes
 *
 * Tell Workspace Manager the number of bytes already processed.
 *
 * PRE-Condition:   handle is locked; handle is valid;
 *                  noBytes <= wsmGetUsedSize
 *
 * POST-Condition:  noBytes starting at wsmGetPtr() position are deleted; 
 *                  remaining bytes are copied to 
 *                  wsmGetPtr(SML_FIRST_FREE_ITEM) position;
 *                  wsmGetUsedSize -= noBytes; wsmGetFreeSize += noBytes
 *
 * IN:      wsmH
 *          Handle to the open buffer
 * IN:      noBytes
 *          Number of bytes already processed from buffer.
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *          SML_ERR_WRONG_USAGE, if handle was not locked
 *          SML_ERR_INVALID_SIZE, if noBytes > wsmGetUsedSize
 *
 * @see  wsmGetFreeSize
 */
Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes);


/**
 * FUNCTION: wsmLockH
 *
 * Locks handle wsmH and get a pointer to the contents of wsmH. <BR>
 * RequestedPos describes the position in the buffer to which the returned 
 * pointer should point to. Valid values are: 
 * <UL>
 *   <LI> SML_FIRST_DATA_ITEM
 *   <LI> SML_FIRST_FREE_ITEM
 * </UL>
 *
 * PRE-Condition:   handle is unlocked; handle is valid
 *
 * POST-Condition:  handle is locked; points to first data item, 
 *                  or first free item.
 *
 * IN:      wsmH
 *          Handle to the open buffer
 * IN:      requestedPos
 *          Requested position of the returned pointer
 *          <UL>
 *            <LI> SML_FIRST_DATA_ITEM : points to first data entry
 *            <LI> SML_FIRST_FREE_ITEM : points to first free entry
 *          </UL>
 * 
 * OUT:     pMem
 *          Pointer to requested memory          
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *          SML_ERR_WRONG_USAGE, if handle was still locked
 *          SML_ERR_UNSPECIFIC, if requested position is unknown, or lock failed
 *
 * @see  wsmUnlockH
 */
Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos,
		MemPtr_t *pMem);


/**
 * FUNCTION: wsmGetFreeSize
 *
 * Returns the remaining unused bytes in the buffer.
 *
 * PRE-Condition:   handle is valid
 *
 * POST-Condition:  wsmGetFreeSize = BufferSize - wsmGetUsedSize
 *
 * IN:      wsmH
 *          Handle to the open buffer
 *
 * OUT:     freeSize
 *          Number of bytes which are unused in this buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *
 * @see  wsmGetUsedSize
 * @see  wsmProcessedBytes
 */
Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize);


/**
 * FUNCTION: wsmGetUsedSize
 *
 * Returns the number of bytes used in the buffer.
 *
 * PRE-Condition:   handle is valid
 *
 * POST-Condition:  usedSize = BufferSize - wsmGetFreeSize
 *
 * IN:      wsmH
 *          Handle to the open buffer
 *
 * OUT:     usedSize
 *          Number of bytes which are already used in this buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *
 * @see  wsmGetFreeSize
 * @see  wsmSetUsedSize
 */
Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize);


/**
 * FUNCTION: wsmUnlockH
 *
 * Unlock handle wsmH. <BR>
 * After this call all pointers to this memory handle are invalid 
 * and should no longer be used.
 *
 * PRE-Condition:   handle is locked; handle is valid
 *
 * POST-Condition:  handle is unlocked
 *
 * OUT:     wsmH
 *          Handle to unlock
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *          SML_ERR_WRONG_USAGE, if handle was not locked
 *          SML_ERR_UNSPECIFIC, unlock failed
 *
 * @see  wsmLockH
 */
Ret_t wsmUnlockH (MemHandle_t wsmH);


/**
 * FUNCTION: wsmSetUsedSize
 *
 * Tell Workspace how many data were written into buffer.
 *
 * PRE-Condition:   handle is valid; usedSize <= wsmGetFreeSize; handle is 
 *                  locked
 *
 * POST-Condition:  wsmGetUsedSize += usedSize; wsmGetFreeSize -= usedSize;
 *                  instancePtr += usedSize;
 *
 * IN:      wsmH
 *          Handle to the open buffer
 * IN:      usedSize
 *          Number of bytes which were written into buffer
 *
 * RETURN:  SML_ERR_OK, if O.K.
 *          SML_ERR_INVALID_HANDLE, if handle was invalid
 *          SML_ERR_INVALID_SIZE, if usedSize <= wsmGetFreeSize
 *
 * @see  wsmGetUsedSize
 */
Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize);
 
/**
 * FUNCTION: wsmReset
 *
 * Reset the Workspace
 *
 * PRE-Condition:   -
 *
 * POST-Condition:  all data is lost. The FirstFree Position equals 
 * the First Data position
 *
 * IN:      wsmH
 *          Handle to the open buffer
 * 
 * RETURN:  SML_ERR_OK, if O.K.
 *
 */
Ret_t wsmReset (MemHandle_t wsmH) ;




#endif
