📄 httpfileobj.cpp
字号:
/****************************************************************************
* IHXFileObject::Seek
*
* This routine moves to a given position in the file. The move can be
* either from the beginning of the file (absolute), or relative to the
* current file position. When seeking has completed, the caller is
* asynchronously notified via the File Response object associated with this
* File Object. This method called by the File Format plug-in when it needs
* to seek to a location within the file.
*/
STDMETHODIMP
CHXHTTPFileObject::Seek(UINT32 offset, BOOL bIsRelative)
{
const char *seekType = NULL;
seekType = (bIsRelative == TRUE)? "REL": "ABS";
MLOG_HTTP("CHXHTTPFileObject::Seek(%u, %s)\n", offset, seekType);
m_lNewReadOffset = offset;
if(bIsRelative)
{
m_lNewReadOffset += m_ulCurrentReadOffset;
}
// Can't seek to outside the file
if( (m_lNewReadOffset < 0) || (m_lNewReadOffset > m_ulFileLength) )
{
m_lNewReadOffset = -1;
return HXR_FAIL;
}
if(!m_bInSeekDone)
{
while(m_lNewReadOffset >= 0)
{
// Cancel any pending reads
m_bReadPending = FALSE;
m_bIncompleteReadPending = FALSE;
HX_RELEASE(m_pPendingReadInfo.pPendingReadBuff);
m_ulCurrentReadOffset = m_lNewReadOffset;
m_lNewReadOffset = -1;
m_bInSeekDone = TRUE;
if (m_pFileResponse)
{
m_pFileResponse->SeekDone(HXR_OK);
}
m_bInSeekDone = FALSE;
}
}
return HXR_OK;
}
/****************************************************************************
* IHXFileObject::Advise
*
* This routine is passed information about the intended usage of this
* object. The useage will indicate whether sequential or random requests
* for information will be made. This may be useful, for example, in
* developing a caching scheme.
*/
STDMETHODIMP
CHXHTTPFileObject::Advise(UINT32 usage)
{
MLOG_HTTP("CHXHTTPFileObject::Advice(%u)\n", usage);
HX_RESULT res = HXR_FAILED;
// Because of the simple cache, only
// linear useage is allowed.
if(HX_FILEADVISE_RANDOMACCESS == usage)
{
res = HXR_ADVISE_PREFER_LINEAR;
}
return res;
} // Advise()
/****************************************************************************
* IHXFileObject::Close
*
* This routine closes the file resource and releases all resources
* associated with the object. This routine is crucial and must be called
* before the File Object is destroyed.
*/
STDMETHODIMP
CHXHTTPFileObject::Close(void)
{
MLOG_HTTP("CHXHTTPFileObject::Close()\n");
/*
* Store this in temp since calling _CleanUp()
* causes m_pFileResponse to get released. We will
* have pCallCloseDone on the stack to call
* CloseDone() and then to safely release.
*/
IHXFileResponse* pCallCloseDone = m_pFileResponse;
if(pCallCloseDone)
pCallCloseDone->AddRef();
HX_RELEASE(m_pFileResponse);
if(pCallCloseDone)
{
pCallCloseDone->CloseDone(HXR_OK);
pCallCloseDone->Release();
}
return HXR_OK;
} // Close()
// IHXRequestHandler Interface Methods
/****************************************************************************
* IHXRequestHandler::SetRequest
*
* This routine associates this File Object with the file Request object
* passed to it from the Helix core. This Request object is primarily used to
* obtain the requested URL. This method is called just after the File
* Object is created.
*/
STDMETHODIMP
CHXHTTPFileObject::SetRequest(IHXRequest* pRequest)
{
MLOG_HTTP("CHXHTTPFileObject::SetRequest()\n");
HX_RESULT res = HXR_OK;
if(pRequest == NULL)
{
res = HXR_INVALID_PARAMETER;
}
else
{
// Release any previous request object, URL
HX_RELEASE(m_pRequest);
if(m_pCHXURL != NULL)
{
delete m_pCHXURL;
m_pCHXURL = NULL;
}
// Store a reference to the object
m_pRequest = pRequest;
m_pRequest->AddRef();
const char *pURL = NULL;
if(m_pRequest->GetURL(pURL) != HXR_OK)
{
HX_RELEASE(m_pRequest);
return HXR_FAIL;
}
// Store the URL in a CHXURL object for parsing.
m_pCHXURL = new CHXURL(pURL);
if(m_pCHXURL == NULL)
{
HX_RELEASE(m_pRequest);
return HXR_FAIL;
//return HXR_OUTOFMEMORY;
}
}
return res;
} // SetRequest()
/****************************************************************************
* IHXRequestHandler::GetRequest
*
* This routine retrieves the Request object associated with this File
* Object. It is called just after the SetRequest() method.
*/
STDMETHODIMP
CHXHTTPFileObject::GetRequest(REF(IHXRequest*) pRequest)
{
MLOG_HTTP("CHXHTTPFileObject::GetRequest()\n");
pRequest = m_pRequest;
if (pRequest != NULL)
{
pRequest->AddRef();
}
return HXR_OK;
}
// IUnknown COM Interface Methods
/****************************************************************************
* IUnknown::AddRef
*
* This routine increases the object reference count in a thread safe
* manner. The reference count is used to manage the lifetime of an object.
* This method must be explicitly called by the user whenever a new
* reference to an object is used.
*/
STDMETHODIMP_(UINT32) CHXHTTPFileObject::AddRef(void)
{
MLOG_HTTP("CHXHTTPFileObject::AddRef()\n");
return InterlockedIncrement(&m_RefCount);
}
/****************************************************************************
* IUnknown::Release
*
* This routine decreases the object reference count in a thread safe
* manner, and deletes the object if no more references to it exist. It must
* be called explicitly by the user whenever an object is no longer needed.
*/
STDMETHODIMP_(UINT32) CHXHTTPFileObject::Release(void)
{
MLOG_HTTP("CHXHTTPFileObject::Release()\n");
if (InterlockedDecrement(&m_RefCount) > 0)
{
return m_RefCount;
}
delete this;
return 0;
}
/****************************************************************************
* IUnknown::QueryInterface
*
* This routine indicates which interfaces this object supports. If a given
* interface is supported, the object's reference count is incremented, and
* a reference to that interface is returned. Otherwise a NULL object and
* error code are returned. This method is called by other objects to
* discover the functionality of this object.
*/
STDMETHODIMP CHXHTTPFileObject::QueryInterface(REFIID interfaceID,
void** ppInterfaceObj)
{
MLOG_HTTP("CHXHTTPFileObject::QueryInterface()\n");
// Initially assume no interfaces are supported
HX_RESULT res = HXR_NOINTERFACE;
*ppInterfaceObj = NULL;
// By definition all COM objects support the IUnknown interface
if (IsEqualIID(interfaceID, IID_IUnknown))
{
*ppInterfaceObj = (IUnknown*)(IHXFileObject*)this;
}
// IHXFileObject interface is supported
else if (IsEqualIID(interfaceID, IID_IHXFileObject))
{
*ppInterfaceObj = (IHXFileObject*)this;
}
// IHXRequestHandler interface is supported
else if (IsEqualIID(interfaceID, IID_IHXRequestHandler))
{
*ppInterfaceObj = (IHXRequestHandler*)this;
}
// IHXFileStat interface is supported
else if (IsEqualIID(interfaceID, IID_IHXFileStat))
{
*ppInterfaceObj = (IHXFileStat*)this;
}
// IHXCacheObjectResponse interface is supported
else if(IsEqualIID(interfaceID, IID_IHXCacheObjectResponse))
{
*ppInterfaceObj = (IHXCacheObjectResponse*)this;
}
// IHXTCPResponse interface is supported
else if (IsEqualIID(interfaceID, IID_IHXTCPResponse))
{
*ppInterfaceObj = (IHXTCPResponse*)this;
}
// IHXCallback interface is supported
else if (IsEqualIID(interfaceID, IID_IHXCallback))
{
*ppInterfaceObj = (IHXCallback*)this;
}
if (*ppInterfaceObj)
{
AddRef();
res = HXR_OK;
}
return res;
}
/************************************************************************
* Method:
* IHXFileStat::Stat
* Purpose:
* Collects information about the file that is returned to the
* caller in an IHXStat object
*/
STDMETHODIMP
CHXHTTPFileObject::Stat(IHXFileStatResponse* pFileStatResponse)
{
MLOG_HTTP("CHXHTTPFileObject::Stat()\n");
if(pFileStatResponse == NULL)
{
return HXR_INVALID_PARAMETER;
}
// It shouldn't call this function before it gets a InitDone() (by which time
// header would have been completely read).
// >>> Later, give proper values for last four parameters too...
if(m_ulFileLength > 0)
{
pFileStatResponse->StatDone(HXR_OK, m_ulFileLength, 0, 0, 0, HX_S_IFREG);
}
else
{
return HXR_FAIL;
}
return HXR_OK;
}
/*
* IHXCacheObjectResponse methods
*/
/************************************************************************
* Method:
*
* IHXCacheObjectResponse::InitDone
*
* Purpose:
*
* Notification that IHXCacheObject::Init call has completed.
*/
STDMETHODIMP
CHXHTTPFileObject::InitDone(HX_RESULT /*IN*/ status)
{
MLOG_HTTP("CHXHTTPFileObject::InitDone(%s)\n", StrRep(status));
return HXR_OK;
} // InitDone()
/************************************************************************
* Method:
*
* IHXCacheObjectResponse::ChangeCapacityDone
*
* Purpose:
*
* Notification that IHXCacheObject::ChangeCapacity call has completed.
*/
STDMETHODIMP
CHXHTTPFileObject::ChangeCapacityDone(HX_RESULT /*IN*/ status)
{
MLOG_HTTP("CHXHTTPFileObject::ChangeCapacityDone(%s)\n", StrRep(status));
return HXR_NOTIMPL;
} // ChangeCapacityDone()
/************************************************************************
* Method:
*
* IHXCacheObjectResponse::AddBlockDone
*
* Purpose:
*
* Notification that IHXCacheObject::AddBlock operation has completed.
*/
STDMETHODIMP
CHXHTTPFileObject::AddBlockDone(HX_RESULT /*IN*/ status)
{
MLOG_HTTP("CHXHTTPFileObject::AddBlockDone(%s)\n", StrRep(status));
// Can the Cache accomodate more data that might arrive
// should we request the network for some.
UINT32 uReadSize = m_ulFileLength - m_ulFileDataRead;
if(uReadSize > CHUNK_SIZE)
uReadSize = CHUNK_SIZE;
if(status == HXR_OUTOFMEMORY)
{
// Try to add this block again when you read
// something of the cache (i.e., in ReadBlockDone()
m_bAddBlockPending = TRUE;
}
else
{
HX_RELEASE(m_pPendingAddBlock);
// Ask the network services to get more data.
m_pSocket->Read((UINT16)uReadSize);
}
return HXR_OK;
} // AddBlockDone()
/************************************************************************
* Method:
*
* IHXCacheObjectResponse::VerifyBlockDone
*
* Purpose:
*
* Notification that IHXCacheObject::VerifyBlock operation has
* completed.
*/
STDMETHODIMP
CHXHTTPFileObject::VerifyBlockDone(BOOL /*IN*/ bExist)
{
MLOG_HTTP("CHXHTTPFileObject::VerifyBlockDone(%d)\n", bExist);
return HXR_NOTIMPL;
} // VerifyBlockDone()
/************************************************************************
* Method:
*
* IHXCacheObjectResponse::ReadBlockDone
*
* Purpose:
*
* Notification that IHXCacheObject::ReadBlock operation has
* completed.
*/
STDMETHODIMP
CHXHTTPFileObject::ReadBlockDone(HX_RESULT /*IN*/ status,
IHXBuffer* /*IN*/ pBuffer)
{
MLOG_HTTP("CHXHTTPFileObject::ReadBlockDone(%s)\n", StrRep(status));
// If the cache has failed to give us anydata and it will not do
// so in the future and at the same time we notice that the server
// has disconnected, then raise alarm. Note that we need to check
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -