예제 #1
0
int bbcp_File::Read_Vector(bbcp_BuffPool *iBP, bbcp_BuffPool *oBP, int vNum)
{
    bbcp_Buffer *ioBuff[IOV_MAX];
    struct iovec ioVec [IOV_MAX];
    ssize_t blen, rlen;
    int rdsz = iBP->DataSize(), numV = (vNum > IOV_MAX ? IOV_MAX : vNum);
    int i, ivN, eof = 0;

// Initialize transfer rate limiting if so desired
//
   if (bbcp_Config.Xrate) Read_Wait(rdsz*numV);

// Simply read one buffer at a time, that's the fastest way to do this
//
// cerr <<"VECTOR READ SIZE=" <<rdsz <<" v=" <<numV <<endl;
   while(!eof)
      {
      // Obtain buffers
      //
         for (ivN = 0; ivN < numV && bytesLeft > 0; ivN++)
             {if (!(ioBuff[ivN] = iBP->getEmptyBuff())) return -ENOBUFS;
              ioVec[ivN].iov_base = (caddr_t)(ioBuff[ivN]->data);
              ioVec[ivN].iov_len  = (rdsz < bytesLeft ? rdsz : bytesLeft);
              bytesLeft -= rdsz;
             }

      // Read data into the buffer
      //
         if ((rlen = IOB->Read((const struct iovec *)&ioVec, ivN)) <= 0)
            {for (i = 0; i < ivN; i++) iBP->putEmptyBuff(ioBuff[i]);
             eof = !rlen; break;
            }

      // Queue a filled buffers for further processing
      //
         for (i = 0; i < ivN && rlen; i++)
             {blen = (rlen >= rdsz ? rdsz : rlen);
              ioBuff[i]->boff = nextoffset; nextoffset += blen;
              ioBuff[i]->blen = blen;       rlen       -= blen;
              oBP->putFullBuff(ioBuff[i]);
             }

      // Return any empty buffers
      //
         eof = i < ivN || bytesLeft <= 0;
         while(i < ivN) iBP->putEmptyBuff(ioBuff[i++]);

      // Limit Transfer rate if need be
      //
         if (PaceTime && !eof) Read_Wait();
      }

// All done
//
   if (!eof) return (rlen ? static_cast<int>(rlen) : -ENODATA);
   return 0;
}
예제 #2
0
int bbcp_File::Read_Normal(bbcp_BuffPool* iBP, bbcp_BuffPool* oBP)
{
    bbcp_Buffer* bP;
    ssize_t rlen;
    int rdsz = iBP->DataSize();

// Initialize transfer rate limiting if so desired
//
    if (bbcp_Config.Xrate)
        Read_Wait(rdsz);

// Simply read one buffer at a time, that's the fastest way to do this
//
// cerr <<"NORMAL READ SIZE=" <<rdsz <<endl;
    do
    {
        // Do real-time copy if need be
        //
        if (rtCopy && (bytesLeft = bbcp_RTCopy.Prep(nextoffset, rdsz, rlen)) <= 0)
            break;

        // Obtain buffer
        //
        if (!(bP = iBP->getEmptyBuff()))
            return -ENOBUFS;

        // Read data into the buffer
        //
        if ((rlen = IOB->Read(bP->data, rdsz)) <= 0)
        {
            iBP->putEmptyBuff(bP);
            break;
        }

        // Queue a filled buffer for further processing
        //
        bytesLeft -= rlen;
        bP->boff = nextoffset;
        nextoffset += rlen;
        bP->blen = rlen;
        oBP->putFullBuff(bP);

        // Limit Transfer rate if need be
        //
        if (PaceTime && rlen == rdsz && bytesLeft > 0)
            Read_Wait();

    } while (rlen == rdsz && bytesLeft > 0);

// All done
//
    if (bytesLeft)
        return (rlen ? static_cast<int>(rlen) : -ENODATA);
    return 0;
}
예제 #3
0
int bbcp_File::Read_Direct(bbcp_BuffPool *iBP, bbcp_BuffPool *oBP)
{
    bbcp_Buffer  *bP;
    ssize_t rlen;
    int Trunc = 0, rdsz = iBP->DataSize();

// Initialize transfer rate limiting if so desired
//
   if (bbcp_Config.Xrate) Read_Wait(rdsz);

// Simply read one buffer at a time, that's the fastest way to do this
//
// cerr <<"DIRECT READ SIZE=" <<rdsz <<endl;
   while(bytesLeft > 0)
      {
      // Obtain buffer
      //
         if (!(bP = iBP->getEmptyBuff())) return -ENOBUFS;

      // Check if we are reading the last segment. Inflate it to the block
      // size value (we have room in the buffer) and indicate trunc() needed.
      // Otherwise, do a normal full-sized read.
      //
         if (bytesLeft < rdsz)
            {rdsz = bytesLeft + (blockSize - 1) & ~(blockSize - 1);
             if ((rlen = IOB->Read(bP->data, rdsz)) < bytesLeft)
                {iBP->putEmptyBuff(bP); break;}
             Trunc = 1; rlen = bytesLeft;
            } else {
             if ((rlen = IOB->Read(bP->data, rdsz)) <= 0)
                {iBP->putEmptyBuff(bP); break;}
            }

      // Queue a filled buffer for further processing
      //
         bytesLeft -= rlen;
         bP->boff   = nextoffset; nextoffset += rlen;
         bP->blen   = rlen;
         oBP->putFullBuff(bP);

      // Limit Transfer rate if need be
      //
         if (PaceTime && bytesLeft > 0) Read_Wait();
      }
  
// All done
//
   if (bytesLeft) return (rlen ? static_cast<int>(rlen) : -ENODATA);
   return 0;
}
예제 #4
0
int bbcp_File::Read_Pipe(bbcp_BuffPool* iBP, bbcp_BuffPool* oBP)
{
    bbcp_Buffer* bP;
    ssize_t rlen;
    int rdsz = iBP->DataSize();

// Initialize transfer rate limiting if so desired
//
    if (bbcp_Config.Xrate)
        Read_Wait(rdsz);

// Simply read one buffer at a time, that's the fastest way to do this
//
// cerr <<"PIPE   READ SIZE=" <<rdsz <<endl;
    do
    {
        // Obtain buffer
        //
        if (!(bP = iBP->getEmptyBuff()))
            return -ENOBUFS;

        // Read data into the buffer
        //
        if ((rlen = IOB->Read(bP->data, rdsz)) <= 0)
        {
            iBP->putEmptyBuff(bP);
            break;
        }

        // Queue a filled buffer for further processing
        //
        bP->boff = nextoffset;
        nextoffset += rlen;
        bP->blen = rlen;
        oBP->putFullBuff(bP);

        // Limit Transfer rate if need be
        //
        if (PaceTime && rlen == rdsz)
            Read_Wait();
    } while (rlen == rdsz);

// All done
//
    return 0;
}