📄 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. * ***********************************************************************/ #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(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -