Logo Search packages:      
Sourcecode: darkice version File versions

unsigned int BufferedSink::write ( const void *  buf,
unsigned int  len 
) throw ( Exception ) [virtual]

Write data to the BufferedSink. Always reads the maximum number of chunkSize chunks buf holds. If the data can not be written to the underlying stream, it is buffered. If the buffer overflows, the oldest data is discarded.

Parameters:
buf the data to write.
len number of bytes to write from buf.
Returns:
the number of bytes written (may be less than len).
Exceptions:
Exception 

Implements Sink.

Definition at line 257 of file BufferedSink.cpp.

References align(), buffer, bufferEnd, canWrite(), chunkSize, inp, isOpen(), misalignment, outp, sink, slidePointer(), and store().

Referenced by flush().

{
    unsigned int    length;
    unsigned int    soFar;
    unsigned char * b = (unsigned char *) buf;

    if ( !buf ) {
        throw Exception( __FILE__, __LINE__, "buf is null");
    }

    if ( !isOpen() ) {
        return 0;
    }

    if ( !align() ) {
        return 0;
    }

    // make it a multiple of chunkSize
    len -= len % chunkSize;

    // try to write data from the buffer first, if any
    if ( inp != outp ) {
        unsigned int    size  = 0;
        unsigned int    total = 0;

        if ( outp > inp ) {
            // valuable data is between outp -> bufferEnd and buffer -> inp
            // try to write the outp -> bufferEnd
            // the rest will be written in the next if

            size    = bufferEnd - outp - 1;
            size   -= size % chunkSize;
            soFar   = 0;

            while ( outp > inp && soFar < size && sink->canWrite( 0, 0) ) {
                length  = sink->write( outp + soFar, size - soFar);
                outp    = slidePointer( outp, length);
                soFar  += length;
            }

            total += soFar;
        }

        if ( outp < inp ) {
            // valuable data is between outp and inp
            // in the previous if wrote all data from the end
            // this part will write the rest

            size    = inp - outp;
            soFar   = 0;

            while ( soFar < size && sink->canWrite( 0, 0) ) {
                length  = sink->write( outp + soFar, size - soFar);
                outp    = slidePointer( outp, length);
                soFar  += length;
            }

            total += soFar;
        }

        while ( (outp - buffer) % chunkSize ) {
            slidePointer( outp, 1);
        }

        // calulate the misalignment to chunkSize boundaries
        misalignment = (chunkSize - (total % chunkSize)) % chunkSize;
    }

    if ( !align() ) {
        return 0;
    }

    // the internal buffer is empty, try to write the fresh data
    soFar = 0;
    if ( inp != outp ) {
        while ( soFar < len && sink->canWrite( 0, 0) ) {
            soFar += sink->write( b + soFar, len - soFar);
        }
    }
    length = soFar;

    // calulate the misalignment to chunkSize boundaries
    misalignment = (chunkSize - (length % chunkSize)) % chunkSize;

    if ( length < len ) {
        // if not all fresh could be written, store the remains

        store( b + length, len - length);
    }

    // tell them we ate everything up to chunkSize alignment
    return len;
}


Generated by  Doxygen 1.6.0   Back to index