Back to index

lightning-sunbird  0.9+nobinonly
Classes | Functions
nsBinaryStream.cpp File Reference
#include <string.h>
#include "nsBinaryStream.h"
#include "nsCRT.h"
#include "nsIStreamBufferAccess.h"
#include "nsMemory.h"
#include "prlong.h"
#include "nsGenericFactory.h"
#include "nsString.h"

Go to the source code of this file.

Classes

struct  ReadSegmentsClosure
struct  WriteStringClosure

Functions

static NS_METHOD ReadSegmentForwardingThunk (nsIInputStream *aStream, void *aClosure, const char *aFromSegment, PRUint32 aToOffset, PRUint32 aCount, PRUint32 *aWriteCount)
static NS_METHOD WriteSegmentToCString (nsIInputStream *aStream, void *aClosure, const char *aFromSegment, PRUint32 aToOffset, PRUint32 aCount, PRUint32 *aWriteCount)
static NS_METHOD WriteSegmentToString (nsIInputStream *aStream, void *aClosure, const char *aFromSegment, PRUint32 aToOffset, PRUint32 aCount, PRUint32 *aWriteCount)

Class Documentation

struct ReadSegmentsClosure

Definition at line 313 of file nsBinaryStream.cpp.

Collaboration diagram for ReadSegmentsClosure:
Class Members
void * mRealClosure
nsIInputStream * mRealInputStream
nsWriteSegmentFun mRealWriter
struct WriteStringClosure

Definition at line 483 of file nsBinaryStream.cpp.

Class Members
char mCarryoverByte
PRPackedBool mHasCarryoverByte
PRUnichar * mWriteCursor

Function Documentation

static NS_METHOD ReadSegmentForwardingThunk ( nsIInputStream aStream,
void aClosure,
const char *  aFromSegment,
PRUint32  aToOffset,
PRUint32  aCount,
PRUint32 aWriteCount 
) [static]

Definition at line 321 of file nsBinaryStream.cpp.

{
    ReadSegmentsClosure* thunkClosure =
        NS_REINTERPRET_CAST(ReadSegmentsClosure*, aClosure);

    return thunkClosure->mRealWriter(thunkClosure->mRealInputStream,
                                     thunkClosure->mRealClosure,
                                     aFromSegment, aToOffset,
                                     aCount, aWriteCount);
}
static NS_METHOD WriteSegmentToCString ( nsIInputStream aStream,
void aClosure,
const char *  aFromSegment,
PRUint32  aToOffset,
PRUint32  aCount,
PRUint32 aWriteCount 
) [static]

Definition at line 445 of file nsBinaryStream.cpp.

{
    nsACString* outString = NS_STATIC_CAST(nsACString*,aClosure);

    outString->Append(aFromSegment, aCount);

    *aWriteCount = aCount;
    
    return NS_OK;
}
static NS_METHOD WriteSegmentToString ( nsIInputStream aStream,
void aClosure,
const char *  aFromSegment,
PRUint32  aToOffset,
PRUint32  aCount,
PRUint32 aWriteCount 
) [static]

Definition at line 506 of file nsBinaryStream.cpp.

{
    NS_PRECONDITION(aCount > 0, "Why are we being told to write 0 bytes?");
    NS_PRECONDITION(sizeof(PRUnichar) == 2, "We can't handle other sizes!");

    WriteStringClosure* closure = NS_STATIC_CAST(WriteStringClosure*,aClosure);
    PRUnichar *cursor = closure->mWriteCursor;

    // we're always going to consume the whole buffer no matter what
    // happens, so take care of that right now.. that allows us to
    // tweak aCount later. Do NOT move this!
    *aWriteCount = aCount;

    // if the last Write had an odd-number of bytes read, then 
    if (closure->mHasCarryoverByte) {
        // re-create the two-byte sequence we want to work with
        char bytes[2] = { closure->mCarryoverByte, *aFromSegment };
        *cursor = *(PRUnichar*)bytes;
        // Now the little endianness dance
#ifdef IS_LITTLE_ENDIAN
        *cursor = (PRUnichar) NS_SWAP16(*cursor);
#endif
        ++cursor;
        
        // now skip past the first byte of the buffer.. code from here
        // can assume normal operations, but should not assume aCount
        // is relative to the ORIGINAL buffer
        ++aFromSegment;
        --aCount;

        closure->mHasCarryoverByte = PR_FALSE;
    }
    
    // this array is possibly unaligned... be careful how we access it!
    const PRUnichar *unicodeSegment =
        NS_REINTERPRET_CAST(const PRUnichar*, aFromSegment);

    // calculate number of full characters in segment (aCount could be odd!)
    PRUint32 segmentLength = aCount / sizeof(PRUnichar);

    // copy all data into our aligned buffer.  byte swap if necessary.
    memcpy(cursor, unicodeSegment, segmentLength * sizeof(PRUnichar));
    PRUnichar *end = cursor + segmentLength;
#ifdef IS_LITTLE_ENDIAN
    for (; cursor < end; ++cursor)
        *cursor = (PRUnichar) NS_SWAP16(*cursor);
#endif
    closure->mWriteCursor = end;

    // remember this is the modifed aCount and aFromSegment,
    // so that will take into account the fact that we might have
    // skipped the first byte in the buffer
    if (aCount % sizeof(PRUnichar) != 0) {
        // we must have had a carryover byte, that we'll need the next
        // time around
        closure->mCarryoverByte = aFromSegment[aCount - 1];
        closure->mHasCarryoverByte = PR_TRUE;
    }
    
    return NS_OK;
}

Here is the call graph for this function: