예제 #1
0
abyss_bool
ConnWriteFromFile(TConn *  const connectionP,
                  TFile *  const fileP,
                  uint64_t const start,
                  uint64_t const last,
                  void *   const buffer,
                  uint32_t const buffersize,
                  uint32_t const rate) {
    /*----------------------------------------------------------------------------
       Write the contents of the file stream *fileP, from offset 'start'
       up through 'last', to the HTTP connection *connectionP.

       Meter the reading so as not to read more than 'rate' bytes per second.

       Use the 'bufferSize' bytes at 'buffer' as an internal buffer for this.
    -----------------------------------------------------------------------------*/
    abyss_bool retval;
    uint32_t waittime;
    abyss_bool success;
    uint32_t readChunkSize;

    if (rate > 0) {
        readChunkSize = MIN(buffersize, rate);  /* One second's worth */
        waittime = (1000 * buffersize) / rate;
    } else {
        readChunkSize = buffersize;
        waittime = 0;
    }

    success = FileSeek(fileP, start, SEEK_SET);
    if (!success)
        retval = FALSE;
    else {
        uint64_t const totalBytesToRead = last - start + 1;
        uint64_t bytesread;

        bytesread = 0;  /* initial value */

        while (bytesread < totalBytesToRead) {
            uint64_t const bytesLeft = totalBytesToRead - bytesread;
            uint64_t const bytesToRead = MIN(readChunkSize, bytesLeft);

            uint64_t bytesReadThisTime;

            bytesReadThisTime = FileRead(fileP, buffer, bytesToRead);
            bytesread += bytesReadThisTime;

            if (bytesReadThisTime > 0)
                ConnWrite(connectionP, buffer, bytesReadThisTime);
            else
                break;

            if (waittime > 0)
                xmlrpc_millisecond_sleep(waittime);
        }
        retval = (bytesread >= totalBytesToRead);
    }
    return retval;
}
예제 #2
0
bool
ConnWriteFromFile(TConn *       const connectionP,
                  const TFile * const fileP,
                  uint64_t      const start,
                  uint64_t      const last,
                  void *        const buffer,
                  uint32_t      const buffersize,
                  uint32_t      const rate) {
/*----------------------------------------------------------------------------
   Write the contents of the file stream *fileP, from offset 'start'
   up through 'last', to the HTTP connection *connectionP.

   Meter the reading so as not to read more than 'rate' bytes per second.

   Use the 'bufferSize' bytes at 'buffer' as an internal buffer for this.
-----------------------------------------------------------------------------*/
    bool retval;
    uint32_t waittime;
    bool success;
    uint32_t readChunkSize;
	uint32_t ChunkSize = 4096 * 2; /* read buffer size */

    if (rate > 0) {
        readChunkSize = MIN(buffersize, rate);  /* One second's worth */
        waittime = (1000 * buffersize) / rate;
    } else {
        readChunkSize = ChunkSize;
        waittime = 0;
    }

    success = FileSeek(fileP, start, SEEK_SET);
    if (!success)
        retval = FALSE;
    else {
        uint64_t const totalBytesToRead = last - start + 1;
        uint64_t bytesread = 0;

        int32_t bytesReadThisTime = 0;
        char * chunk = (char *) buffer; /* the beginning */
        do {

			if ((bytesReadThisTime = FileRead(fileP, chunk, readChunkSize)) <= 0 )
				break;
			
			bytesread += bytesReadThisTime;
			chunk += bytesReadThisTime;

			/* fix bug in ms ie as it doesn't render text/plain properly                    */
			/* if CRLFs are split between reassembled tcp packets,                          */
			/* ie "might" undeterministically render extra empty lines                      */
			/* if it ends in CR or LF, read an extra chunk until the buffer is full         */
			/* or end of file is reached. You may still have bad luck, complaints go to MS) */

/*			if (bytesReadThisTime == readChunkSize &&  chunk - (char *) buffer + readChunkSize < buffersize) { 
 *				char * end = chunk - 1;
 *				if (*end == CR || *end == LF) {
 *					continue;
 *				}
 *			}
 */				          
            if (!bytesReadThisTime || !ConnWrite(connectionP, buffer, chunk - (char *) buffer)) {
                break;
			}

			chunk = (char *) buffer; /* a new beginning */

			if (waittime > 0)
                xmlrpc_millisecond_sleep(waittime);
			
        } while (bytesReadThisTime == readChunkSize);

        retval = (bytesread >= totalBytesToRead);
    }
    return retval;
}