📄 sbinetfilestream.cpp
字号:
/****************License************************************************
*
* Copyright 2000-2003. ScanSoft, Inc.
*
* Use of this software is subject to notices and obligations set forth
* in the SpeechWorks Public License - Software Version 1.2 which is
* included with this software.
*
* ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,
* SpeechWorks and the SpeechWorks logo are registered trademarks or
* trademarks of SpeechWorks International, Inc. in the United States
* and other countries.
*
***********************************************************************/
#include <vxibuildopts.h>
#if P_VXI
#ifndef _SB_USE_STD_NAMESPACE
#define _SB_USE_STD_NAMESPACE
#endif
#include "SBinetFileStream.hpp"
#include "SBinetValidator.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
typedef struct _stat VXIStatStruct;
#define VXIStat(a,b) _stat(a,b)
#else
typedef struct stat VXIStatStruct;
#define VXIStat(a,b) stat(a,b)
#endif
VXIinetResult
SBinetFileStream::Open(VXIint32 flags,
const VXIMap *properties,
VXIMap *streamInfo)
{
VXIinetResult returnValue = VXIinet_RESULT_SUCCESS;
/*
Get the flag to determine whether to open local files. Also check
the validator to see if it contains INET_INFO_VALIDATOR and if it
does contain the modified time. */
SBinetValidator validator(GetLog(), GetDiagBase());
const VXIValue *validatorVal = NULL;
if(properties)
{
const VXIValue *val = VXIMapGetProperty(properties, INET_OPEN_LOCAL_FILE);
if(val != NULL)
{
if (VXIValueGetType(val) == VALUE_INTEGER)
{
if ( VXIIntegerValue((const VXIInteger *) val) == FALSE )
returnValue = VXIinet_RESULT_LOCAL_FILE;
}
else
{
Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
L"Passed invalid type for INET_OPEN_LOCAL_FILE property");
}
}
// SBinetValidator::Create() logs errors for us
validatorVal = VXIMapGetProperty(properties, INET_OPEN_IF_MODIFIED);
if((validatorVal != NULL) &&
(validator.Create(validatorVal) != VXIinet_RESULT_SUCCESS))
validatorVal = NULL;
}
Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
_url->getAbsolute( ));
// Stat the file to make sure it exists and to get the length and
// last modified time
VXIStatStruct statInfo;
if ( VXIStat(SBinetNString(_url->getPath()).c_str(), &statInfo) != 0 ) {
Error(222, L"%s%s", L"File", _url->getPath());
return(VXIinet_RESULT_NOT_FOUND);
}
_content_length = statInfo.st_size;
// If there is a conditional open using a validator, see if the
// validator is still valid (no need to re-read and re-process)
if (validatorVal)
{
if (! validator.isModified(statInfo.st_mtime, statInfo.st_size))
{
Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
L"Validator OK, returning NOT_MODIFIED");
returnValue = VXIinet_RESULT_NOT_MODIFIED;
}
else
{
Diag(MODULE_SBINET_STREAM_TAGID, L"SBinetFileStream::Open",
L"Validator modified, must re-fetch");
}
}
if(( returnValue != VXIinet_RESULT_NOT_MODIFIED ) &&
( returnValue != VXIinet_RESULT_LOCAL_FILE ))
{
// Use fopen for now. Note: Open support reads for now
_pFile = ::fopen( SBinetNString(_url->getPath()).c_str(), "rb" );
if(!_pFile){
Error(223, L"%s%s", L"File", _url->getPath());
return(VXIinet_RESULT_NOT_FOUND);
}
_ReadSoFar = 0;
}
if( streamInfo != NULL )
{
// Use extension mapping algorithm to determine MIME content type
VXIString *guessContent = _url->getContentTypeFromUrl();
if (guessContent == NULL) {
guessContent = VXIStringCreate(_channel->getDefaultMimeType());
// This error message is useful, but unfortunately it gets printed
// for all the grammar files etc. whose extensions are unknown...
//Error (303, L"%s%s", L"URL", _url->getPath());
}
VXIMapSetProperty(streamInfo, INET_INFO_MIME_TYPE, (VXIValue*) guessContent);
// Set the absolute path, any file:// prefix and host name is
// already stripped prior to this method being invoked
VXIMapSetProperty(streamInfo, INET_INFO_ABSOLUTE_NAME,
(VXIValue*)VXIStringCreate( _url->getPath() ));
// Set the validator property
VXIValue *newValidator = NULL;
if (returnValue == VXIinet_RESULT_NOT_MODIFIED) {
newValidator = VXIValueClone(validatorVal);
} else {
SBinetValidator validator(GetLog(), GetDiagBase());
if (validator.Create(_url->getPath(), statInfo.st_size,
statInfo.st_mtime) == VXIinet_RESULT_SUCCESS)
{
newValidator = (VXIValue *) validator.serialize();
}
}
if (newValidator)
VXIMapSetProperty(streamInfo, INET_INFO_VALIDATOR, newValidator);
else {
Error(103, NULL);
returnValue = VXIinet_RESULT_OUT_OF_MEMORY;
}
// Set the size
VXIMapSetProperty(streamInfo, INET_INFO_SIZE_BYTES,
(VXIValue*)VXIIntegerCreate( _content_length));
}
return returnValue;
}
//
// Read is the same for all File requests (GET and POST)
//
VXIinetResult
SBinetFileStream::Read(VXIbyte *buffer,
VXIulong buflen,
VXIulong *nread)
{
if(!buffer || !nread)
{
Error(200, L"%s%s", L"Operation", L"Read");
return(VXIinet_RESULT_INVALID_ARGUMENT);
}
if(!_pFile) return(VXIinet_RESULT_FAILURE);
int toRead = buflen;
/*
* Note: don't try to remember hos many byte are left in file and
* set toRead based on this, or you will never get EOF
*/
int n = ::fread(buffer,sizeof(VXIbyte),toRead,_pFile);
if(n <= 0)
{
// Check for EOF, otherwise ERROR
// printf("read %d eof = %d\n",n,feof(_pFile));
if(feof(_pFile))
{
*nread = 0;
return VXIinet_RESULT_END_OF_STREAM;
}
Close();
Error(224, L"%s%s", L"File", _url->getPath());
return VXIinet_RESULT_FAILURE;
}
*nread = n;
if( feof(_pFile))
{
return VXIinet_RESULT_END_OF_STREAM;
}
return VXIinet_RESULT_SUCCESS;
}
VXIinetResult SBinetFileStream::Write(const VXIbyte* pBuffer,
VXIulong nBuflen,
VXIulong* pnWritten)
{
return VXIinet_RESULT_UNSUPPORTED;
}
VXIinetResult SBinetFileStream::Close()
{
/* Clean up the request */
if(_pFile)
{
::fclose(_pFile);
_pFile = NULL;
return VXIinet_RESULT_SUCCESS;
}
else
{
return VXIinet_RESULT_INVALID_ARGUMENT;
}
}
SBinetFileStream::SBinetFileStream(SBinetURL* url,
SBinetChannel* ch,
VXIlogInterface *log,
VXIunsigned diagLogBase):
SBinetStream(url, log, diagLogBase), _channel(ch)
{
_pFile = NULL;
_content_length = 0;
_ReadSoFar = 0;
}
SBinetFileStream::~SBinetFileStream()
{
Close();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -