Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
nsMultiMixedConv Class Reference

#include <nsMultiMixedConv.h>

Inheritance diagram for nsMultiMixedConv:
Inheritance graph
[legend]
Collaboration diagram for nsMultiMixedConv:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMCONVERTER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER 
nsMultiMixedConv ()
virtual ~nsMultiMixedConv ()
nsIInputStream convert (in nsIInputStream aFromStream, in string aFromType, in string aToType, in nsISupports aCtxt)
 SYNCRONOUS VERSION Converts a stream of one type, to a stream of another type.
void asyncConvertData (in string aFromType, in string aToType, in nsIStreamListener aListener, in nsISupports aCtxt)
 ASYNCRONOUS VERSION Converts data arriving via the converter's nsIStreamListener::OnDataAvailable() method from one type to another, pushing the converted data out to the caller via aListener::OnDataAvailable().
void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext, in nsIInputStream aInputStream, in unsigned long aOffset, in unsigned long aCount)
 Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.
void onStartRequest (in nsIRequest aRequest, in nsISupports aContext)
 Called to signify the beginning of an asynchronous request.
void onStopRequest (in nsIRequest aRequest, in nsISupports aContext, in nsresult aStatusCode)
 Called to signify the end of an asynchronous request.

Protected Member Functions

nsresult SendStart (nsIChannel *aChannel)
nsresult SendStop (nsresult aStatus)
nsresult SendData (char *aBuffer, PRUint32 aLen)
nsresult ParseHeaders (nsIChannel *aChannel, char *&aPtr, PRUint32 &aLen, PRBool *_retval)
PRInt32 PushOverLine (char *&aPtr, PRUint32 &aLen)
char * FindToken (char *aCursor, PRUint32 aLen)
nsresult BufferData (char *aData, PRUint32 aLen)

Protected Attributes

PRBool mNewPart
PRBool mProcessingHeaders
nsCOMPtr< nsIStreamListenermFinalListener
nsCString mToken
PRUint32 mTokenLen
nsRefPtr< nsPartChannelmPartChannel
nsCOMPtr< nsISupports > mContext
nsCString mContentType
nsCString mContentDisposition
nsUint64 mContentLength
char * mBuffer
PRUint32 mBufLen
nsUint64 mTotalSent
PRBool mFirstOnData
nsInt64 mByteRangeStart
nsInt64 mByteRangeEnd
PRBool mIsByteRangeRequest
PRUint32 mCurrentPartID

Detailed Description

Definition at line 144 of file nsMultiMixedConv.h.


Constructor & Destructor Documentation

Definition at line 711 of file nsMultiMixedConv.cpp.

                                    {
    NS_ASSERTION(!mBuffer, "all buffered data should be gone");
    if (mBuffer) {
        free(mBuffer);
        mBuffer = nsnull;
    }
}

Member Function Documentation

void nsIStreamConverter::asyncConvertData ( in string  aFromType,
in string  aToType,
in nsIStreamListener  aListener,
in nsISupports  aCtxt 
) [inherited]

ASYNCRONOUS VERSION Converts data arriving via the converter's nsIStreamListener::OnDataAvailable() method from one type to another, pushing the converted data out to the caller via aListener::OnDataAvailable().

Use this method when you want to proxy (and convert) nsIStreamListener callbacks asynchronously.

Parameters:
aFromTypeThe MIME type of the original/raw data.
aToTypeThe MIME type of the converted data.
aListenerThe listener who receives the converted data.
aCtxtEither an opaque context, or a converter specific context (implementation specific).
nsresult nsMultiMixedConv::BufferData ( char *  aData,
PRUint32  aLen 
) [protected]

Definition at line 720 of file nsMultiMixedConv.cpp.

                                                       {
    NS_ASSERTION(!mBuffer, "trying to over-write buffer");

    char *buffer = (char *) malloc(aLen);
    if (!buffer) return NS_ERROR_OUT_OF_MEMORY;

    memcpy(buffer, aData, aLen);
    mBuffer = buffer;
    mBufLen = aLen;
    return NS_OK;
}

Here is the call graph for this function:

nsIInputStream nsIStreamConverter::convert ( in nsIInputStream  aFromStream,
in string  aFromType,
in string  aToType,
in nsISupports  aCtxt 
) [inherited]

SYNCRONOUS VERSION Converts a stream of one type, to a stream of another type.

