📄 wsm.c
字号:
/*************************************************************************//* module: SyncML WorkSpace Manager *//* file: WSM.c *//* target system: All *//* target OS: All *//*************************************************************************//* * 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. * *//** * Workspace Manager API <BR> * Manages the SyncML document in memory. * * @version @label * * */#ifndef NOWSM// if no WSM, we can leave this one out completely/*************************************************************************//* Definitions *//*************************************************************************/#include "wsm.h"#include "wsm_sm.h"#include "smldef.h"#include "libmem.h"#include "libstr.h"#include "liblock.h" // for THREADDEBUGPRINTF %%% luz#include "mgr.h" // for global anchor/** WSM buffer flags */#define WSM_VALID_F (Byte_t) 0x01#define WSM_LOCKED_F (Byte_t) 0x02#define WSM_MEMH_UNUSED -1#ifndef __SML_LITE__/* Global Vars *//* =========== *//* defines for convient use of global anchor */#define wsmRet (mgrGetSyncMLAnchor())->wsmGlobals->wsmRet#define initWasCalled (mgrGetSyncMLAnchor())->wsmGlobals->initWasCalled#define maxWsmAvailMem (mgrGetSyncMLAnchor())->syncmlOptions->maxWorkspaceAvailMem#define wsmBuf (mgrGetSyncMLAnchor())->wsmGlobals->wsmBuf#define wsmIndex (mgrGetSyncMLAnchor())->wsmGlobals->wsmIndexvoid createDataStructs(void);void createDataStructs() { if ( (mgrGetSyncMLAnchor())->wsmGlobals == NULL ) { if ( ((mgrGetSyncMLAnchor())->wsmGlobals=smlLibMalloc(sizeof(WsmGlobals_t))) == 0 ) { return; } smlLibMemset((mgrGetSyncMLAnchor())->wsmGlobals, 0, sizeof(WsmGlobals_t)); wsmRet = 0; initWasCalled = 0; wsmIndex = 0;#ifdef __ANSI_C__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;#endif#ifdef __PALM_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smMemH = 0; (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm.smLocked = 0;#endif#ifdef __EPOC_OS__ (mgrGetSyncMLAnchor())->wsmGlobals->wsmSm = NULL;#endif }}#define freeDataStructs() smlLibFree((mgrGetSyncMLAnchor())->wsmGlobals)/* private functions prototypes */static Short_t getNextFreeEntry();static Short_t lookup(MemHandle_t memH);static MemHandle_t nameToHandle(String_t name);static Short_t deleteBufferHandle(MemHandle_t memH);static Short_t resetBufferGlobals(MemHandle_t memH);static Byte_t isValidMemH(MemHandle_t memH);static Byte_t isLockedMemH(MemHandle_t memH);static Byte_t isMemAvailable(MemSize_t memToAlloc);/*************************************************************************//* Internal Functions *//*************************************************************************//** * Get next free buffer entry. * Returns index of next free entry, or -1 if buffer table is full. */static Short_t getNextFreeEntry() { Short_t i; for ( i=0; i < MAX_WSM_BUFFERS; ++i ) if ( wsmBuf[i].memH == WSM_MEMH_UNUSED ) return i; return -1;}/** * Get buffer table index for memH. * Returns -1 if memH not found. */static Short_t lookup(MemHandle_t memH) { Short_t i; // first check cache if ( wsmBuf[wsmIndex].memH == memH ) return wsmIndex; // search through buffer for ( i=0; (i < MAX_WSM_BUFFERS) && (wsmBuf[i].memH != memH); ++i ) ; if ( i < MAX_WSM_BUFFERS ) { wsmIndex = i; return i; } else { return -1; // memH not found }}/** * Find memory handle corresponding to name. * Return WSM_MEMH_UNUSED, if name not found in wsmBuf. */static MemHandle_t nameToHandle(String_t name) { int i; // first check cache if ( (wsmBuf[wsmIndex].bufName != NULL) && (smlLibStrcmp(wsmBuf[wsmIndex].bufName, name) == 0) ) return wsmBuf[wsmIndex].memH; // search through buffer for ( i=0; ((i < MAX_WSM_BUFFERS) && (wsmBuf[i].bufName == NULL ? 1 : smlLibStrcmp(wsmBuf[i].bufName, name) != 0)); ++i ) ; if ( i < MAX_WSM_BUFFERS ) return wsmBuf[i].memH; else { return WSM_MEMH_UNUSED; // name not found }} /** * Delete memory handle from buffer. * Return -1, if handle not found. */static Short_t deleteBufferHandle(MemHandle_t memH) { if ( (wsmIndex = lookup(memH)) < 0 ) return -1; // handle not found // reset the values wsmBuf[wsmIndex].memH = WSM_MEMH_UNUSED; wsmBuf[wsmIndex].pFirstFree = NULL; wsmBuf[wsmIndex].pFirstData = NULL; wsmBuf[wsmIndex].size = 0; wsmBuf[wsmIndex].usedBytes = 0; //wsmBuf[wsmIndex].flags = ~WSM_VALID_F; wsmBuf[wsmIndex].flags = ((Byte_t) ~WSM_VALID_F); smlLibFree(wsmBuf[wsmIndex].bufName); // free mem wsmBuf[wsmIndex].bufName = NULL; return 0;}/** * Reset values in buffer table for entry memH. * If memH doesn't exist create an entry. * Return index to memH in buffer table, * or -1 if table is full */static Short_t resetBufferGlobals(MemHandle_t memH) { if ( (wsmIndex = lookup(memH)) < 0 ) { // create new one if ( (wsmIndex = getNextFreeEntry()) < 0 ) return -1; // buffer table full wsmBuf[wsmIndex].memH = memH; } else // use existing one, which has to be reset prior usage smlLibFree(wsmBuf[wsmIndex].bufName); // free mem // reset the values wsmBuf[wsmIndex].pFirstFree = NULL; wsmBuf[wsmIndex].pFirstData = NULL; wsmBuf[wsmIndex].size = 0; wsmBuf[wsmIndex].usedBytes = 0; wsmBuf[wsmIndex].flags = WSM_VALID_F; wsmBuf[wsmIndex].bufName = NULL; return wsmIndex;}static Byte_t isValidMemH(MemHandle_t memH) { return (Byte_t) (wsmBuf[lookup(memH)].flags & WSM_VALID_F);}static Byte_t isLockedMemH(MemHandle_t memH) { return (Byte_t) (wsmBuf[lookup(memH)].flags & WSM_LOCKED_F);}static Byte_t isMemAvailable(MemSize_t memToAlloc) { int i; MemSize_t actMem = memToAlloc; if ( maxWsmAvailMem == 0 ) return 1; // no memsize restrictions for (i=0; i < MAX_WSM_BUFFERS; ++i) { if ( wsmBuf[i].memH != WSM_MEMH_UNUSED ) actMem += wsmBuf[i].size; } return ((Byte_t)(actMem <= maxWsmAvailMem));}/*************************************************************************//* External Functions *//*************************************************************************//** * 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> maxAvailMem<BR> * Maximal amount of memory which wsm can use for the buffers<BR> * 0 == no limitation * </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) { int i; // create global datastructs createDataStructs(); if (NULL == mgrGetSyncMLAnchor()->wsmGlobals) { return SML_ERR_NOT_ENOUGH_SPACE; } // check if init was already called if ( initWasCalled ) return SML_ERR_WRONG_USAGE; // check options if ( wsmOpts != NULL ) { if ( wsmOpts->maxAvailMem > 0 ) { maxWsmAvailMem = wsmOpts->maxAvailMem; } } // init resources for ( i=0; i < MAX_WSM_BUFFERS; ++i ) wsmBuf[i].memH = WSM_MEMH_UNUSED; wsmIndex = 0; initWasCalled = (Byte_t) 1; return wsmRet=SML_ERR_OK;} /** * 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) { *wsmH = 0; // 0 in case of error if ( ! initWasCalled ) return SML_ERR_WRONG_USAGE; // check buffer space if ( getNextFreeEntry() == -1 ) { return wsmRet=SML_ERR_WSM_BUF_TABLE_FULL; } // check for maxMemAvailable if ( ! isMemAvailable(bufSize) ) { return SML_ERR_NOT_ENOUGH_SPACE; } // create buffer if ( (wsmRet = smCreate(bufName, bufSize, wsmH)) != SML_ERR_OK ) { if ( wsmRet == SML_ERR_WRONG_USAGE ) { // buffer already exists // resize existing buffer // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } // resize buffer if ( (wsmRet = smSetSize(*wsmH, bufSize)) != SML_ERR_OK ) { return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } } else { return wsmRet; } } // reset buffer vars wsmIndex = resetBufferGlobals(*wsmH); // set buffer vars wsmBuf[wsmIndex].size = bufSize; wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName); if (wsmBuf[wsmIndex].bufName == NULL) { smClose(*wsmH); smDestroy(bufName); return wsmRet=SML_ERR_NOT_ENOUGH_SPACE; } return wsmRet=SML_ERR_OK;}/** * 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){ // open buffer if ( (wsmRet = smOpen(bufName, wsmH)) != SML_ERR_OK ) { return wsmRet; } // reset buffer vars wsmIndex = resetBufferGlobals(*wsmH); // set buf vars wsmRet = smGetSize(*wsmH, &wsmBuf[wsmIndex].size); wsmBuf[wsmIndex].bufName = smlLibStrdup(bufName); return wsmRet=SML_ERR_OK;}/** * 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) { // check if handle is invalid if ( ! isValidMemH(wsmH) ) { return wsmRet=SML_ERR_INVALID_HANDLE; } // close handle if ( (wsmRet = smClose(wsmH)) != SML_ERR_OK ) { return wsmRet; } wsmRet = deleteBufferHandle(wsmH); return wsmRet=SML_ERR_OK;}/** * 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) { // free resources if ( (wsmRet = wsmClose(nameToHandle(bufName))) != SML_ERR_OK ) { return wsmRet; } // free buffer if ( (wsmRet = smDestroy(bufName)) != SML_ERR_OK ) { return wsmRet; } return wsmRet=SML_ERR_OK;}/** * FUNCTION: wsmTerminate * * Terminate WSM; free all buffers and resources. * * PRE-Condition: all handles must be unlocked * * POST-Condition: all resources are freed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -