obexstream.cpp
来自「Windows CE 6.0 Server 源码」· C++ 代码 · 共 1,418 行 · 第 1/4 页
CPP
1,418 行
goto Done;
}
if (uiTotalSize > uiMaxPacket)
{
SVSUTIL_ASSERT(uiMaxPacket >= (uiBodyLen + 3 + uiPacketSize));
toWrite = uiMaxPacket - uiBodyLen - 3 - uiPacketSize;
}
else
{
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- oooh. packet fits nicely. we can cache it away for later. -- will be caching: %d bytes", toWrite + uiBodyLen));
}
//
// fill pcBodyChunk with data
//
if (pcBodyChunk && toWrite)
{
//since we have old cached data, put that in first, then as much of
// the new data as possible
BYTE *pcNewChunk = new BYTE [uiBodyLen + toWrite];
if (pcNewChunk)
memcpy (pcNewChunk, pcBodyPtr, uiBodyLen);
else
{
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- out of memory\n"));
hr = E_OUTOFMEMORY;
goto Done;
}
delete [] pcBodyChunk;
pcBodyChunk = pcBodyPtr = pcNewChunk;
//copy in new data
memcpy(pcBodyChunk + uiBodyLen, pv, toWrite);
uiBodyLen += toWrite;
}
else if(toWrite)
{
//if nothing is cached, simply
SVSUTIL_ASSERT (uiBodyLen == 0);
pcBodyChunk = new BYTE[toWrite];
pcBodyPtr = pcBodyChunk;
if (! pcBodyChunk)
{
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- out of memory\n"));
hr = E_OUTOFMEMORY;
goto Done;
}
//copy in new data
memcpy(pcBodyChunk + uiBodyLen, pv, toWrite);
uiBodyLen = toWrite;
}
unsigned char *pNewPacket;
ULONG uiIPackSize;
//the size is already accounted for
myHeaderCollection->AddBody(uiBodyLen, pcBodyChunk);
delete [] pcBodyChunk;
uiBodyLen = 0;
pcBodyChunk = pcBodyPtr = NULL;
//add (if any) connection ID
if(uiConnectionId != OBEX_INVALID_CONNECTION)
myHeaderCollection->AddConnectionId(uiConnectionId);
//send off the packet
if(SUCCEEDED(hr = ObexSendRecvWithAuthSaveHeaders(pConnection, uiMaxPacket, wcPassword, cOpCode, 0,0, myHeaderCollection, &pNewPacket, &uiIPackSize)))
{
//parse out all interesting fields
ObexParser p (pNewPacket, uiIPackSize);
//get the command data
if (p.Op() != 0x90 && p.Op() != 0xA0)
hr = E_FAIL;
else
hr = S_OK;
//cleanup & init everything to be ready for a new packet
delete [] pNewPacket;
myHeaderCollection->Release();
myHeaderCollection = new CHeaderCollection();
if( !myHeaderCollection )
{
hr = E_OUTOFMEMORY;
goto Done;
}
if(SUCCEEDED(hr))
{
*pcbWritten = toWrite;
goto Done;
}
else
{
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- INVALID OP CODE (not continue or okay)!\n"));
goto Done;
}
}
else
{
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"CObexStream::WriteAll() -- ObexSendRecv FAILED!\n"));
hr = E_FAIL;
goto Done;
}
Done:
return hr;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Seek(LARGE_INTEGER dlibMove, //Offset relative to dwOrigin
DWORD dwOrigin, //Specifies the origin for the offset
ULARGE_INTEGER *plibNewPosition //Pointer to location containing
// new seek pointer
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::SetSize(ULARGE_INTEGER libNewSize //Specifies the new size of the stream object
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::CopyTo(
IStream *pstm, //Pointer to the destination stream
ULARGE_INTEGER cb, //Specifies the number of bytes to copy
ULARGE_INTEGER *pcbRead, //Pointer to the actual number of bytes
// read from the source
ULARGE_INTEGER *pcbWritten //Pointer to the actual number of
// bytes written to the destination
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Commit(DWORD grfCommitFlags)
{
HRESULT hr = S_OK;
//
// If the stream is still active and is a PUT, flush it out
// this will allow the client application to read errors
// then render the stream worthless (at this point the END_BODY has
// been sent)... NOTE: since only one packet can possibly be put into
// queues we dont need to loop
if(uiStreamType == OBEX_PUT && !StreamDisabled()) {
hr = FlushSendBuffers(OBEX_OP_PUT);
uiStreamType = OBEX_ERR;
ASSERT(0 == uiBodyLen);
ASSERT(NULL == pcBodyChunk);
ASSERT(NULL == pcBodyPtr);
}
return hr;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Revert(void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::LockRegion(ULARGE_INTEGER libOffset, //Specifies the byte offset for
// the beginning of the range
ULARGE_INTEGER cb, //Specifies the length of the range in bytes
DWORD dwLockType //Specifies the restriction on
// accessing the specified range
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::UnlockRegion(ULARGE_INTEGER libOffset, //Specifies the byte offset for
// the beginning of the range
ULARGE_INTEGER cb, //Specifies the length of the range in bytes
DWORD dwLockType //Specifies the access restriction
// previously placed on the range
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Stat(STATSTG *pstatstg, //Location for STATSTG structure
DWORD grfStatFlag //Values taken from the STATFLAG enumeration
)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Clone(IStream **ppstm //Pointer to location for pointer to the new stream object
)
{
return E_NOTIMPL;
}
//
// IObexResponse Interface
//
HRESULT STDMETHODCALLTYPE
CObexStream::GetLastResponseCode(BYTE *pResponseCode)
{
// We haven't performed first req<->resp yet, so no data to send.
if (! fHaveSentData)
return E_FAIL;
*pResponseCode = bLastResponseCode;
return S_OK;
}
//
// IHeaderEnum Interface
//
// First time this is called, if raw Obex headers are available (in pResponseHeaders)
// then fill out pResponseHeadEnum with appropriate header data
HRESULT CObexStream::SetupHeaderEnum(void) {
// We've already performed the parsing operation
if (pResponseHeadEnum)
return S_OK;
if (pResponseHeaders == NULL) {
DEBUGMSG(OBEX_OBEXSTREAM_ZONE,(L"OBEX: Attempt to access response headers was made, but headers not available yet\r\n"));
return E_FAIL;
}
HRESULT hr = E_OUTOFMEMORY;
// Allocate and parse headers
pResponseHeadEnum = new CHeaderEnum;
if( !pResponseHeadEnum )
return E_OUTOFMEMORY;
ObexParser p(pResponseHeaders,uiResponseHeaderLen);
OBEX_HEADER *pNewHeader = NULL;
while (! p.__EOF ()) {
pNewHeader = new OBEX_HEADER;
if (pNewHeader == NULL)
goto done;
memset(pNewHeader,0,sizeof(*pNewHeader));
pNewHeader->bId = (BYTE)p.Code();
switch (p.Type ()) {
case OBEX_TYPE_UNICODE:
if (! p.GetString(&pNewHeader->value.pszData))
goto done;
break;
case OBEX_TYPE_BYTESEQ:
if (! p.GetBytes((void**)&pNewHeader->value.ba.pbaData))
goto done;
pNewHeader->value.ba.dwSize = p.Length();
break;
case OBEX_TYPE_BYTE:
if (! p.GetBYTE (&pNewHeader->value.bData))
goto done;
break;
case OBEX_TYPE_DWORD:
if (! p.GetDWORD (&pNewHeader->value.dwData))
goto done;
break;
default:
ASSERT(0);
hr = E_FAIL;
goto done;
}
pResponseHeadEnum->InsertBack(pNewHeader);
pNewHeader = NULL;
if (! p.Next ())
break;
}
hr = S_OK;
done:
if (FAILED(hr)) {
if (pResponseHeadEnum) {
pResponseHeadEnum->RemoveAll();
delete pResponseHeadEnum;
pResponseHeadEnum = NULL;
}
if (pNewHeader)
delete pNewHeader;
}
return hr;
}
HRESULT STDMETHODCALLTYPE
CObexStream::Next(ULONG celt, OBEX_HEADER **rgelt, ULONG *pceltFetched)
{
if (FAILED(SetupHeaderEnum()))
return E_FAIL;
return pResponseHeadEnum->Next(celt,rgelt,pceltFetched);
}
HRESULT STDMETHODCALLTYPE
CObexStream::Skip(ULONG celt)
{
if (FAILED(SetupHeaderEnum()))
return E_FAIL;
return pResponseHeadEnum->Skip(celt);
}
HRESULT STDMETHODCALLTYPE
CObexStream::Reset(void)
{
if (FAILED(SetupHeaderEnum()))
return E_FAIL;
return pResponseHeadEnum->Reset();
}
HRESULT STDMETHODCALLTYPE
CObexStream::Clone(IHeaderEnum **ppenum)
{
if (FAILED(SetupHeaderEnum()))
return E_FAIL;
return pResponseHeadEnum->Clone(ppenum);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?