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 + -
显示快捷键?