Use this method when you have a stream you want to convert.

Parameters:
aFromStreamThe stream representing the original/raw data.
aFromTypeThe MIME type of aFromStream.
aToTypeThe MIME type of the returned stream.
aCtxtEither an opaque context, or a converter specific context (implementation specific).
Returns:
The converted stream. NOTE: The returned stream may not already be converted. An efficient stream converter implementation will converter data on demand rather than buffering the converted data until it is used.
char * nsMultiMixedConv::FindToken ( char *  aCursor,
PRUint32  aLen 
) [protected]

Definition at line 961 of file nsMultiMixedConv.cpp.

                                                        {
    // strnstr without looking for null termination
    const char *token = mToken.get();
    char *cur = aCursor;

    if (!(token && aCursor && *token)) {
        NS_WARNING("bad data");
        return nsnull;
    }

    for (; aLen >= mTokenLen; aCursor++, aLen--) {
        if (!memcmp(aCursor, token, mTokenLen) ) {
            if ((aCursor - cur) >= 2) {
                // back the cursor up over a double dash for backwards compat.
                if ((*(aCursor-1) == '-') && (*(aCursor-2) == '-')) {
                    aCursor -= 2;
                    aLen += 2;

                    // we're playing w/ double dash tokens, adjust.
                    mToken.Assign(aCursor, mTokenLen + 2);
                    mTokenLen = mToken.Length();
                }
            }
            return aCursor;
        }
    }

    return nsnull;
}

Here is the call graph for this function:

void nsIStreamListener::onDataAvailable ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsIInputStream  aInputStream,
in unsigned long  aOffset,
in unsigned long  aCount 
) [inherited]

Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.

The onDataAvailable impl must read exactly |aCount| bytes of data before returning.

Parameters:
aRequestrequest corresponding to the source of the data
aContextuser defined context
aInputStreaminput stream containing the data chunk
aOffsetNumber of bytes that were sent in previous onDataAvailable calls for this request. In other words, the sum of all previous count parameters. If that number is greater than or equal to 2^32, this parameter will be PR_UINT32_MAX (2^32 - 1).
aCountnumber of bytes available in the stream

NOTE: The aInputStream parameter must implement readSegments.

An exception thrown from onDataAvailable has the side-effect of causing the request to be canceled.

void nsIRequestObserver::onStartRequest ( in nsIRequest  aRequest,
in nsISupports  aContext 
) [inherited]

Called to signify the beginning of an asynchronous request.

Parameters:
aRequestrequest being observed
aContextuser defined context

An exception thrown from onStartRequest has the side-effect of causing the request to be canceled.

Here is the caller graph for this function:

void nsIRequestObserver::onStopRequest ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsresult  aStatusCode 
) [inherited]

Called to signify the end of an asynchronous request.

This call is always preceded by a call to onStartRequest.

Parameters:
aRequestrequest being observed
aContextuser defined context
aStatusCodereason for stopping (NS_OK if completed successfully)

An exception thrown from onStopRequest is generally ignored.

Here is the caller graph for this function:

nsresult nsMultiMixedConv::ParseHeaders ( nsIChannel aChannel,
char *&  aPtr,
PRUint32 aLen,
PRBool _retval 
) [protected]

Definition at line 856 of file nsMultiMixedConv.cpp.

                                                                {
    // NOTE: this data must be ascii.
    // NOTE: aPtr is NOT null terminated!
    nsresult rv = NS_OK;
    char *cursor = aPtr, *newLine = nsnull;
    PRUint32 cursorLen = aLen;
    PRBool done = PR_FALSE;
    PRUint32 lineFeedIncrement = 1;
    
    mContentLength = LL_MAXUINT; // XXX what if we were already called?
    while (cursorLen && (newLine = (char *) memchr(cursor, nsCRT::LF, cursorLen))) {
        // adjust for linefeeds
        if ((newLine > cursor) && (newLine[-1] == nsCRT::CR) ) { // CRLF
            lineFeedIncrement = 2;
            newLine--;
        }
        else
            lineFeedIncrement = 1; // reset

        if (newLine == cursor) {
            // move the newLine beyond the linefeed marker
            NS_ASSERTION(cursorLen >= lineFeedIncrement, "oops!");

            cursor += lineFeedIncrement;
            cursorLen -= lineFeedIncrement;

            done = PR_TRUE;
            break;
        }

        char tmpChar = *newLine;
        *newLine = '\0'; // cursor is now null terminated
        char *colon = (char *) strchr(cursor, ':');
        if (colon) {
            *colon = '\0';
            nsCAutoString headerStr(cursor);
            headerStr.CompressWhitespace();
            *colon = ':';

            nsCAutoString headerVal(colon + 1);
            headerVal.CompressWhitespace();

            // examine header
            if (headerStr.LowerCaseEqualsLiteral("content-type")) {
                mContentType = headerVal;
            } else if (headerStr.LowerCaseEqualsLiteral("content-length")) {
                mContentLength = atoi(headerVal.get()); // XXX 64-bit math?
            } else if (headerStr.LowerCaseEqualsLiteral("content-disposition")) {
                mContentDisposition = headerVal;
            } else if (headerStr.LowerCaseEqualsLiteral("set-cookie")) {
                nsCOMPtr<nsIHttpChannelInternal> httpInternal =
                    do_QueryInterface(aChannel);
                if (httpInternal) {
                    httpInternal->SetCookie(headerVal.get());
                }
            } else if (headerStr.LowerCaseEqualsLiteral("content-range") || 
                       headerStr.LowerCaseEqualsLiteral("range") ) {
                // something like: Content-range: bytes 7000-7999/8000
                char* tmpPtr;

                tmpPtr = (char *) strchr(colon + 1, '/');
                if (tmpPtr) 
                    *tmpPtr = '\0';

                // pass the bytes-unit and the SP
                char *range = (char *) strchr(colon + 2, ' ');

                if (!range)
                    return NS_ERROR_FAILURE;

                if (range[0] == '*'){
                    mByteRangeStart = mByteRangeEnd = 0;
                }
                else {
                    tmpPtr = (char *) strchr(range, '-');
                    if (!tmpPtr)
                        return NS_ERROR_FAILURE;
                    
                    tmpPtr[0] = '\0';
                    
                    mByteRangeStart = atoi(range); // XXX want 64-bit conv
                    tmpPtr++;
                    mByteRangeEnd = atoi(tmpPtr);
                }

                mIsByteRangeRequest = PR_TRUE;
                if (mContentLength == LL_MAXUINT)
                    mContentLength = PRUint64(PRInt64(mByteRangeEnd - mByteRangeStart + nsInt64(1)));
            }
        }
        *newLine = tmpChar;
        newLine += lineFeedIncrement;
        cursorLen -= (newLine - cursor);
        cursor = newLine;
    }

    aPtr = cursor;
    aLen = cursorLen;

    *_retval = done;
    return rv;
}

Here is the call graph for this function:

PRInt32 nsMultiMixedConv::PushOverLine ( char *&  aPtr,
PRUint32 aLen 
) [protected]

Definition at line 843 of file nsMultiMixedConv.cpp.

                                                          {
    PRInt32 chars = 0;
    if ((aLen > 0) && (*aPtr == nsCRT::CR || *aPtr == nsCRT::LF)) {
        if ((aLen > 1) && (aPtr[1] == nsCRT::LF))
            chars++;
        chars++;
        aPtr += chars;
        aLen -= chars;
    }
    return chars;
}
nsresult nsMultiMixedConv::SendData ( char *  aBuffer,
PRUint32  aLen 
) [protected]

Definition at line 808 of file nsMultiMixedConv.cpp.

                                                       {

    nsresult rv = NS_OK;
    
    if (!mPartChannel) return NS_ERROR_FAILURE; // something went wrong w/ processing

    if (mContentLength != LL_MAXUINT) {
        // make sure that we don't send more than the mContentLength
        // XXX why? perhaps the Content-Length header was actually wrong!!
        if ((nsUint64(aLen) + mTotalSent) > mContentLength)
            aLen = mContentLength - mTotalSent;

        if (aLen == 0)
            return NS_OK;
    }

    PRUint32 offset = mTotalSent;
    mTotalSent += aLen;

    nsCOMPtr<nsIStringInputStream> ss(
            do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
    if (NS_FAILED(rv))
        return rv;

    rv = ss->ShareData(aBuffer, aLen);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIInputStream> inStream(do_QueryInterface(ss, &rv));
    if (NS_FAILED(rv)) return rv;

    return mFinalListener->OnDataAvailable(mPartChannel, mContext, inStream, offset, aLen);
}

Here is the call graph for this function:

nsresult nsMultiMixedConv::SendStart ( nsIChannel aChannel) [protected]

Definition at line 734 of file nsMultiMixedConv.cpp.

                                                {
    nsresult rv = NS_OK;

    if (mContentType.IsEmpty())
        mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);

    // if we already have an mPartChannel, that means we never sent a Stop()
    // before starting up another "part." that would be bad.
    NS_ASSERTION(!mPartChannel, "tisk tisk, shouldn't be overwriting a channel");

    nsPartChannel *newChannel;
    newChannel = new nsPartChannel(aChannel, mCurrentPartID++);
    if (!newChannel)
        return NS_ERROR_OUT_OF_MEMORY;

    if (mIsByteRangeRequest) {
        newChannel->InitializeByteRange(mByteRangeStart, mByteRangeEnd);
    }

    mTotalSent = 0;

    // Set up the new part channel...
    mPartChannel = newChannel;

    rv = mPartChannel->SetContentType(mContentType);
    if (NS_FAILED(rv)) return rv;

    rv = mPartChannel->SetContentLength(mContentLength); // XXX Truncates 64-bit!
    if (NS_FAILED(rv)) return rv;

    rv = mPartChannel->SetContentDisposition(mContentDisposition);
    if (NS_FAILED(rv)) return rv;

    nsLoadFlags loadFlags = 0;
    mPartChannel->GetLoadFlags(&loadFlags);
    loadFlags |= nsIChannel::LOAD_REPLACE;
    mPartChannel->SetLoadFlags(loadFlags);

    nsCOMPtr<nsILoadGroup> loadGroup;
    (void)mPartChannel->GetLoadGroup(getter_AddRefs(loadGroup));

    // Add the new channel to the load group (if any)
    if (loadGroup) {
        rv = loadGroup->AddRequest(mPartChannel, nsnull);
        if (NS_FAILED(rv)) return rv;
    }

    // Let's start off the load. NOTE: we don't forward on the channel passed
    // into our OnDataAvailable() as it's the root channel for the raw stream.
    return mFinalListener->OnStartRequest(mPartChannel, mContext);
}

Here is the call graph for this function:

nsresult nsMultiMixedConv::SendStop ( nsresult  aStatus) [protected]

Definition at line 788 of file nsMultiMixedConv.cpp.

                                           {
    
    nsresult rv = NS_OK;
    if (mPartChannel) {
        rv = mFinalListener->OnStopRequest(mPartChannel, mContext, aStatus);
        // don't check for failure here, we need to remove the channel from 
        // the loadgroup.

        // Remove the channel from its load group (if any)
        nsCOMPtr<nsILoadGroup> loadGroup;
        (void) mPartChannel->GetLoadGroup(getter_AddRefs(loadGroup));
        if (loadGroup) 
            (void) loadGroup->RemoveRequest(mPartChannel, mContext, aStatus);
    }

    mPartChannel = 0;
    return rv;
}

Here is the call graph for this function:


Member Data Documentation

char* nsMultiMixedConv::mBuffer [protected]

Definition at line 179 of file nsMultiMixedConv.h.

Definition at line 180 of file nsMultiMixedConv.h.

Definition at line 188 of file nsMultiMixedConv.h.

Definition at line 187 of file nsMultiMixedConv.h.

Definition at line 176 of file nsMultiMixedConv.h.

Definition at line 177 of file nsMultiMixedConv.h.

Definition at line 175 of file nsMultiMixedConv.h.

nsCOMPtr<nsISupports> nsMultiMixedConv::mContext [protected]

Definition at line 174 of file nsMultiMixedConv.h.

Definition at line 191 of file nsMultiMixedConv.h.

Definition at line 167 of file nsMultiMixedConv.h.

Definition at line 182 of file nsMultiMixedConv.h.

Definition at line 189 of file nsMultiMixedConv.h.

Definition at line 165 of file nsMultiMixedConv.h.

Definition at line 172 of file nsMultiMixedConv.h.

Definition at line 166 of file nsMultiMixedConv.h.

Definition at line 169 of file nsMultiMixedConv.h.

Definition at line 170 of file nsMultiMixedConv.h.

Definition at line 181 of file nsMultiMixedConv.h.


The documentation for this class was generated from the following files: