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

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. #ifndef _SB_USE_STD_NAMESPACE
  23. #define _SB_USE_STD_NAMESPACE
  24. #endif
  25. #include "SBinetFileStream.hpp"
  26. #include "SBinetValidator.h"
  27. #include <stdio.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #ifdef _WIN32
  31. typedef struct _stat VXIStatStruct;
  32. #define VXIStat(a,b) _stat(a,b)
  33. #else
  34. typedef struct stat  VXIStatStruct;
  35. #define VXIStat(a,b) stat(a,b)
  36. #endif
  37. VXIinetResult
  38. SBinetFileStream::Open(VXIint32                  flags,
  39.        const VXIMap             *properties,
  40.        VXIMap                   *streamInfo)
  41. {
  42.   VXIinetResult returnValue = VXIinet_RESULT_SUCCESS;
  43.   /*
  44.      Get the flag to determine whether to open local files. Also check
  45.      the validator to see if it contains INET_INFO_VALIDATOR and if it
  46.      does contain the modified time. */
  47.   SBinetValidator validator(GetLog(), GetDiagBase());
  48.   const VXIValue *validatorVal = NULL;
  49.   if (properties)
  50.   {
  51.     const VXIValue *val = VXIMapGetProperty(properties, INET_OPEN_LOCAL_FILE);
  52.     if (val != NULL)
  53.     {
  54.       if (VXIValueGetType(val) == VALUE_INTEGER)
  55.       {
  56.         if (VXIIntegerValue((const VXIInteger *) val) == FALSE)
  57.           returnValue = VXIinet_RESULT_LOCAL_FILE;
  58.       }
  59.       else
  60.       {
  61.         Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
  62.              L"Passed invalid type for INET_OPEN_LOCAL_FILE property");
  63.       }
  64.     }
  65.     // SBinetValidator::Create() logs errors for us
  66.     validatorVal = VXIMapGetProperty(properties, INET_OPEN_IF_MODIFIED);
  67.     if((validatorVal != NULL) &&
  68.        (validator.Create(validatorVal) != VXIinet_RESULT_SUCCESS))
  69.       validatorVal = NULL;
  70.   }
  71.   Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
  72.        _url->getAbsolute( ));
  73.   // Stat the file to make sure it exists and to get the length and
  74.   // last modified time
  75.   VXIStatStruct statInfo;
  76.   if (VXIStat(SBinetNString(_url->getPath()).c_str(), &statInfo) != 0) {
  77.     Error(222, L"%s%s", L"File", _url->getPath());
  78.     return(VXIinet_RESULT_NOT_FOUND);
  79.   }
  80.   _content_length = statInfo.st_size;
  81.   // If there is a conditional open using a validator, see if the
  82.   // validator is still valid (no need to re-read and re-process)
  83.   if (validatorVal)
  84.   {
  85.     if (! validator.isModified(statInfo.st_mtime, statInfo.st_size))
  86.     {
  87.       Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
  88.            L"Validator OK, returning NOT_MODIFIED");
  89.       returnValue = VXIinet_RESULT_NOT_MODIFIED;
  90.     }
  91.     else
  92.     {
  93.       Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
  94.            L"Validator modified, must re-fetch");
  95.     }
  96.   }
  97.   if (returnValue != VXIinet_RESULT_LOCAL_FILE)
  98.   {
  99.     // Use fopen for now. Note: Open support reads for now
  100.     _pFile = ::fopen( SBinetNString(_url->getPath()).c_str(), "rb" );
  101.     if(!_pFile){
  102.       Error(223, L"%s%s", L"File", _url->getPath());
  103.       return(VXIinet_RESULT_NOT_FOUND);
  104.     }
  105.     _ReadSoFar = 0;
  106.   }
  107.   if (streamInfo != NULL)
  108.   {
  109.     // Set FILE data source information   
  110.     VXIMapSetProperty(streamInfo, INET_INFO_DATA_SOURCE, 
  111.                      (VXIValue*) VXIIntegerCreate(INET_DATA_SOURCE_FILE));
  112.     
  113.     // Use extension mapping algorithm to determine MIME content type
  114.     VXIString *guessContent = _url->getContentTypeFromUrl();
  115.     if (guessContent == NULL) {
  116.       guessContent = VXIStringCreate(_channel->getDefaultMimeType());
  117.       // This error message is useful, but unfortunately it gets printed
  118.       // for all the grammar files etc. whose extensions are unknown...
  119.       //Error (303, L"%s%s", L"URL", _url->getPath());
  120.     }
  121.     VXIMapSetProperty(streamInfo, INET_INFO_MIME_TYPE, (VXIValue*) guessContent);
  122.     // Set the absolute path, any file:// prefix and host name is
  123.     // already stripped prior to this method being invoked
  124.     VXIMapSetProperty(streamInfo, INET_INFO_ABSOLUTE_NAME,
  125.       (VXIValue*)VXIStringCreate( _url->getPath() ));
  126.     // Set the validator property
  127.     VXIValue *newValidator = NULL;
  128.     if (returnValue == VXIinet_RESULT_NOT_MODIFIED) {
  129.       newValidator = VXIValueClone(validatorVal);
  130.     } else {
  131.       SBinetValidator validator(GetLog(), GetDiagBase());
  132.       if (validator.Create(_url->getPath(), statInfo.st_size,
  133.                            statInfo.st_mtime) == VXIinet_RESULT_SUCCESS)
  134.       {
  135. newValidator = (VXIValue *) validator.serialize();
  136.       }
  137.     }
  138.     if (newValidator)
  139.       VXIMapSetProperty(streamInfo, INET_INFO_VALIDATOR, newValidator);
  140.     else {
  141.       Error(103, NULL);
  142.       returnValue = VXIinet_RESULT_OUT_OF_MEMORY;
  143.     }
  144.     // Set the size
  145.     VXIMapSetProperty(streamInfo, INET_INFO_SIZE_BYTES,
  146.       (VXIValue*)VXIIntegerCreate( _content_length));
  147.   }
  148.   if (!validatorVal && (returnValue == VXIinet_RESULT_NOT_MODIFIED))
  149.     return VXIinet_RESULT_SUCCESS;
  150.   return returnValue;
  151. }
  152. //
  153. // Read is the same for all File requests (GET and POST)
  154. //
  155. VXIinetResult
  156. SBinetFileStream::Read(VXIbyte                 *buffer,
  157.        VXIulong                 buflen,
  158.        VXIulong                *nread)
  159. {
  160.   if(!buffer || !nread)
  161.   {
  162.     Error(200, L"%s%s", L"Operation", L"Read");
  163.     return(VXIinet_RESULT_INVALID_ARGUMENT);
  164.   }
  165.   if(!_pFile) return(VXIinet_RESULT_FAILURE);
  166.   int toRead = buflen;
  167.   /*
  168.    * Note: don't try to remember hos many byte are left in file and
  169.    *   set toRead based on this, or you will never get EOF
  170.    */
  171.   int n = ::fread(buffer,sizeof(VXIbyte),toRead,_pFile);
  172.   if(n <= 0)
  173.   {
  174.     // Check for EOF, otherwise ERROR
  175.     //    printf("read %d eof = %dn",n,feof(_pFile));
  176.     if(feof(_pFile))
  177.     {
  178.       *nread = 0;
  179.       return VXIinet_RESULT_END_OF_STREAM;
  180.     }
  181.     Close();
  182.     Error(224, L"%s%s", L"File", _url->getPath());
  183.     return VXIinet_RESULT_FAILURE;
  184.   }
  185.   *nread = n;
  186.   if( feof(_pFile))
  187.   {
  188.     return VXIinet_RESULT_END_OF_STREAM;
  189.   }
  190.   return VXIinet_RESULT_SUCCESS;
  191. }
  192. VXIinetResult SBinetFileStream::Write(const VXIbyte*   pBuffer,
  193.                                       VXIulong         nBuflen,
  194.                                       VXIulong*        pnWritten)
  195. {
  196.   return VXIinet_RESULT_UNSUPPORTED;
  197. }
  198. VXIinetResult SBinetFileStream::Close()
  199. {
  200.   /* Clean up the request */
  201.   if(_pFile)
  202.   {
  203.     ::fclose(_pFile);
  204.     _pFile = NULL;
  205.     return VXIinet_RESULT_SUCCESS;
  206.   }
  207.   else
  208.   {
  209.     return VXIinet_RESULT_INVALID_ARGUMENT;
  210.   }
  211. }
  212. SBinetFileStream::SBinetFileStream(SBinetURL* url,
  213.    SBinetChannel* ch,
  214.    VXIlogInterface *log,
  215.    VXIunsigned diagLogBase):
  216.   SBinetStream(url, SBinetStream_FILE, log, diagLogBase), _channel(ch)
  217. {
  218.   _pFile = NULL;
  219.   _content_length = 0;
  220.   _ReadSoFar = 0;
  221. }
  222. SBinetFileStream::~SBinetFileStream()
  223. {
  224.   Close();
  225. }