Home | History | Annotate | Download | only in src
      1 /*************************************************************************/
      2 /* module:          SyncML WorkSpace Manager                             */
      3 /* file:            WSM.c                                                */
      4 /* target system:   All                                                  */
      5 /* target OS:       All                                                  */
      6 /*************************************************************************/
      7 
      8 
      9 /*
     10  * Copyright Notice
     11  * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication
     12  * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc.,
     13  * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001).
     14  * All Rights Reserved.
     15  * Implementation of all or part of any Specification may require
     16  * licenses under third party intellectual property rights,
     17  * including without limitation, patent rights (such a third party
     18  * may or may not be a Supporter). The Sponsors of the Specification
     19  * are not responsible and shall not be held responsible in any
     20  * manner for identifying or failing to identify any or all such
     21  * third party intellectual property rights.
     22  *
     23  * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED
     24  * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM,
     25  * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA,
     26  * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML
     27  * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
     28  * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
     29  * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
     30  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
     31  * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO.,
     32  * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY
     33  * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF
     34  * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF
     35  * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL,
     36  * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH
     37  * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED
     38  * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
     39  *
     40  * The above notice and this paragraph must be included on all copies
     41  * of this document that are made.
     42  *
     43  */
     44 
     45 
     46 /**
     47  * Workspace Manager API <BR>
     48  * Manages the SyncML document in memory.
     49  *
     50  * @version  @label
     51  *
     52  *
     53  */
     54 
     55 
     56 #ifndef NOWSM
     57 // if no WSM, we can leave this one out completely
     58 
     59 /*************************************************************************/
     60 /*  Definitions                                                          */
     61 /*************************************************************************/
     62 
     63 #include "wsm.h"
     64 
     65 #include "wsm_sm.h"
     66 #include "smldef.h"
     67 #include "libmem.h"
     68 #include "libstr.h"
     69 #include "liblock.h" // for THREADDEBUGPRINTF %%% luz
     70 #include "mgr.h"   // for global anchor
     71 
     72 
     73 /** WSM buffer flags */
     74 #define  WSM_VALID_F     (Byte_t) 0x01
     75 #define  WSM_LOCKED_F    (Byte_t) 0x02
     76 
     77 #define  WSM_MEMH_UNUSED   -1
     78 
     79 #ifndef __SML_LITE__
     80 
     81 /* Global Vars */
     82 /* =========== */
     83 
     84 /* defines for convient use of global anchor */
     85 
     86 #define wsmRet          (mgrGetSyncMLAnchor())->wsmGlobals->wsmRet
     87 #define initWasCalled   (mgrGetSyncMLAnchor())->wsmGlobals->initWasCalled
     88 #define maxWsmAvailMem     (mgrGetSyncMLAnchor())->syncmlOptions->maxWorkspaceAvailMem
     89 #define wsmBuf          (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf
     90 #define wsmIndex        (mgrGetSyncMLAnchor())->wsmGlobals->wsmIndex
     91 
     92 void createDataStructs(void);
     93 
     94 void createDataStructs() {
     95   if ( (mgrGetSyncMLAnchor())->wsmGlobals == NULL ) {
     96     if ( ((mgrGetSyncMLAnchor())->wsmGlobals=smlLibMalloc(sizeof(WsmGlobals_t))) == 0 ) {
     97       return;
     98     }
     99     smlLibMemset((mgrGetSyncMLAnchor())->wsmGlobals, 0, sizeof(WsmGlobals_t));
    100     wsmRet = 0;
    101     initWasCalled = 0;
    102     wsmIndex = 0;
    103 #ifdef __ANSI_C__
    104     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;
    105 #endif
    106 #ifdef __PALM_OS__
    107     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH = 0;
    108     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked = 0;
    109 #endif
    110 #ifdef __EPOC_OS__
    111     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;
    112 #endif
    113   }
    114 }
    115 #define freeDataStructs() smlLibFree((mgrGetSyncMLAnchor())->wsmGlobals)
    116 
    117 
    118 /* private functions prototypes */
    119 static Short_t getNextFreeEntry();
    120 static Short_t lookup(MemHandle_t memH);
    121 static MemHandle_t nameToHandle(String_t name);
    122 static Short_t deleteBufferHandle(MemHandle_t memH);
    123 static Short_t resetBufferGlobals(MemHandle_t memH);
    124 static Byte_t isValidMemH(MemHandle_t memH);
    125 static Byte_t isLockedMemH(MemHandle_t memH);
    126 static Byte_t isMemAvailable(MemSize_t memToAlloc);
    127 
    128 
    129 
    130 
    131 /*************************************************************************/
    132 /*  Internal Functions                                                   */
    133 /*************************************************************************/
    134 
    135 
    136 
    137 /**
    138  * Get next free buffer entry.
    139  * Returns index of next free entry, or -1 if buffer table is full.
    140  */
    141 static Short_t getNextFreeEntry() {
    142   Short_t i;
    143 
    144   for ( i=0; i < MAX_WSM_BUFFERS; ++i )
    145     if ( wsmBuf[i].memH == WSM_MEMH_UNUSED )
    146       return i;
    147 
    148   return -1;
    149 }
    150 
    151 
    152 
    153 /**
    154  * Get buffer table index for memH.
    155  * Returns -1 if memH not found.
    156  */
    157 static Short_t lookup(MemHandle_t memH) {
    158   Short_t i;
    159 
    160   // first check cache
    161   if ( wsmBuf[wsmIndex].memH == memH )
    162     return wsmIndex;
    163 
    164   // search through buffer
    165   for ( i=0; (i < MAX_WSM_BUFFERS) && (wsmBuf[i].memH != memH); ++i )
    166     ;
    167   if ( i < MAX_WSM_BUFFERS ) {
    168     wsmIndex = i;
    169     return i;
    170   }
    171   else {
    172     return -1;     // memH not found
    173   }
    174 }
    175 
    176 
    177 /**
    178  * Find memory handle corresponding to name.
    179  * Return WSM_MEMH_UNUSED, if name not found in wsmBuf.
    180  */
    181 static MemHandle_t nameToHandle(String_t name) {
    182   int i;
    183 
    184   // first check cache
    185   if ( (wsmBuf[wsmIndex].bufName != NULL) &&
    186        (smlLibStrcmp(wsmBuf[wsmIndex].bufName, name) == 0) )
    187     return wsmBuf[wsmIndex].memH;
    188 
    189   // search through buffer
    190   for ( i=0; ((i < MAX_WSM_BUFFERS) &&
    191 	      (wsmBuf[i].bufName == NULL ? 1 :
    192 	       smlLibStrcmp(wsmBuf[i].bufName, name) != 0)); ++i )
    193     ;
    194   if ( i < MAX_WSM_BUFFERS )
    195     return wsmBuf[i].memH;
    196   else {
    197     return WSM_MEMH_UNUSED;     // name not found
    198   }
    199 }
    200 
    201 
    202 
    203 /**
    204  * Delete memory handle from buffer.
    205  * Return -1, if handle not found.
    206  */
    207 static Short_t deleteBufferHandle(MemHandle_t memH) {
    208   if ( (wsmIndex = lookup(memH)) < 0 )
    209     return -1;  // handle not found
    210 
    211   // reset the values
    212   wsmBuf[wsmIndex].memH = WSM_MEMH_UNUSED;
    213   wsmBuf[wsmIndex].pFirstFree = NULL;
    214   wsmBuf[wsmIndex].pFirstData = NULL;
    215   wsmBuf[wsmIndex].size      = 0;
    216   wsmBuf[wsmIndex].usedBytes = 0;
    217   //wsmBuf[wsmIndex].flags     = ~WSM_VALID_F;
    218   wsmBuf[wsmIndex].flags     = ((Byte_t) ~WSM_VALID_F);
    219   smlLibFree(wsmBuf[wsmIndex].bufName);   // free mem
    220   wsmBuf[wsmIndex].bufName   = NULL;
    221 
    222   return 0;
    223 }
    224 
    225 
    226 /**
    227  * Reset values in buffer table for entry memH.
    228  * If memH doesn't exist create an entry.
    229  * Return index to memH in buffer table,
    230  * or -1 if table is full
    231  */
    232 static Short_t resetBufferGlobals(MemHandle_t memH) {
    233   if ( (wsmIndex = lookup(memH)) < 0 ) {
    234     // create new one
    235     if ( (wsmIndex = getNextFreeEntry()) < 0 )
    236       return -1;  // buffer table full
    237     wsmBuf[wsmIndex].memH = memH;
    238   } else
    239     // use existing one, which has to be reset prior usage
    240     smlLibFree(wsmBuf[wsmIndex].bufName);   // free mem
    241 
    242   // reset the values
    243   wsmBuf[wsmIndex].pFirstFree = NULL;
    244   wsmBuf[wsmIndex].pFirstData = NULL;
    245   wsmBuf[wsmIndex].size      = 0;
    246   wsmBuf[wsmIndex].usedBytes = 0;
    247   wsmBuf[wsmIndex].flags     = WSM_VALID_F;
    248   wsmBuf[wsmIndex].bufName   = NULL;
    249 
    250   return wsmIndex;
    251 }
    252 
    253 
    254 static Byte_t isValidMemH(MemHandle_t memH) {
    255   Short_t i;
    256   i = lookup(memH);
    257   if (i < 0)
    258   {
    259     return 0;
    260   }else{
    261     return (Byte_t) (wsmBuf[i].flags & WSM_VALID_F);
    262   }
    263 }
    264 
    265 static Byte_t isLockedMemH(MemHandle_t memH) {
    266   Short_t i;
    267   i = lookup(memH);
    268   if (i < 0)
    269   {
    270     return 0;
    271   }else{
    272     return (Byte_t) (wsmBuf[i].flags & WSM_LOCKED_F);
    273   }
    274 }
    275 
    276 static Byte_t isMemAvailable(MemSize_t memToAlloc) {
    277   int i;
    278   MemSize_t actMem = memToAlloc;
    279   if ( maxWsmAvailMem == 0 )
    280     return 1;  // no memsize restrictions
    281   for (i=0; i < MAX_WSM_BUFFERS; ++i) {
    282     if ( wsmBuf[i].memH != WSM_MEMH_UNUSED )
    283       actMem += wsmBuf[i].size;
    284   }
    285   return ((Byte_t)(actMem <= maxWsmAvailMem));
    286 }
    287 
    288 
    289 
    290 /*************************************************************************/
    291 /*  External Functions                                                   */
    292 /*************************************************************************/
    293 
    294 
    295 
    296 /**
    297  * FUNCTION: wsmInit
    298  *
    299  * Initializes all Workspace Manager related resources.<BR>
    300  * Should only be called once!
    301  *
    302  * PRE-Condition:   This is the first function call to WSM
    303  *
    304  * POST-Condition:  All WSM resources are initialized
    305  *
    306  * IN:      wsmOpts
    307  *          WSM options, valid options are:
    308  *          <UL>
    309  *          <LI> maxAvailMem<BR>
    310  *               Maximal amount of memory which wsm can use for the buffers<BR>
    311  *               0 == no limitation
    312  *          </UL>
    313  *
    314  * OUT:     wsmH
    315  *          Handle to new buffer
    316  *
    317  * RETURN:  SML_ERR_OK, if O.K.
    318  *          SML_ERR_INVALID_OPTIONS, if wsmOpts is not valid
    319  *          SML_ERR_NOT_ENOUGH_SPACE, if not enough available memory
    320  *          SML_ERR_WRONG_USAGE, if wsmInit was already called
    321  */
    322 Ret_t wsmInit (const WsmOptions_t *wsmOpts) {
    323   int i;
    324 
    325   // create global datastructs
    326   createDataStructs();
    327 
    328   if (NULL == mgrGetSyncMLAnchor()->wsmGlobals) {
    329  	  return SML_ERR_NOT_ENOUGH_SPACE;
    330    }
    331 
    332   // check if init was already called
    333   if ( initWasCalled )
    334     return SML_ERR_WRONG_USAGE;
    335 
    336   // check options
    337   if ( wsmOpts != NULL ) {
    338     if ( wsmOpts->maxAvailMem > 0 ) {
    339       maxWsmAvailMem = wsmOpts->maxAvailMem;
    340     }
    341   }
    342 
    343   // init resources
    344   for ( i=0; i < MAX_WSM_BUFFERS; ++i )
    345     wsmBuf[i].memH = WSM_MEMH_UNUSED;
    346   wsmIndex = 0;
    347   initWasCalled = (Byte_t) 1;
    348 
    349   return wsmRet=SML_ERR_OK;
    350 }
    351 
    352 
    353 /**
    354  * FUNCTION: wsmCreate
    355  *
    356  * Creates and opens a new buffer with name bufName and size bufSize.<BR>
    357  * If a buffer with name bufName already exists, the existing buffer
    358  * is resized to bufSize.
    359  *
    360  * PRE-Condition:   bufSize > 0
    361  *
    362  * POST-Condition:  handle refers to buffer bufName; BufferSize = size
    363  *
    364  * IN:      bufName
    365  *          Name of buffer to be created
    366  * IN:      bufSize
    367  *          Size of buffer to be created
    368  *
    369  * OUT:     wsmH
    370  *          Handle to new buffer
    371  *
    372  * RETURN:  SML_ERR_OK, if O.K.
    373  *          SML_ERR_INVALID_SIZE, if bufSize <= 0
    374  *          SML_ERR_NOT_ENOUGH_SPACE, if available memory < bufSize
    375  *          SML_ERR_WSM_BUF_TABLE_FULL, if buffer table is full
    376  *          SML_ERR_WRONG_USAGE, if wsmInit wasn't called before
    377  *
    378  * @see  wsmDestroy
    379  */
    380 Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH) {
    381 
    382   *wsmH = 0;    // 0 in case of error
    383 
    384   if ( ! initWasCalled )
    385     return SML_ERR_WRONG_USAGE;
    386 
    387   // check buffer space
    388   if ( getNextFreeEntry() == -1 ) {
    389     return wsmRet=SML_ERR_WSM_BUF_TABLE_FULL;
    390   }
    391   // check for maxMemAvailable
    392   if ( ! isMemAvailable(bufSize) ) {
    393     return SML_ERR_NOT_ENOUGH_SPACE;
    394   }
    395 
    396   // create buffer
    397   if ( (wsmRet = smCreate(bufName, bufSize, wsmH)) != SML_ERR_OK ) {
    398     if ( wsmRet == SML_ERR_WRONG_USAGE ) {    // buffer already exists
    399       // resize existing buffer
    400       // open buffer
    401       if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) {
    402       	return wsmRet=SML_ERR_NOT_ENOUGH_SPACE;
    403       }
    404       // resize buffer
    405       if ( (wsmRet = smSetSize(*wsmH, bufSize)) != SML_ERR_OK ) {
    406       	return wsmRet=SML_ERR_NOT_ENOUGH_SPACE;
    407       }
    408     }
    409     else {
    410       return wsmRet;
    411     }
    412   }
    413 
    414   // reset buffer vars
    415   wsmIndex = resetBufferGlobals(*wsmH);
    416 
    417   // set buffer vars
    418   wsmBuf[wsmIndex].size = bufSize;
    419   wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName);
    420 
    421    if (wsmBuf[wsmIndex].bufName == NULL) {
    422  	  smClose(*wsmH);
    423  	  smDestroy(bufName);
    424  	  return wsmRet=SML_ERR_NOT_ENOUGH_SPACE;
    425    }
    426 
    427 
    428   return wsmRet=SML_ERR_OK;
    429 }
    430 
    431 
    432 /**
    433  * FUNCTION: wsmOpen
    434  *
    435  * Open existing buffer with name bufName.
    436  *
    437  * PRE-Condition:   WSM knows bufName
    438  *
    439  * POST-Condition:  wsmH refers to buffer bufName
    440  *
    441  * IN:      bufName
    442  *          Name of buffer to be opened
    443  *
    444  * OUT:     wsmH
    445  *          Handle to new buffer
    446  *
    447  * RETURN:  SML_ERR_OK, if O.K.
    448  *          SML_WRONG_PARAM, if bufName is unknown
    449  *
    450  * @see  wsmClose
    451  */
    452 Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH){
    453 
    454   // open buffer
    455   if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) {
    456     return wsmRet;
    457   }
    458 
    459   // reset buffer vars
    460   wsmIndex = resetBufferGlobals(*wsmH);
    461 
    462   // set buf vars
    463   wsmRet = smGetSize(*wsmH, &wsmBuf[wsmIndex].size);
    464   wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName);
    465 
    466   return wsmRet=SML_ERR_OK;
    467 }
    468 
    469 
    470 /**
    471  * FUNCTION: wsmClose
    472  *
    473  * Close an open buffer.
    474  *
    475  * PRE-Condition:   handle is valid; handle is unlocked
    476  *
    477  * POST-Condition:  handle is not known to WSM any more
    478  *
    479  * IN:      wsmH
    480  *          Handle to the open buffer
    481  *
    482  * RETURN:  SML_ERR_OK, if O.K.
    483  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    484  *          SML_ERR_WRONG_USAGE, if handle was still locked
    485  *
    486  * @see  wsmOpen
    487  */
    488 Ret_t wsmClose (MemHandle_t wsmH) {
    489 
    490   // check if handle is invalid
    491   if ( ! isValidMemH(wsmH) ) {
    492     return wsmRet=SML_ERR_INVALID_HANDLE;
    493   }
    494 
    495   // close handle
    496   if ( (wsmRet = smClose(wsmH)) != SML_ERR_OK ) {
    497     return wsmRet;
    498   }
    499   wsmRet = deleteBufferHandle(wsmH);
    500 
    501   return wsmRet=SML_ERR_OK;
    502 }
    503 
    504 
    505 /**
    506  * FUNCTION: wsmDestroy
    507  *
    508  * Destroy existing buffer with name bufName.
    509  *
    510  * PRE-Condition:   WSM knows bufName; handle is unlocked
    511  *
    512  * POST-Condition:  buffer is not known to WSM any more; all resources
    513  *                  connected to this buffer are freed
    514  *
    515  * IN:      bufName
    516  *          Name of buffer to be opened
    517  *
    518  * RETURN:  SML_ERR_OK, if O.K.
    519  *          SML_ERR_WRONG_PARAM, if bufName is unknown to WSM
    520  *          SML_ERR_WRONG_USAGE, if handle was still locked
    521  *
    522  * @see  wsmCreate
    523  */
    524 Ret_t wsmDestroy (String_t bufName) {
    525 
    526   // free resources
    527   if ( (wsmRet = wsmClose(nameToHandle(bufName))) != SML_ERR_OK ) {
    528     return wsmRet;
    529   }
    530 
    531   // free buffer
    532   if ( (wsmRet = smDestroy(bufName)) != SML_ERR_OK ) {
    533     return wsmRet;
    534   }
    535 
    536   return wsmRet=SML_ERR_OK;
    537 }
    538 
    539 
    540 /**
    541  * FUNCTION: wsmTerminate
    542  *
    543  * Terminate WSM; free all buffers and resources.
    544  *
    545  * PRE-Condition: all handles must be unlocked
    546  *
    547  * POST-Condition: all resources are freed
    548  *
    549  * RETURN:  SML_ERR_OK, if O.K.
    550  *          SML_ERR_WRONG_USAGE, if a handle was still locked
    551  *
    552  */
    553 Ret_t wsmTerminate (void) {
    554   int i;
    555 
    556   // free all WSM resources
    557   for (i=0; i < MAX_WSM_BUFFERS; ++i) {
    558     if ( wsmBuf[i].memH != WSM_MEMH_UNUSED )
    559       if ( wsmDestroy(wsmBuf[i].bufName) == SML_ERR_WRONG_USAGE ) {
    560 	return SML_ERR_WRONG_USAGE;
    561       }
    562   }
    563 
    564   // free global DataStructs
    565   freeDataStructs();
    566 
    567   return SML_ERR_OK;
    568 }
    569 
    570 
    571 /**
    572  * FUNCTION: wsmProcessedBytes
    573  *
    574  * Tell Workspace Manager the number of bytes already processed.
    575  *
    576  * PRE-Condition:   handle is locked; handle is valid;
    577  *                  noBytes <= wsmGetUsedSize
    578  *
    579  * POST-Condition:  noBytes starting at wsmGetPtr() position are deleted;
    580  *                  remaining bytes are copied to
    581  *                  wsmGetPtr(SML_FIRST_FREE_ITEM) position;
    582  *                  wsmGetUsedSize -= noBytes; wsmGetFreeSize += noBytes
    583  *
    584  * IN:      wsmH
    585  *          Handle to the open buffer
    586  * IN:      noBytes
    587  *          Number of bytes already processed from buffer.
    588  *
    589  * RETURN:  SML_ERR_OK, if O.K.
    590  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    591  *          SML_ERR_WRONG_USAGE, if handle was not locked
    592  *          SML_ERR_INVALID_SIZE, if noBytes > wsmGetUsedSize
    593  *
    594  * @see  wsmGetFreeSize
    595  */
    596 Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes) {
    597 
    598   // check if handle is invalid
    599   if ( ! isValidMemH(wsmH) ) {
    600     return wsmRet=SML_ERR_INVALID_HANDLE;
    601   }
    602   // check if handle is unlocked
    603   if ( ! isLockedMemH(wsmH) ) {
    604     return wsmRet=SML_ERR_WRONG_USAGE;
    605   }
    606 
    607   wsmIndex = lookup(wsmH);
    608 
    609   if ( noBytes > wsmBuf[wsmIndex].usedBytes ) {
    610     return wsmRet=SML_ERR_INVALID_SIZE;
    611   }
    612 
    613   // adapt usedSize
    614   wsmBuf[wsmIndex].usedBytes -= noBytes;
    615 
    616   // move memory
    617   // check return ?????
    618   smlLibMemmove(wsmBuf[wsmIndex].pFirstData,
    619 	  (wsmBuf[wsmIndex].pFirstData + noBytes),
    620 	  wsmBuf[wsmIndex].usedBytes);
    621 
    622   // move pFirstFree
    623   wsmBuf[wsmIndex].pFirstFree -= noBytes;
    624 
    625   return wsmRet=SML_ERR_OK;
    626 }
    627 
    628 
    629 /**
    630  * FUNCTION: wsmLockH
    631  *
    632  * Locks handle wsmH and get a pointer to the contents of wsmH. <BR>
    633  * RequestedPos describes the position in the buffer to which the returned
    634  * pointer should point. Valid values are:
    635  * <UL>
    636  *   <LI> SML_FIRST_DATA_ITEM
    637  *   <LI> SML_FIRST_FREE_ITEM
    638  * </UL>
    639  *
    640  * PRE-Condition:   handle is unlocked; handle is valid
    641  *
    642  * POST-Condition:  handle is locked; points to first data item,
    643  *                  or first free item.
    644  *
    645  * IN:      wsmH
    646  *          Handle to the open buffer
    647  * IN:      requestedPos
    648  *          Requested position of the returned pointer
    649  *          <UL>
    650  *            <LI> SML_FIRST_DATA_ITEM : points to first data entry
    651  *            <LI> SML_FIRST_FREE_ITEM : points to first free entry
    652  *          </UL>
    653  *
    654  * OUT:     pMem
    655  *          Pointer to requested memory
    656  *
    657  * RETURN:  SML_ERR_OK, if O.K.
    658  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    659  *          SML_ERR_WRONG_USAGE, if handle was still locked
    660  *          SML_ERR_UNSPECIFIC, if requested position is unknown, or lock failed
    661  *
    662  * @see  wsmUnlockH
    663  */
    664 Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos,
    665 		MemPtr_t *pMem) {
    666 
    667   // check if handle is invalid
    668   if ( ! isValidMemH(wsmH) ) {
    669     return wsmRet=SML_ERR_INVALID_HANDLE;
    670   }
    671   // check if handle is locked
    672   if ( isLockedMemH(wsmH) ) {
    673     return wsmRet=SML_ERR_WRONG_USAGE;
    674   }
    675 
    676   // lock
    677   if ( (wsmRet = smLock(wsmH, pMem)) != SML_ERR_OK ) {
    678     return wsmRet=SML_ERR_UNSPECIFIC;
    679   }
    680 
    681   // set local pointers
    682   wsmIndex = lookup(wsmH);
    683   wsmBuf[wsmIndex].pFirstData = *pMem;
    684   wsmBuf[wsmIndex].pFirstFree = *pMem + wsmBuf[wsmIndex].usedBytes;
    685   wsmBuf[wsmIndex].flags |= WSM_LOCKED_F;
    686 
    687   switch (requestedPos) {
    688   case SML_FIRST_DATA_ITEM:
    689     *pMem = wsmBuf[wsmIndex].pFirstData;
    690     break;
    691   case SML_FIRST_FREE_ITEM:
    692     *pMem = wsmBuf[wsmIndex].pFirstFree;
    693     break;
    694   default:
    695     return wsmRet=SML_ERR_UNSPECIFIC;
    696   }
    697 
    698   return wsmRet=SML_ERR_OK;
    699 }
    700 
    701 
    702 /**
    703  * FUNCTION: wsmGetFreeSize
    704  *
    705  * Returns the remaining unused bytes in the buffer.
    706  *
    707  * PRE-Condition:   handle is valid
    708  *
    709  * POST-Condition:  wsmGetFreeSize = BufferSize - wsmGetUsedSize
    710  *
    711  * IN:      wsmH
    712  *          Handle to the open buffer
    713  *
    714  * OUT:     freeSize
    715  *          Number of bytes which are unused in this buffer
    716  *
    717  * RETURN:  SML_ERR_OK, if O.K.
    718  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    719  *
    720  * @see  wsmGetUsedSize
    721  * @see  wsmProcessedBytes
    722  */
    723 Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize) {
    724 
    725   // check if handle is invalid
    726   if ( ! isValidMemH(wsmH) ) {
    727     return wsmRet=SML_ERR_INVALID_HANDLE;
    728   }
    729 
    730   wsmIndex = lookup(wsmH);
    731 
    732   *freeSize = wsmBuf[wsmIndex].size - wsmBuf[wsmIndex].usedBytes;
    733 
    734   return wsmRet=SML_ERR_OK;
    735 }
    736 
    737 
    738 /**
    739  * FUNCTION: wsmGetUsedSize
    740  *
    741  * Returns the number of bytes used in the buffer.
    742  *
    743  * PRE-Condition:   handle is valid
    744  *
    745  * POST-Condition:  usedSize = BufferSize - wsmGetFreeSize
    746  *
    747  * IN:      wsmH
    748  *          Handle to the open buffer
    749  *
    750  * OUT:     usedSize
    751  *          Number of bytes which are already used in this buffer
    752  *
    753  * RETURN:  SML_ERR_OK, if O.K.
    754  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    755  *
    756  * @see  wsmGetFreeSize
    757  * @see  wsmSetUsedSize
    758  */
    759 Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize) {
    760 
    761   // check if handle is invalid
    762   if ( ! isValidMemH(wsmH) ) {
    763     return wsmRet=SML_ERR_INVALID_HANDLE;
    764   }
    765 
    766   wsmIndex = lookup(wsmH);
    767 
    768   *usedSize = wsmBuf[wsmIndex].usedBytes;
    769 
    770   return wsmRet=SML_ERR_OK;
    771 }
    772 
    773 
    774 /**
    775  * FUNCTION: wsmUnlockH
    776  *
    777  * Unlock handle wsmH. <BR>
    778  * After this call all pointers to this memory handle are invalid
    779  * and should no longer be used.
    780  *
    781  * PRE-Condition:   handle is locked; handle is valid
    782  *
    783  * POST-Condition:  handle is unlocked
    784  *
    785  * OUT:     wsmH
    786  *          Handle to unlock
    787  *
    788  * RETURN:  SML_ERR_OK, if O.K.
    789  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    790  *          SML_ERR_WRONG_USAGE, if handle was not locked
    791  *          SML_ERR_UNSPECIFIC, unlock failed
    792  *
    793  * @see  wsmLockH
    794  */
    795 Ret_t wsmUnlockH (MemHandle_t wsmH) {
    796 
    797   // check if handle is invalid
    798   if ( ! isValidMemH(wsmH) ) {
    799     return wsmRet=SML_ERR_INVALID_HANDLE;
    800   }
    801   // check if handle is already unlocked
    802   if ( ! isLockedMemH(wsmH) ) {
    803     return wsmRet=SML_ERR_WRONG_USAGE;
    804   }
    805 
    806   // unlock
    807   if ( (wsmRet = smUnlock(wsmH)) != SML_ERR_OK ) {
    808     return wsmRet=SML_ERR_UNSPECIFIC;
    809   }
    810 
    811   // set local pointers
    812   wsmIndex = lookup(wsmH);
    813   wsmBuf[wsmIndex].pFirstData = NULL;
    814   wsmBuf[wsmIndex].pFirstFree = NULL;
    815   wsmBuf[wsmIndex].flags &= ~WSM_LOCKED_F;
    816 
    817   return wsmRet=SML_ERR_OK;
    818 }
    819 
    820 
    821 /**
    822  * FUNCTION: wsmSetUsedSize
    823  *
    824  * Tell Workspace how many data were written into buffer.
    825  *
    826  * PRE-Condition:   handle is valid; usedSize <= wsmGetFreeSize; handle is
    827  *                  locked
    828  *
    829  * POST-Condition:  wsmGetUsedSize += usedSize; wsmGetFreeSize -= usedSize;
    830  *                  instancePtr += usedSize;
    831  *
    832  * IN:      wsmH
    833  *          Handle to the open buffer
    834  * IN:      usedSize
    835  *          Number of bytes which were written into buffer
    836  *
    837  * RETURN:  SML_ERR_OK, if O.K.
    838  *          SML_ERR_INVALID_HANDLE, if handle was invalid
    839  *          SML_ERR_INVALID_SIZE, if usedSize <= wsmGetFreeSize
    840  *
    841  * @see  wsmGetUsedSize
    842  */
    843 Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize) {
    844 
    845   // check if handle is invalid
    846   if ( ! isValidMemH(wsmH) ) {
    847     return wsmRet=SML_ERR_INVALID_HANDLE;
    848   }
    849   // check if handle is unlocked
    850   if ( ! isLockedMemH(wsmH) ) {
    851     return wsmRet=SML_ERR_WRONG_USAGE;
    852   }
    853 
    854   wsmIndex = lookup(wsmH);
    855 
    856   // usedSize > freeSize?
    857   if ( usedSize >
    858        (wsmBuf[wsmIndex].size - wsmBuf[wsmIndex].usedBytes) ) {
    859     return wsmRet=SML_ERR_INVALID_SIZE;
    860   }
    861 
    862   // adapt usedSize
    863   wsmBuf[wsmIndex].usedBytes += usedSize;
    864 
    865   // move pFirstFree
    866   wsmBuf[wsmIndex].pFirstFree += usedSize;
    867 
    868   return wsmRet=SML_ERR_OK;
    869 }
    870 
    871 /**
    872  * FUNCTION: wsmReset
    873  *
    874  * Reset the Workspace
    875  *
    876  * PRE-Condition:   -
    877  *
    878  * POST-Condition:  all data is lost. The FirstFree Position equals
    879  * the First Data position
    880  *
    881  * IN:      wsmH
    882  *          Handle to the open buffer
    883  *
    884  * RETURN:  SML_ERR_OK, if O.K.
    885  *
    886  */
    887 Ret_t wsmReset (MemHandle_t wsmH) {
    888 
    889   wsmIndex = lookup(wsmH);
    890   wsmBuf[wsmIndex].pFirstFree = wsmBuf[wsmIndex].pFirstFree - wsmBuf[wsmIndex].usedBytes ;
    891   wsmBuf[wsmIndex].pFirstData = wsmBuf[wsmIndex].pFirstFree;
    892   wsmBuf[wsmIndex].usedBytes = 0;
    893 
    894   return SML_ERR_OK;
    895 }
    896 
    897 /*======================================================================================*/
    898 #else
    899 /* WSM_LITE Version - uses only one buffer*/
    900 /*======================================================================================*/
    901 
    902 
    903 /* Global Vars */
    904 /* =========== */
    905 
    906 /* defines for convient use of global anchor */
    907 #define wsmRet          (mgrGetSyncMLAnchor())->wsmGlobals->wsmRet
    908 #define initWasCalled   (mgrGetSyncMLAnchor())->wsmGlobals->initWasCalled
    909 #define maxWsmAvailMem  (mgrGetSyncMLAnchor())->syncmlOptions->maxWorkspaceAvailMem
    910 #define wsmBuf          (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf
    911 #define wsmIndex        (mgrGetSyncMLAnchor())->wsmGlobals->wsmIndex
    912 
    913 void createDataStructs(void);
    914 
    915 void createDataStructs() {
    916   if ( (mgrGetSyncMLAnchor())->wsmGlobals == NULL ) {
    917     if ( ((mgrGetSyncMLAnchor())->wsmGlobals=smlLibMalloc(sizeof(WsmGlobals_t))) == 0 ) {
    918       return;
    919     }
    920     wsmRet = 0;
    921     initWasCalled = 0;
    922     wsmIndex = 0;
    923 #ifdef __ANSI_C__
    924     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;
    925 #endif
    926 #ifdef __PALM_OS__
    927     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH = 0;
    928     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked = 0;
    929 #endif
    930 #ifdef __EPOC_OS__
    931     (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;
    932 #endif
    933   }
    934 }
    935 #define freeDataStructs() smlLibFree((mgrGetSyncMLAnchor())->wsmGlobals)
    936 
    937 
    938 
    939 /* private functions prototypes */
    940 static Short_t getNextFreeEntry();
    941 static Short_t deleteBufferHandle(MemHandle_t memH);
    942 static Short_t resetBufferGlobals(MemHandle_t memH);
    943 static Byte_t isMemAvailable(MemSize_t memToAlloc);
    944 
    945 
    946 
    947 
    948 /*************************************************************************/
    949 /*  Internal Functions                                                   */
    950 /*************************************************************************/
    951 
    952 
    953 
    954 
    955 /**
    956  * Delete memory handle from buffer.
    957  * Return -1, if handle not found.
    958  */
    959 static Short_t deleteBufferHandle(MemHandle_t memH) {
    960   // reset the values
    961   wsmBuf[0].memH = WSM_MEMH_UNUSED;
    962   wsmBuf[0].pFirstFree = NULL;
    963   wsmBuf[0].pFirstData = NULL;
    964   wsmBuf[0].size      = 0;
    965   wsmBuf[0].usedBytes = 0;
    966   wsmBuf[0].flags     = ~WSM_VALID_F;
    967   smlLibFree(wsmBuf[0].bufName);   // free mem
    968   wsmBuf[0].bufName   = NULL;
    969 
    970   return 0;
    971 }
    972 
    973 
    974 /**
    975  * Reset values in buffer table for entry memH.
    976  * If memH doesn't exist create an entry.
    977  * Return index to memH in buffer table,
    978  * or -1 if table is full
    979  */
    980 static Short_t resetBufferGlobals(MemHandle_t memH) {
    981   if ( (wsmBuf[0].memH != memH) && (wsmBuf[0].memH == WSM_MEMH_UNUSED)) {
    982     // create new one
    983     wsmBuf[0].memH = memH;
    984   } else {
    985     // use existing one, which has to be reset prior usage
    986     smlLibFree(wsmBuf[0].bufName);   // free mem
    987   }
    988   // reset the values
    989   wsmBuf[0].pFirstFree = NULL;
    990   wsmBuf[0].pFirstData = NULL;
    991   wsmBuf[0].size      = 0;
    992   wsmBuf[0].usedBytes = 0;
    993   wsmBuf[0].flags     = WSM_VALID_F;
    994   wsmBuf[0].bufName   = NULL;
    995 
    996   return 0;
    997 }
    998 
    999 
   1000 static Byte_t isMemAvailable(MemSize_t memToAlloc) {
   1001   MemSize_t actMem = memToAlloc;
   1002   if ( maxWsmAvailMem == 0 )
   1003     return 1;  // no memsize restrictions
   1004   if ( wsmBuf[0].memH != WSM_MEMH_UNUSED )
   1005     actMem += wsmBuf[0].size;
   1006   return (actMem <= maxWsmAvailMem);
   1007 }
   1008 
   1009 
   1010 
   1011 /*************************************************************************/
   1012 /*  External Functions                                                   */
   1013 /*************************************************************************/
   1014 
   1015 
   1016 
   1017 /**
   1018  * FUNCTION: wsmInit
   1019  *
   1020  * Initializes all Workspace Manager related resources.<BR>
   1021  * Should only be called once!
   1022  *
   1023  * PRE-Condition:   This is the first function call to WSM
   1024  *
   1025  * POST-Condition:  All WSM resources are initialized
   1026  *
   1027  * IN:      wsmOpts
   1028  *          WSM options, valid options are:
   1029  *          <UL>
   1030  *          <LI> maxAvailMem<BR>
   1031  *               Maximal amount of memory which wsm can use for the buffers<BR>
   1032  *               0 == no limitation
   1033  *          </UL>
   1034  *
   1035  * OUT:     wsmH
   1036  *          Handle to new buffer
   1037  *
   1038  * RETURN:  SML_ERR_OK, if O.K.
   1039  *          SML_ERR_INVALID_OPTIONS, if wsmOpts is not valid
   1040  *          SML_ERR_NOT_ENOUGH_SPACE, if not enough available memory
   1041  *          SML_ERR_WRONG_USAGE, if wsmInit was already called
   1042  */
   1043 Ret_t wsmInit (const WsmOptions_t *wsmOpts) {
   1044   // create global datastructs
   1045   createDataStructs();
   1046 
   1047   if (NULL == mgrGetSyncMLAnchor()->wsmGlobals) {
   1048 	  return SML_ERR_NOT_ENOUGH_SPACE;
   1049    }
   1050 
   1051 
   1052   // check if init was already called
   1053   if ( initWasCalled )
   1054     return SML_ERR_WRONG_USAGE;
   1055 
   1056   // check options
   1057   if ( wsmOpts != NULL ) {
   1058     if ( wsmOpts->maxAvailMem > 0 ) {
   1059       maxWsmAvailMem = wsmOpts->maxAvailMem;
   1060     }
   1061   }
   1062 
   1063   // init resources
   1064   wsmBuf[0].memH = WSM_MEMH_UNUSED;
   1065   wsmIndex = 0;
   1066   initWasCalled = (Byte_t) 1;
   1067 
   1068   return wsmRet=SML_ERR_OK;
   1069 }
   1070 
   1071 
   1072 /**
   1073  * FUNCTION: wsmCreate
   1074  *
   1075  * Creates and opens a new buffer with name bufName and size bufSize.<BR>
   1076  * If a buffer with name bufName already exists, the existing buffer
   1077  * is resized to bufSize.
   1078  *
   1079  * PRE-Condition:   bufSize > 0
   1080  *
   1081  * POST-Condition:  handle refers to buffer bufName; BufferSize = size
   1082  *
   1083  * IN:      bufName
   1084  *          Name of buffer to be created
   1085  * IN:      bufSize
   1086  *          Size of buffer to be created
   1087  *
   1088  * OUT:     wsmH
   1089  *          Handle to new buffer
   1090  *
   1091  * RETURN:  SML_ERR_OK, if O.K.
   1092  *          SML_ERR_INVALID_SIZE, if bufSize <= 0
   1093  *          SML_ERR_NOT_ENOUGH_SPACE, if available memory < bufSize
   1094  *          SML_ERR_WSM_BUF_TABLE_FULL, if buffer table is full
   1095  *          SML_ERR_WRONG_USAGE, if wsmInit wasn't called before
   1096  *
   1097  * @see  wsmDestroy
   1098  */
   1099 Ret_t wsmCreate (String_t bufName, MemSize_t bufSize, MemHandle_t *wsmH) {
   1100 
   1101   *wsmH = 0;    // 0 in case of error
   1102 
   1103   if ( ! initWasCalled )
   1104     return SML_ERR_WRONG_USAGE;
   1105 
   1106   // check buffer space
   1107   if ( wsmBuf[0].memH != WSM_MEMH_UNUSED ) {
   1108     return wsmRet=SML_ERR_WSM_BUF_TABLE_FULL;
   1109   }
   1110   // check for maxMemAvailable
   1111   if ( ! isMemAvailable(bufSize) ) {
   1112     return SML_ERR_NOT_ENOUGH_SPACE;
   1113   }
   1114 
   1115   // create buffer
   1116   if ( (wsmRet = smCreate(bufName, bufSize, wsmH)) != SML_ERR_OK ) {
   1117     if ( wsmRet == SML_ERR_WRONG_USAGE ) {    // buffer already exists
   1118       // resize existing buffer
   1119       // open buffer
   1120       if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) {
   1121 	return wsmRet=SML_ERR_NOT_ENOUGH_SPACE;
   1122       }
   1123       // resize buffer
   1124       if ( (wsmRet = smSetSize(*wsmH, bufSize)) != SML_ERR_OK ) {
   1125 	return wsmRet=SML_ERR_NOT_ENOUGH_SPACE;
   1126       }
   1127     }
   1128     else {
   1129       return wsmRet;
   1130     }
   1131   }
   1132 
   1133   // reset buffer vars
   1134   resetBufferGlobals(*wsmH);
   1135 
   1136   // set buffer vars
   1137   wsmBuf[0].size = bufSize;
   1138   wsmBuf[0].bufName = smlLibStrdup(bufName);
   1139 
   1140   return wsmRet=SML_ERR_OK;
   1141 }
   1142 
   1143 
   1144 /**
   1145  * FUNCTION: wsmOpen
   1146  *
   1147  * Open existing buffer with name bufName.
   1148  *
   1149  * PRE-Condition:   WSM knows bufName
   1150  *
   1151  * POST-Condition:  wsmH refers to buffer bufName
   1152  *
   1153  * IN:      bufName
   1154  *          Name of buffer to be opened
   1155  *
   1156  * OUT:     wsmH
   1157  *          Handle to new buffer
   1158  *
   1159  * RETURN:  SML_ERR_OK, if O.K.
   1160  *          SML_WRONG_PARAM, if bufName is unknown
   1161  *
   1162  * @see  wsmClose
   1163  */
   1164 Ret_t wsmOpen (String_t bufName, MemHandle_t *wsmH){
   1165 
   1166   // open buffer
   1167   if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) {
   1168     return wsmRet;
   1169   }
   1170 
   1171   // reset buffer vars
   1172   resetBufferGlobals(*wsmH);
   1173 
   1174   // set buf vars
   1175   wsmRet = smGetSize(*wsmH, &wsmBuf[0].size);
   1176   wsmBuf[0].bufName = smlLibStrdup(bufName);
   1177 
   1178   return wsmRet=SML_ERR_OK;
   1179 }
   1180 
   1181 
   1182 /**
   1183  * FUNCTION: wsmClose
   1184  *
   1185  * Close an open buffer.
   1186  *
   1187  * PRE-Condition:   handle is valid; handle is unlocked
   1188  *
   1189  * POST-Condition:  handle is not known to WSM any more
   1190  *
   1191  * IN:      wsmH
   1192  *          Handle to the open buffer
   1193  *
   1194  * RETURN:  SML_ERR_OK, if O.K.
   1195  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1196  *          SML_ERR_WRONG_USAGE, if handle was still locked
   1197  *
   1198  * @see  wsmOpen
   1199  */
   1200 Ret_t wsmClose (MemHandle_t wsmH) {
   1201 
   1202   // check if handle is invalid
   1203   // must be buffer 0, as only this one exists
   1204   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1205     return wsmRet=SML_ERR_INVALID_HANDLE;
   1206   }
   1207 
   1208   // close handle
   1209   if ( (wsmRet = smClose(wsmH)) != SML_ERR_OK ) {
   1210     return wsmRet;
   1211   }
   1212   wsmRet = deleteBufferHandle(wsmH);
   1213 
   1214   return wsmRet=SML_ERR_OK;
   1215 }
   1216 
   1217 
   1218 /**
   1219  * FUNCTION: wsmDestroy
   1220  *
   1221  * Destroy existing buffer with name bufName.
   1222  *
   1223  * PRE-Condition:   WSM knows bufName; handle is unlocked
   1224  *
   1225  * POST-Condition:  buffer is not known to WSM any more; all resources
   1226  *                  connected to this buffer are freed
   1227  *
   1228  * IN:      bufName
   1229  *          Name of buffer to be opened
   1230  *
   1231  * RETURN:  SML_ERR_OK, if O.K.
   1232  *          SML_ERR_WRONG_PARAM, if bufName is unknown to WSM
   1233  *          SML_ERR_WRONG_USAGE, if handle was still locked
   1234  *
   1235  * @see  wsmCreate
   1236  */
   1237 Ret_t wsmDestroy (String_t bufName) {
   1238 
   1239   // free resources
   1240   if ( (wsmRet = wsmClose(wsmBuf[0].memH)) != SML_ERR_OK ) {
   1241     return wsmRet;
   1242   }
   1243 
   1244   // free buffer
   1245   if ( (wsmRet = smDestroy(bufName)) != SML_ERR_OK ) {
   1246     return wsmRet;
   1247   }
   1248 
   1249   return wsmRet=SML_ERR_OK;
   1250 }
   1251 
   1252 
   1253 /**
   1254  * FUNCTION: wsmTerminate
   1255  *
   1256  * Terminate WSM; free all buffers and resources.
   1257  *
   1258  * PRE-Condition: all handles must be unlocked
   1259  *
   1260  * POST-Condition: all resources are freed
   1261  *
   1262  * RETURN:  SML_ERR_OK, if O.K.
   1263  *          SML_ERR_WRONG_USAGE, if a handle was still locked
   1264  *
   1265  */
   1266 Ret_t wsmTerminate () {
   1267   int i;
   1268 
   1269   // free all WSM resources
   1270   for (i=0; i < MAX_WSM_BUFFERS; ++i) {
   1271     if ( wsmBuf[i].memH != WSM_MEMH_UNUSED )
   1272       if ( wsmDestroy(wsmBuf[i].bufName) == SML_ERR_WRONG_USAGE ) {
   1273 	return SML_ERR_WRONG_USAGE;
   1274       }
   1275   }
   1276 
   1277   // free global DataStructs
   1278   freeDataStructs();
   1279 
   1280   return SML_ERR_OK;
   1281 }
   1282 
   1283 
   1284 /**
   1285  * FUNCTION: wsmProcessedBytes
   1286  *
   1287  * Tell Workspace Manager the number of bytes already processed.
   1288  *
   1289  * PRE-Condition:   handle is locked; handle is valid;
   1290  *                  noBytes <= wsmGetUsedSize
   1291  *
   1292  * POST-Condition:  noBytes starting at wsmGetPtr() position are deleted;
   1293  *                  remaining bytes are copied to
   1294  *                  wsmGetPtr(SML_FIRST_FREE_ITEM) position;
   1295  *                  wsmGetUsedSize -= noBytes; wsmGetFreeSize += noBytes
   1296  *
   1297  * IN:      wsmH
   1298  *          Handle to the open buffer
   1299  * IN:      noBytes
   1300  *          Number of bytes already processed from buffer.
   1301  *
   1302  * RETURN:  SML_ERR_OK, if O.K.
   1303  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1304  *          SML_ERR_WRONG_USAGE, if handle was not locked
   1305  *          SML_ERR_INVALID_SIZE, if noBytes > wsmGetUsedSize
   1306  *
   1307  * @see  wsmGetFreeSize
   1308  */
   1309 Ret_t wsmProcessedBytes (MemHandle_t wsmH, MemSize_t noBytes) {
   1310 
   1311   // check if handle is invalid
   1312   // must be buffer 0, as only this one exists
   1313   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1314     return wsmRet=SML_ERR_INVALID_HANDLE;
   1315   }
   1316   // check if handle is unlocked
   1317   // must be buffer 0, as only this one exists
   1318   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) {
   1319     return wsmRet=SML_ERR_WRONG_USAGE;
   1320   }
   1321 
   1322   if ( noBytes > wsmBuf[0].usedBytes ) {
   1323     return wsmRet=SML_ERR_INVALID_SIZE;
   1324   }
   1325 
   1326   // adapt usedSize
   1327   wsmBuf[0].usedBytes -= noBytes;
   1328 
   1329   // move memory
   1330   // check return ?????
   1331   smlLibMemmove(wsmBuf[0].pFirstData,
   1332 	  (wsmBuf[0].pFirstData + noBytes),
   1333 	  wsmBuf[0].usedBytes);
   1334 
   1335   // move pFirstFree
   1336   wsmBuf[0].pFirstFree -= noBytes;
   1337 
   1338   return wsmRet=SML_ERR_OK;
   1339 }
   1340 
   1341 
   1342 /**
   1343  * FUNCTION: wsmLockH
   1344  *
   1345  * Locks handle wsmH and get a pointer to the contents of wsmH. <BR>
   1346  * RequestedPos describes the position in the buffer to which the returned
   1347  * pointer should point. Valid values are:
   1348  * <UL>
   1349  *   <LI> SML_FIRST_DATA_ITEM
   1350  *   <LI> SML_FIRST_FREE_ITEM
   1351  * </UL>
   1352  *
   1353  * PRE-Condition:   handle is unlocked; handle is valid
   1354  *
   1355  * POST-Condition:  handle is locked; points to first data item,
   1356  *                  or first free item.
   1357  *
   1358  * IN:      wsmH
   1359  *          Handle to the open buffer
   1360  * IN:      requestedPos
   1361  *          Requested position of the returned pointer
   1362  *          <UL>
   1363  *            <LI> SML_FIRST_DATA_ITEM : points to first data entry
   1364  *            <LI> SML_FIRST_FREE_ITEM : points to first free entry
   1365  *          </UL>
   1366  *
   1367  * OUT:     pMem
   1368  *          Pointer to requested memory
   1369  *
   1370  * RETURN:  SML_ERR_OK, if O.K.
   1371  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1372  *          SML_ERR_WRONG_USAGE, if handle was still locked
   1373  *          SML_ERR_UNSPECIFIC, if requested position is unknown, or lock failed
   1374  *
   1375  * @see  wsmUnlockH
   1376  */
   1377 Ret_t wsmLockH (MemHandle_t wsmH, SmlBufPtrPos_t requestedPos,
   1378 		MemPtr_t *pMem) {
   1379 
   1380   // check if handle is invalid
   1381   // must be buffer 0, as only this one exists
   1382   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1383     return wsmRet=SML_ERR_INVALID_HANDLE;
   1384   }
   1385   // check if handle is locked
   1386   // must be buffer 0, as only this one exists
   1387   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) {
   1388     return wsmRet=SML_ERR_WRONG_USAGE;
   1389   }
   1390 
   1391   // lock
   1392   if ( (wsmRet = smLock(wsmH, pMem)) != SML_ERR_OK ) {
   1393     return wsmRet=SML_ERR_UNSPECIFIC;
   1394   }
   1395 
   1396   // set local pointers
   1397   wsmBuf[0].pFirstData = *pMem;
   1398   wsmBuf[0].pFirstFree = *pMem + wsmBuf[0].usedBytes;
   1399   wsmBuf[0].flags |= WSM_LOCKED_F;
   1400 
   1401   switch (requestedPos) {
   1402   case SML_FIRST_DATA_ITEM:
   1403     *pMem = wsmBuf[0].pFirstData;
   1404     break;
   1405   case SML_FIRST_FREE_ITEM:
   1406     *pMem = wsmBuf[0].pFirstFree;
   1407     break;
   1408   default:
   1409     return wsmRet=SML_ERR_UNSPECIFIC;
   1410   }
   1411 
   1412   return wsmRet=SML_ERR_OK;
   1413 }
   1414 
   1415 
   1416 /**
   1417  * FUNCTION: wsmGetFreeSize
   1418  *
   1419  * Returns the remaining unused bytes in the buffer.
   1420  *
   1421  * PRE-Condition:   handle is valid
   1422  *
   1423  * POST-Condition:  wsmGetFreeSize = BufferSize - wsmGetUsedSize
   1424  *
   1425  * IN:      wsmH
   1426  *          Handle to the open buffer
   1427  *
   1428  * OUT:     freeSize
   1429  *          Number of bytes which are unused in this buffer
   1430  *
   1431  * RETURN:  SML_ERR_OK, if O.K.
   1432  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1433  *
   1434  * @see  wsmGetUsedSize
   1435  * @see  wsmProcessedBytes
   1436  */
   1437 Ret_t wsmGetFreeSize(MemHandle_t wsmH, MemSize_t *freeSize) {
   1438 
   1439   // check if handle is invalid
   1440   // must be buffer 0, as only this one exists
   1441   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1442     return wsmRet=SML_ERR_INVALID_HANDLE;
   1443   }
   1444 
   1445   *freeSize = wsmBuf[0].size - wsmBuf[0].usedBytes;
   1446 
   1447   return wsmRet=SML_ERR_OK;
   1448 }
   1449 
   1450 
   1451 /**
   1452  * FUNCTION: wsmGetUsedSize
   1453  *
   1454  * Returns the number of bytes used in the buffer.
   1455  *
   1456  * PRE-Condition:   handle is valid
   1457  *
   1458  * POST-Condition:  usedSize = BufferSize - wsmGetFreeSize
   1459  *
   1460  * IN:      wsmH
   1461  *          Handle to the open buffer
   1462  *
   1463  * OUT:     usedSize
   1464  *          Number of bytes which are already used in this buffer
   1465  *
   1466  * RETURN:  SML_ERR_OK, if O.K.
   1467  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1468  *
   1469  * @see  wsmGetFreeSize
   1470  * @see  wsmSetUsedSize
   1471  */
   1472 Ret_t wsmGetUsedSize(MemHandle_t wsmH, MemSize_t *usedSize) {
   1473 
   1474   // check if handle is invalid
   1475   // must be buffer 0, as only this one exists
   1476   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1477     return wsmRet=SML_ERR_INVALID_HANDLE;
   1478   }
   1479 
   1480   *usedSize = wsmBuf[0].usedBytes;
   1481 
   1482   return wsmRet=SML_ERR_OK;
   1483 }
   1484 
   1485 
   1486 /**
   1487  * FUNCTION: wsmUnlockH
   1488  *
   1489  * Unlock handle wsmH. <BR>
   1490  * After this call all pointers to this memory handle are invalid
   1491  * and should no longer be used.
   1492  *
   1493  * PRE-Condition:   handle is locked; handle is valid
   1494  *
   1495  * POST-Condition:  handle is unlocked
   1496  *
   1497  * OUT:     wsmH
   1498  *          Handle to unlock
   1499  *
   1500  * RETURN:  SML_ERR_OK, if O.K.
   1501  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1502  *          SML_ERR_WRONG_USAGE, if handle was not locked
   1503  *          SML_ERR_UNSPECIFIC, unlock failed
   1504  *
   1505  * @see  wsmLockH
   1506  */
   1507 Ret_t wsmUnlockH (MemHandle_t wsmH) {
   1508 
   1509   // check if handle is invalid
   1510   // must be buffer 0, as only this one exists
   1511   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1512     return wsmRet=SML_ERR_INVALID_HANDLE;
   1513   }
   1514   // check if handle is already unlocked
   1515   // must be buffer 0, as only this one exists
   1516   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) {
   1517     return wsmRet=SML_ERR_WRONG_USAGE;
   1518   }
   1519 
   1520   // unlock
   1521   if ( (wsmRet = smUnlock(wsmH)) != SML_ERR_OK ) {
   1522     return wsmRet=SML_ERR_UNSPECIFIC;
   1523   }
   1524 
   1525   // set local pointers
   1526   wsmBuf[0].pFirstData = NULL;
   1527   wsmBuf[0].pFirstFree = NULL;
   1528   wsmBuf[0].flags &= ~WSM_LOCKED_F;
   1529 
   1530   return wsmRet=SML_ERR_OK;
   1531 }
   1532 
   1533 
   1534 /**
   1535  * FUNCTION: wsmSetUsedSize
   1536  *
   1537  * Tell Workspace how many data were written into buffer.
   1538  *
   1539  * PRE-Condition:   handle is valid; usedSize <= wsmGetFreeSize; handle is
   1540  *                  locked
   1541  *
   1542  * POST-Condition:  wsmGetUsedSize += usedSize; wsmGetFreeSize -= usedSize;
   1543  *                  instancePtr += usedSize;
   1544  *
   1545  * IN:      wsmH
   1546  *          Handle to the open buffer
   1547  * IN:      usedSize
   1548  *          Number of bytes which were written into buffer
   1549  *
   1550  * RETURN:  SML_ERR_OK, if O.K.
   1551  *          SML_ERR_INVALID_HANDLE, if handle was invalid
   1552  *          SML_ERR_INVALID_SIZE, if usedSize <= wsmGetFreeSize
   1553  *
   1554  * @see  wsmGetUsedSize
   1555  */
   1556 Ret_t wsmSetUsedSize (MemHandle_t wsmH, MemSize_t usedSize) {
   1557 
   1558   // check if handle is invalid
   1559   // must be buffer 0, as only this one exists
   1560   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_VALID_F)) ) {
   1561     return wsmRet=SML_ERR_INVALID_HANDLE;
   1562   }
   1563   // check if handle is unlocked
   1564   // must be buffer 0, as only this one exists
   1565   if ( ! ((wsmBuf[0].memH == wsmH) || (wsmBuf[0].flags & WSM_LOCKED_F)) ) {
   1566     return wsmRet=SML_ERR_WRONG_USAGE;
   1567   }
   1568 
   1569   // usedSize > freeSize?
   1570   if ( usedSize >
   1571        (wsmBuf[0].size - wsmBuf[0].usedBytes) ) {
   1572     return wsmRet=SML_ERR_INVALID_SIZE;
   1573   }
   1574 
   1575   // adapt usedSize
   1576   wsmBuf[0].usedBytes += usedSize;
   1577 
   1578   // move pFirstFree
   1579   wsmBuf[0].pFirstFree += usedSize;
   1580 
   1581   return wsmRet=SML_ERR_OK;
   1582 }
   1583 
   1584 /**
   1585  * FUNCTION: wsmReset
   1586  *
   1587  * Reset the Workspace
   1588  *
   1589  * PRE-Condition:   -
   1590  *
   1591  * POST-Condition:  all data is lost. The FirstFree Position equals
   1592  * the First Data position
   1593  *
   1594  * IN:      wsmH
   1595  *          Handle to the open buffer
   1596  *
   1597  * RETURN:  SML_ERR_OK, if O.K.
   1598  *
   1599  */
   1600 Ret_t wsmReset (MemHandle_t wsmH) {
   1601   wsmBuf[0].pFirstFree = wsmBuf[0].pFirstFree - wsmBuf[0].usedBytes ;
   1602   wsmBuf[0].pFirstData = wsmBuf[0].pFirstFree;
   1603   wsmBuf[0].usedBytes = 0;
   1604 
   1605   return SML_ERR_OK;
   1606 }
   1607 
   1608 
   1609 #endif // #ifndef __SML_LITE__
   1610 
   1611 #endif // #idndef NOWSM
   1612 
   1613