Logo Search packages:      
Sourcecode: darkice version File versions

unsigned int Connector::transfer ( unsigned long  bytes,
unsigned int  bufSize,
unsigned int  sec,
unsigned int  usec 
) throw ( Exception ) [virtual]

Transfer a given amount of data from the Source to all the Sinks attached. If an attached Sink closes or encounteres an error during the process, it is detached and the function carries on with the rest of the Sinks. If no Sinks remain, or an error is encountered with the Source, the function returns prematurely.

Parameters:
bytes the amount of data to transfer, in bytes. If 0, transfer forever.
bufSize the size of the buffer to use for transfering. This amount of data is read from the Source and written to each Sink on each turn.
sec the number of seconds to wait for the Source to have data available in each turn, and the number of seconds to wait for the Sinks to accept data.
usec the number of micro seconds to wait for the Source to have data available in each turn, and the number of micro seconds to wait for the Sinks to accept data.
Returns:
the number of bytes read from the Source.
Exceptions:
Exception 

Reimplemented in MultiThreadedConnector.

Definition at line 256 of file Connector.cpp.

References detach(), numSinks, Reporter::reportEvent(), sinks, and source.

{
    unsigned int    u;
    unsigned long   b;

    if ( numSinks == 0 ) {
        return 0;
    }

    if ( bufSize == 0 ) {
        return 0;
    }

    unsigned char * buf = new unsigned char[bufSize];

    reportEvent( 6, "Connector :: tranfer, bytes", bytes);
    
    for ( b = 0; !bytes || b < bytes; ) {
        unsigned int    d = 0;
        unsigned int    e = 0;

        if ( source->canRead( sec, usec) ) {
            d = source->read( buf, bufSize);

            // check for EOF
            if ( d == 0 ) {
                reportEvent( 3, "Connector :: transfer, EOF");
                break;
            }

            for ( u = 0; u < numSinks; ++u ) {

                if ( sinks[u]->canWrite( sec, usec) ) {
                    try {
                        // we expect the sink to accept all data written
                        e = sinks[u]->write( buf, d);
                    } catch ( Exception     & e ) {
                        sinks[u]->close();
                        detach( sinks[u].get() );

                        reportEvent( 4,
                              "Connector :: transfer, sink removed, remaining",
                              numSinks);

                        if ( numSinks == 0 ) {
                            reportEvent( 4,
                                        "Connector :: transfer, no more sinks");
                            delete[] buf;
                            return b;
                        }
                        // with the call to detach, numSinks gets 1 lower,
                        // and the next sink comes to sinks[u]
                        --u;
                    }
                }
            }
            
            b += d;
        } else {
            reportEvent( 3, "Connector :: transfer, can't read");
            break;
        }
    }

    delete[] buf;
    return b;
}


Generated by  Doxygen 1.6.0   Back to index