SBcache.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:25k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #include "SBcacheInternal.h"
  23. #define SBCACHE_EXPORTS
  24. #include "SBcache.h"           // Init/Shutdown/Create/Destroy
  25. #include "SBcacheManager.hpp"  // For SBcacheManager
  26. #include "SBcacheLog.h"        // For logging
  27. #include "base64.h"            // base64 encoding functions
  28. #include "md5.h"               // MD5 digest functions
  29. #define MAX_CACHE_KEY   256
  30. /*****************************************************************************/
  31. // Static definitions and functions
  32. /*****************************************************************************/
  33. static VXIunsigned      gblDiagTagBase = 0;
  34. static SBcacheManager  *gblCacheMgr = NULL;
  35. // Static class to ensure the cache index file is updated even if
  36. // SBcacheShutDown( ) is not called
  37. class SBcacheTerminate {
  38. public:
  39.   SBcacheTerminate( ) { }
  40.   ~SBcacheTerminate( );
  41. };
  42. static SBcacheTerminate gblCacheTerminate;
  43. SBcacheTerminate::~SBcacheTerminate( )
  44. {
  45.   if (gblCacheMgr) {
  46.     // Disable logging, the log resource is probably gone by now so
  47.     // trying to use it as will be done at shutdown causes a crash
  48.     gblCacheMgr->ClearLogResource( );
  49.     // Write out the index
  50.     gblCacheMgr->WriteIndex( );
  51.     // NOTE: Do not delete the cache manager here, doing so may result
  52.     // in crashes/asserts due to deleting mutexes that are active
  53.   }
  54. }
  55. /*****************************************************************************/
  56. // Cache Interface Class, one per channel
  57. /*****************************************************************************/
  58. class SBcacheInterface : public VXIcacheInterface, public SBinetLogger
  59. {
  60. public:
  61.   SBcacheInterface(VXIlogInterface *log, VXIunsigned diagTagBase);
  62.   virtual ~SBcacheInterface( ) { }
  63.   /****************************************/
  64.   // Static functions for mapping from C to C++
  65.   /****************************************/
  66.   static    VXIint32       GetVersion(void);
  67.   static    const VXIchar* GetImplementationName(void);
  68.   static    VXIcacheResult CallOpen(struct VXIcacheInterface *pThis,
  69.     const VXIchar *moduleName,
  70.     const VXIchar *key,
  71.     VXIcacheOpenMode mode,
  72.     VXIint32 flags,
  73.     const VXIMap *properties,
  74.     VXIMap *streamInfo,
  75.     VXIcacheStream **stream);
  76.   static    VXIcacheResult CallClose(struct VXIcacheInterface *pThis,
  77.      VXIcacheStream **stream);
  78.   static    VXIcacheResult CallUnlock(struct VXIcacheInterface *pThis,
  79.       const VXIchar *key);
  80.     
  81.   static    VXIcacheResult CallRead(struct VXIcacheInterface *pThis,
  82.     VXIbyte   *buffer,
  83.     VXIulong  buflen,
  84.     VXIulong  *nread,
  85.     VXIcacheStream *stream);
  86.     
  87.   static    VXIcacheResult CallWrite(struct VXIcacheInterface *pThis,
  88.      const VXIbyte *buffer,
  89.      VXIulong buflen,
  90.      VXIulong *nwritten,
  91.      VXIcacheStream *stream);
  92.   static    VXIcacheResult CallOpenEx(struct VXIcacheInterface *pThis,
  93.       const VXIchar *moduleName,
  94.       const VXIbyte *key,
  95.       VXIulong keySizeBytes,
  96.       VXIcacheOpenMode mode,
  97.       VXIint32 flags,
  98.       const VXIMap *properties,
  99.       VXIMap *streamInfo,
  100.       VXIcacheStream **stream);
  101.   static    VXIcacheResult CallCloseEx(struct VXIcacheInterface *pThis,
  102.        VXIbool keepEntry,
  103.        VXIcacheStream **stream);
  104.   
  105.   static    VXIcacheResult CallUnlockEx(struct VXIcacheInterface *pThis,
  106. const VXIbyte *key,
  107. VXIulong keySizeBytes);
  108.     
  109. private:
  110.   /****************************************/
  111.   // The real implementations
  112.   /****************************************/
  113.   VXIcacheResult Open(const VXIchar *moduleName,
  114.       const VXIchar *key,
  115.       VXIcacheOpenMode mode,
  116.       VXIint32 flags,
  117.       const VXIMap *properties,
  118.       VXIMap *streamInfo,
  119.       VXIcacheStream **stream);
  120.   VXIcacheResult Open(const VXIchar *moduleName,
  121.       const VXIbyte *key,
  122.       VXIulong keySizeBytes,
  123.       VXIcacheOpenMode mode,
  124.       VXIint32 flags,
  125.       const VXIMap *properties,
  126.       VXIMap *streamInfo,
  127.       VXIcacheStream **stream);
  128.   VXIcacheResult Close(VXIbool keepEntry,
  129.        VXIcacheStream **stream);
  130.   VXIcacheResult Unlock(const VXIchar *key);
  131.   VXIcacheResult Unlock(const VXIbyte *key,
  132. VXIulong keySizeBytes);
  133.     
  134.   VXIcacheResult Read(VXIbyte *buffer,
  135.       VXIulong buflen,
  136.       VXIulong *nread,
  137.       VXIcacheStream *stream);
  138.     
  139.   VXIcacheResult Write(const VXIbyte *buffer,
  140.        VXIulong buflen,
  141.        VXIulong *nwritten,
  142.        VXIcacheStream *stream);
  143.   /************************************/
  144.   // Utility methods
  145.   /************************************/
  146.   SBcacheKey MakeCacheKey(const VXIbyte *buf, VXIunsigned bufSizeBytes) const;
  147.   SBcacheKey MakeCacheKey(const VXIchar *buf) const;
  148. };
  149. SBcacheInterface::SBcacheInterface(VXIlogInterface *log, 
  150.    VXIunsigned diagTagBase) :
  151.   SBinetLogger(MODULE_SBCACHE, log, diagTagBase)
  152. {
  153.   VXIcacheInterface::GetVersion = SBcacheInterface::GetVersion;
  154.   VXIcacheInterface::GetImplementationName = 
  155.     SBcacheInterface::GetImplementationName;
  156.   
  157.   VXIcacheInterface::Open     = SBcacheInterface::CallOpen;
  158.   VXIcacheInterface::Close    = SBcacheInterface::CallClose;
  159.   VXIcacheInterface::Unlock   = SBcacheInterface::CallUnlock;
  160.   VXIcacheInterface::Read     = SBcacheInterface::CallRead;
  161.   VXIcacheInterface::Write    = SBcacheInterface::CallWrite;
  162.   VXIcacheInterface::OpenEx   = SBcacheInterface::CallOpenEx;
  163.   VXIcacheInterface::CloseEx  = SBcacheInterface::CallCloseEx;
  164.   VXIcacheInterface::UnlockEx = SBcacheInterface::CallUnlockEx;
  165. }
  166. VXIcacheResult
  167. SBcacheInterface::Open(const VXIchar *moduleName,
  168.                        const VXIchar *key,
  169.                        VXIcacheOpenMode mode,
  170.                        VXIint32 flags,
  171.                        const VXIMap *properties,
  172.                        VXIMap *streamInfo,
  173.                        VXIcacheStream **stream )
  174. {
  175.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  176.   
  177.   if (( ! key ) || ( ! key[0] ) || ( ! stream ) ||
  178.       ( mode > CACHE_MODE_READ_CREATE )) {
  179.     Error (200, NULL);
  180.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  181.   } else {
  182.     // Create the final cache key
  183.     SBcacheKey finalKey = MakeCacheKey (key);
  184.     if ( finalKey.length( ) == 0 ) {
  185.       Error(100, NULL);
  186.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  187.     } else {
  188.       // Open the cache entry
  189.       SBcacheString finalModuleName;
  190.       if ( moduleName )
  191. finalModuleName = moduleName;
  192.       
  193.       rc = gblCacheMgr->Open (GetLog( ), finalModuleName, finalKey, mode,
  194.       flags, properties, streamInfo, stream);
  195.     }
  196.   }
  197.   
  198.   return rc;
  199. }
  200. VXIcacheResult
  201. SBcacheInterface::Open(const VXIchar *moduleName,
  202.                        const VXIbyte *key,
  203.        VXIulong keySizeBytes,
  204.                        VXIcacheOpenMode mode,
  205.                        VXIint32 flags,
  206.                        const VXIMap *properties,
  207.                        VXIMap *streamInfo,
  208.                        VXIcacheStream **stream )
  209. {
  210.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  211.   
  212.   if (( ! key ) || ( keySizeBytes < 1 ) || ( ! stream ) ||
  213.       ( mode > CACHE_MODE_READ_CREATE )) {
  214.     Error (200, NULL);
  215.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  216.   } else {
  217.     // Create the final cache key
  218.     SBcacheKey finalKey = MakeCacheKey (key, keySizeBytes);
  219.     if ( finalKey.length( ) == 0 ) {
  220.       Error(100, NULL);
  221.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  222.     } else {
  223.       // Open the cache entry
  224.       SBcacheString finalModuleName;
  225.       if ( moduleName )
  226. finalModuleName = moduleName;
  227.       
  228.       rc = gblCacheMgr->Open (GetLog( ), finalModuleName, finalKey, mode,
  229.       flags, properties, streamInfo, stream);
  230.     }
  231.   }
  232.   
  233.   return rc;
  234. }
  235. VXIcacheResult
  236. SBcacheInterface::Close (VXIbool keepEntry,
  237.  VXIcacheStream **stream)
  238.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  239.   if (( ! stream ) || ( ! *stream )) {
  240.     Error (201, NULL);
  241.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  242.   } else {
  243.     VXIcacheResult rc2;
  244.     if ( ! keepEntry ) {
  245.       // May have deleted the entry from the table already, so ignore
  246.       // all non-fatal errors
  247.       rc2 = gblCacheMgr->Delete (GetLog( ), (*stream)->GetKey( ), true);
  248.       if ( rc2 < VXIcache_RESULT_SUCCESS )
  249. rc = rc2;
  250.     }
  251.     
  252.     rc2 = (*stream)->Close (keepEntry ? false : true);
  253.     if ( rc2 != VXIcache_RESULT_SUCCESS )
  254.       rc = rc2;
  255.     delete *stream;
  256.     *stream = NULL;
  257.   }
  258.   return rc;
  259. }
  260. VXIcacheResult
  261. SBcacheInterface::Unlock(const VXIchar *key)
  262. {
  263.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  264.   if (( ! key ) || ( ! key[0] )) {
  265.     Error (202, NULL);
  266.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  267.   } else {
  268.     // Create the final cache key
  269.     SBcacheKey finalKey = MakeCacheKey (key);
  270.     if ( finalKey.length( ) == 0 ) {
  271.       Error(100, NULL);
  272.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  273.     } else {
  274.       // Unlock the entry
  275.       rc = gblCacheMgr->Unlock (GetLog( ), finalKey);
  276.     }
  277.   }
  278.   return rc;
  279. }
  280.     
  281. VXIcacheResult
  282. SBcacheInterface::Unlock(const VXIbyte *key,
  283.  VXIulong keySizeBytes)
  284. {
  285.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  286.   if (( ! key ) || ( keySizeBytes < 1 )) {
  287.     Error (202, NULL);
  288.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  289.   } else {
  290.     // Create the final cache key
  291.     SBcacheKey finalKey = MakeCacheKey (key, keySizeBytes);
  292.     if ( finalKey.length( ) == 0 ) {
  293.       Error(100, NULL);
  294.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  295.     } else {
  296.       // Unlock the entry
  297.       rc = gblCacheMgr->Unlock (GetLog( ), finalKey);
  298.     }
  299.   }
  300.   return rc;
  301. }
  302.     
  303. VXIcacheResult
  304. SBcacheInterface::Read(VXIbyte        *buffer,
  305.                        VXIulong        buflen,
  306.                        VXIulong       *nread,
  307.                        VXIcacheStream *stream )
  308. {
  309.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  310.   if (( ! buffer ) || ( buflen < 1 ) || ( ! nread ) || ( ! stream )) {
  311.     Error (203, NULL);
  312.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  313.   } else {
  314.     rc = stream->Read (buffer, buflen, nread);
  315.   }
  316.   return rc;
  317. }
  318. VXIcacheResult
  319. SBcacheInterface::Write(const VXIbyte  *buffer,
  320.                         VXIulong        buflen,
  321.                         VXIulong       *nwritten,
  322.                         VXIcacheStream *stream )
  323. {
  324.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  325.   if (( ! buffer ) || ( buflen < 1 ) || ( ! nwritten ) || ( ! stream )) {
  326.     Error (204, NULL);
  327.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  328.   } else {
  329.     rc = stream->Write (buffer, buflen, nwritten);
  330.     if (( rc == VXIcache_RESULT_SUCCESS ) ||
  331. ( rc == VXIcache_RESULT_WOULD_BLOCK ))
  332.       gblCacheMgr->WriteNotification (GetLog( ), stream->GetModuleName( ),
  333.       *nwritten, stream->GetKey());
  334.   }
  335.   return rc;
  336. }
  337. /**
  338.  * Use MD5 to generate a key off binary data
  339.  */
  340. SBcacheKey 
  341. SBcacheInterface::MakeCacheKey(const VXIbyte *buf, 
  342.        VXIunsigned    bufSizeBytes) const
  343. {
  344.   // Create a MD5 digest for the key
  345.   unsigned char digest[16];
  346.   memset(digest, 0, 16 * sizeof(unsigned char));
  347.   MD5_CTX md5;
  348.   MD5Init (&md5);
  349.   MD5Update (&md5, buf, bufSizeBytes);
  350.   MD5Final (digest, &md5);
  351.   // The final key is an ASCII string using a base64 encoding of the
  352.   // binary MD5 digest
  353.   VXIchar keyBuf[B64ELEN(16) + 1];
  354.   keyBuf[B64ELEN(16)] = L'';
  355.   wcsb64e (digest, 16, keyBuf);
  356.   return keyBuf;
  357. }
  358. /**
  359.  * Generate a key off wide character data
  360.  */
  361. SBcacheKey
  362. SBcacheInterface::MakeCacheKey(const VXIchar *key) const
  363. {
  364.   // If the text is too long, create a MD5 based key
  365.   size_t keyLen = ::wcslen (key);
  366.   if ( keyLen > MAX_CACHE_KEY )
  367.     return MakeCacheKey ((const VXIbyte *) key, keyLen * sizeof(*key));
  368.   return key;
  369. }
  370. /********************************************************/
  371. /* Map the static functions to the real implementations */
  372. /********************************************************/
  373. VXIint32 SBcacheInterface::GetVersion(void)
  374. {
  375.   return VXI_CURRENT_VERSION;
  376. }
  377. const VXIchar* SBcacheInterface::GetImplementationName(void)
  378. {
  379.   static const VXIchar IMPLEMENTATION_NAME[] = SBCACHE_IMPLEMENTATION_NAME;
  380.   return IMPLEMENTATION_NAME;
  381. }
  382. VXIcacheResult
  383. SBcacheInterface::CallOpen(struct VXIcacheInterface *pThis,
  384.                            const VXIchar *moduleName,
  385.                            const VXIchar *key,
  386.                            VXIcacheOpenMode mode,
  387.                            VXIint32 flags,
  388.                            const VXIMap *properties,
  389.                            VXIMap *streamInfo,
  390.                            VXIcacheStream **stream )
  391. {
  392.   if (!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  393.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  394.   const VXIchar *modeName;
  395.   switch ( mode ) {
  396.   case CACHE_MODE_READ:
  397.     modeName = L"read";
  398.     break;
  399.   case CACHE_MODE_WRITE:
  400.     modeName = L"write";
  401.     break;
  402.   case CACHE_MODE_READ_CREATE:
  403.     modeName = L"readCreate";
  404.     break;
  405.   default:
  406.     modeName = L"unknownMode";
  407.     break;
  408.   }
  409.     
  410.   me->Diag (SBCACHE_API_TAGID, L"Open", 
  411.     L"entering: 0x%p, %s, %0.256s, 0x%x [%s], 0x%x [%s%s%s], 0x%p, "
  412.     L"0x%p, 0x%p", pThis, moduleName, key, mode, modeName,
  413.     flags, ((flags & CACHE_FLAG_LOCK) ? L"lock, " : L""),
  414.     ((flags & CACHE_FLAG_LOCK_MEMORY) ? L"memory lock, " : L""),
  415.     ((flags & CACHE_FLAG_NONBLOCKING_IO) ? L"non-blocking I/O" : L""),
  416.     properties, streamInfo, stream);
  417.   if (stream)
  418.     *stream = NULL;
  419.   VXIcacheResult rc = me->Open (moduleName, key, mode, flags, properties,
  420. streamInfo, stream);
  421.   me->Diag (SBCACHE_API_TAGID, L"Open", L"exiting: %d, 0x%p", rc,
  422.     (stream ? *stream : NULL));
  423.   return rc;
  424. }
  425. VXIcacheResult
  426. SBcacheInterface::CallClose(struct VXIcacheInterface *pThis,
  427.                             VXIcacheStream **stream )
  428. {
  429.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  430.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  431.   
  432.   me->Diag (SBCACHE_API_TAGID, L"Close", L"entering: 0x%p, 0x%p [0x%p]",
  433.     pThis, stream, (stream ? *stream : NULL));
  434.   VXIcacheResult rc = me->Close (TRUE, stream);
  435.   me->Diag (SBCACHE_API_TAGID, L"Close", L"exiting: %d", rc);
  436.   return rc;
  437. }
  438. VXIcacheResult
  439. SBcacheInterface::CallUnlock(struct VXIcacheInterface *pThis,
  440.                              const VXIchar *key)
  441. {
  442.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  443.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  444.   me->Diag (SBCACHE_API_TAGID, L"Unlock", L"entering: 0x%p, %0.256s",
  445.     pThis, key);
  446.   VXIcacheResult rc = me->Unlock (key);
  447.   me->Diag (SBCACHE_API_TAGID, L"Unlock", L"exiting: %d", rc);
  448.   return rc;
  449. }
  450. VXIcacheResult
  451. SBcacheInterface::CallRead(struct VXIcacheInterface *pThis,
  452.                            VXIbyte   *buffer,
  453.                            VXIulong   buflen,
  454.                            VXIulong  *nread,
  455.                            VXIcacheStream *stream )
  456. {
  457.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  458.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  459.   
  460.   me->Diag (SBCACHE_API_TAGID, L"Read", 
  461.     L"entering: 0x%p, 0x%p, %lu, 0x%p, 0x%p",
  462.     pThis, buffer, buflen, nread, stream);
  463.   VXIcacheResult rc = me->Read(buffer, buflen, nread, stream );
  464.   me->Diag (SBCACHE_API_TAGID, L"Read", L"exiting: %d, %lu", rc,
  465.     (nread ? *nread : 0));
  466.   return rc;
  467. }
  468.     
  469. VXIcacheResult
  470. SBcacheInterface::CallWrite(struct VXIcacheInterface *pThis,
  471.                             const VXIbyte *buffer,
  472.                             VXIulong buflen,
  473.                             VXIulong *nwritten,
  474.                             VXIcacheStream *stream )
  475. {
  476.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  477.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  478.   me->Diag (SBCACHE_API_TAGID, L"Write", 
  479.     L"entering: 0x%p, 0x%p, %lu, 0x%p, 0x%p",
  480.     pThis, buffer, buflen, nwritten, stream);
  481.   
  482.   VXIcacheResult rc = me->Write (buffer, buflen, nwritten, stream );
  483.   me->Diag (SBCACHE_API_TAGID, L"Write", L"exiting: %d, %lu", rc,
  484.     (nwritten ? *nwritten : 0));
  485.   return rc;
  486. }
  487. VXIcacheResult
  488. SBcacheInterface::CallOpenEx(struct VXIcacheInterface *pThis,
  489.      const VXIchar *moduleName,
  490.      const VXIbyte *key,
  491.      VXIulong keySizeBytes,
  492.      VXIcacheOpenMode mode,
  493.      VXIint32 flags,
  494.      const VXIMap *properties,
  495.      VXIMap *streamInfo,
  496.      VXIcacheStream **stream )
  497. {
  498.   if (!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  499.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  500.   me->Diag (SBCACHE_API_TAGID, L"OpenEx", 
  501.     L"entering: 0x%p, %s, 0x%p, %lu, 0x%x [%s], 0x%x [%s%s%s], 0x%p, "
  502.     L"0x%p, 0x%p", pThis, moduleName, key, keySizeBytes, mode, 
  503.     (mode == CACHE_MODE_READ ? L"read" :
  504.      (mode == CACHE_MODE_WRITE ? L"write" : L"<unknown>")),
  505.     flags, ((flags & CACHE_FLAG_LOCK) ? L"lock, " : L""),
  506.     ((flags & CACHE_FLAG_LOCK_MEMORY) ? L"memory lock, " : L""),
  507.     ((flags & CACHE_FLAG_NONBLOCKING_IO) ? L"non-blocking I/O" : L""),
  508.     properties, streamInfo, stream);
  509.   
  510.   VXIcacheResult rc = me->Open (moduleName, key, keySizeBytes, mode, flags,
  511. properties, streamInfo, stream);
  512.   me->Diag (SBCACHE_API_TAGID, L"OpenEx", L"exiting: %d, 0x%p", rc,
  513.     (stream ? *stream : NULL));
  514.   return rc;
  515. }
  516. VXIcacheResult
  517. SBcacheInterface::CallCloseEx(struct VXIcacheInterface *pThis,
  518.       VXIbool keepEntry,
  519.       VXIcacheStream **stream )
  520. {
  521.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  522.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  523.   
  524.   me->Diag (SBCACHE_API_TAGID, L"CloseEx", L"entering: 0x%p, %s, 0x%p [0x%p]",
  525.     pThis, (keepEntry ? L"TRUE" : L"FALSE"), stream, 
  526.     (stream ? *stream : NULL));
  527.   VXIcacheResult rc = me->Close (keepEntry, stream);
  528.   me->Diag (SBCACHE_API_TAGID, L"CloseEx", L"exiting: %d", rc);
  529.   return rc;
  530. }
  531. VXIcacheResult
  532. SBcacheInterface::CallUnlockEx(struct VXIcacheInterface *pThis,
  533.        const VXIbyte *key,
  534.        VXIulong keySizeBytes)
  535. {
  536.   if(!pThis) return VXIcache_RESULT_INVALID_ARGUMENT;
  537.   SBcacheInterface * me = static_cast<SBcacheInterface *>(pThis);
  538.   me->Diag (SBCACHE_API_TAGID, L"UnlockEx", L"entering: 0x%p, 0x%p, %lu",
  539.     pThis, key, keySizeBytes);
  540.   VXIcacheResult rc = me->Unlock (key, keySizeBytes);
  541.   me->Diag (SBCACHE_API_TAGID, L"UnlockEx", L"exiting: %d", rc);
  542.   return rc;
  543. }
  544. /********************************************/
  545. /* Public Interface DLL Functions           */
  546. /********************************************/
  547. SBCACHE_API
  548. VXIcacheResult SBcacheInit( VXIlogInterface    *log,
  549.                             const VXIunsigned   diagTagBase,
  550.                             const VXIchar      *pCacheFolder,
  551.                             const VXIint        nCacheTotalSizeMB,
  552.                             const VXIint        nCacheEntryMaxSizeMB,
  553.                             const VXIint        nCacheEntryExpTimeSec,
  554.                             VXIbool             fUnlockEntries,
  555.                             const VXIint        nCacheLowWaterMB)
  556. {
  557.   if (log == NULL)
  558.     return VXIcache_RESULT_INVALID_ARGUMENT;
  559.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  560.   SBinetLogFunc apiTrace (log, diagTagBase + SBCACHE_API_TAGID, 
  561.   L"SBcacheInit", (int *) &rc, 
  562.   L"entering: 0x%p, %u, %s, %d, %d, %d, %d, %d",
  563.   log, diagTagBase, pCacheFolder, 
  564.   nCacheTotalSizeMB, nCacheEntryMaxSizeMB,
  565.   nCacheEntryExpTimeSec, fUnlockEntries,
  566.   nCacheLowWaterMB);
  567.   
  568.   // Avoid double initialization
  569.   if ( gblCacheMgr ) {
  570.     SBinetLogger::Error (log, MODULE_SBCACHE, 101, NULL);
  571.     return (rc = VXIcache_RESULT_SUCCESS);
  572.   }
  573.   // Copy over globals
  574.   gblDiagTagBase = diagTagBase;
  575.   // Check the remaining arguments
  576.   if ((! pCacheFolder) || (! pCacheFolder[0])) {
  577.     SBinetLogger::Error (log, MODULE_SBCACHE, 102, NULL);
  578.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  579.   } else {
  580.     // Ensure we only have 8 bit characters for the folder name
  581.     int i;
  582.     for (i = 0; 
  583.  (pCacheFolder[i] != L'') && ((pCacheFolder[i] & 0xff00) == 0); i++)
  584.       ; /* keep going */
  585.     
  586.     if ( pCacheFolder[i] != L'' ) {
  587.       SBinetLogger::Error (log, MODULE_SBCACHE, 103, L"%s%s",
  588.    L"configured", pCacheFolder);
  589.       rc = VXIcache_RESULT_INVALID_ARGUMENT;
  590.     }
  591.   }
  592.   if ( nCacheTotalSizeMB < 0 ) {
  593.     SBinetLogger::Error (log, MODULE_SBCACHE, 104, L"%s%d", L"configured",
  594.  nCacheTotalSizeMB);
  595.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  596.   }
  597.   if ( nCacheEntryMaxSizeMB < 0 ) {
  598.     SBinetLogger::Error (log, MODULE_SBCACHE, 105, L"%s%d", L"configured",
  599.  nCacheEntryMaxSizeMB);
  600.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  601.   }
  602.   if ( nCacheEntryExpTimeSec <= 0 ) {
  603.     SBinetLogger::Error (log, MODULE_SBCACHE, 106, L"%s%d", L"configured",
  604.  nCacheEntryExpTimeSec);
  605.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  606.   }
  607.   if ( nCacheEntryMaxSizeMB > nCacheTotalSizeMB ) {
  608.     SBinetLogger::Error (log, MODULE_SBCACHE, 107, L"%s%d%s%d", 
  609.  L"entryMaxSizeMB", nCacheEntryMaxSizeMB, 
  610.  L"totalSizeMB", nCacheTotalSizeMB);
  611.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  612.   }
  613.   if ( nCacheLowWaterMB > nCacheTotalSizeMB ) {
  614.     SBinetLogger::Error (log, MODULE_SBCACHE, 107, L"%s%d%s%d", 
  615.  L"cacheLowWaterMB", nCacheLowWaterMB,
  616.  L"totalSizeMB", nCacheTotalSizeMB);
  617.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  618.   }
  619.   // Create the cache manager
  620.   if ( rc == VXIcache_RESULT_SUCCESS ) {
  621.     gblCacheMgr = new SBcacheManager (log, diagTagBase);
  622.     if (! gblCacheMgr) {
  623.       SBinetLogger::Error (log, MODULE_SBCACHE, 100, NULL);    
  624.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  625.     } else {
  626.       SBcacheNString nCacheFolderStr;
  627.       for (int i = 0; pCacheFolder[i] != L''; i++)
  628. nCacheFolderStr += SBinetW2C (pCacheFolder[i]);
  629.       
  630.       rc = gblCacheMgr->Create (nCacheFolderStr, nCacheTotalSizeMB * 1000000, 
  631. nCacheEntryMaxSizeMB * 1000000, 
  632. nCacheEntryExpTimeSec, fUnlockEntries,
  633.                                 nCacheLowWaterMB * 1000000);
  634.       
  635.       if ( rc != VXIcache_RESULT_SUCCESS ) {
  636. // Error already reported
  637. delete gblCacheMgr;
  638. gblCacheMgr = NULL;
  639.       }
  640.     }
  641.   }
  642.   return rc;
  643. }
  644. SBCACHE_API
  645. VXIcacheResult SBcacheShutDown( VXIlogInterface *log )
  646. {
  647.   if ( !log )
  648.     return VXIcache_RESULT_INVALID_ARGUMENT;
  649.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  650.   SBinetLogFunc apiTrace (log, gblDiagTagBase + SBCACHE_API_TAGID, 
  651.   L"SBcacheShutDown", (int *) &rc, 
  652.   L"entering: 0x%p", log);
  653.   // Destroy the cache manager
  654.   if (! gblCacheMgr) {
  655.     SBinetLogger::Error (log, MODULE_SBCACHE, 205, NULL);
  656.     rc = VXIcache_RESULT_NON_FATAL_ERROR;
  657.   } else {
  658.     delete gblCacheMgr;
  659.     gblCacheMgr = NULL;
  660.   }
  661.   return rc;
  662. }
  663. SBCACHE_API
  664. VXIcacheResult SBcacheCreateResource( VXIlogInterface    *log,
  665.                                       VXIcacheInterface **ppVXIcache)  
  666. {
  667.   if ( !log )
  668.     return VXIcache_RESULT_INVALID_ARGUMENT;
  669.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  670.   SBinetLogFunc apiTrace (log, gblDiagTagBase + SBCACHE_API_TAGID, 
  671.   L"SBcacheCreateResource", (int *) &rc, 
  672.   L"entering: 0x%p, 0x%p", log, ppVXIcache);
  673.   
  674.   // Create the cache interface
  675.   if ( ! ppVXIcache ) {
  676.     SBinetLogger::Error (log, MODULE_SBCACHE, 108, NULL);
  677.     rc = VXIcache_RESULT_INVALID_ARGUMENT;
  678.   } else {
  679.     *ppVXIcache = new SBcacheInterface (log, gblDiagTagBase);
  680.     if ( ! *ppVXIcache ) {
  681.       SBinetLogger::Error (log, MODULE_SBCACHE, 100, NULL);
  682.       rc = VXIcache_RESULT_OUT_OF_MEMORY;
  683.     }
  684.   }
  685.   return rc;
  686. }
  687. SBCACHE_API
  688. VXIcacheResult SBcacheDestroyResource( VXIcacheInterface **ppVXIcache )
  689. {
  690.   if (( ! ppVXIcache ) || ( ! *ppVXIcache ))
  691.     return VXIcache_RESULT_INVALID_ARGUMENT;
  692.   SBcacheInterface * me = static_cast<SBcacheInterface *>(*ppVXIcache);
  693.   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
  694.   SBinetLogFunc apiTrace (me->GetLog( ), 
  695.   me->GetDiagBase( ) + SBCACHE_API_TAGID,
  696.   L"Read", (int *) &rc, L"entering: 0x%p [0x%p]", 
  697.   ppVXIcache, *ppVXIcache);
  698.   // Destroy the cache interface
  699.   delete me;
  700.   *ppVXIcache = NULL;
  701.   
  702.   return rc;
  703. }