Logo Search packages:      
Sourcecode: jigdo version File versions

void SingleUrl::download_data ( const byte *  data,
unsigned  size,
uint64  currentSize 
) [private, virtual]

Called during download whenever data arrives, with the data that just arrived. You can write the data to a file, copy it away etc. currentSize is the offset into the downloaded data (including the "size" new bytes) - useful for "x% done" messages.

Implements Download::Output.

Definition at line 159 of file single-url.cc.

References destStream(), Download::pausedSoon(), resuming(), and writeToDestStream().

                                                  {
# if DEBUG
  Paranoid(resuming() || progressVal.currentSize() == currentSize - size);
  //g_usleep(10000);
  string s;
  unsigned limit = (size < 65 ? size : 65);
  for (unsigned i = 0; i < limit; ++i)
    if (data[i] >= 32 && data[i] < 127) s += data[i]; else s += '.';
  debug("%5 Got %1 currentSize=%2, realoffset=%3: %4",
        size, progressVal.currentSize(), currentSize - size, s, this);
# endif

  if (!progressVal.autoTick() // <-- extra check for efficiency only
      && !download.pausedSoon())
    progressVal.setAutoTick(true);

  if (!resuming()) {
    // Normal case: Just write it to file and forward it downstream
    progressVal.setCurrentSize(currentSize);
    if (writeToDestStream(destOff + currentSize - size, data, size)
        == FAILURE) return;
    if (io) io->dataSource_data(data, size, currentSize);
    return;
  }
  //____________________

  /* We're in the middle of a resume - compare downloaded bytes with bytes
     from destStream, don't pass them on. Note that progressVal.currentSize()
     is "stuck" at the value currentSize+resumeLeft, i.e. the offset of the
     end of the overlap area. */
  debug("RESUME left=%1 off=%2 fileoff=%3", resumeLeft,
        destOff + currentSize - size, destOff + currentSize - size);

  // Read from file
  unsigned toRead = min(resumeLeft, size);
  byte buf[toRead];
  byte* bufEnd = buf + toRead;
  byte* b = buf;
  destStream()->seekg(destOff + currentSize - size, ios::beg);
  while (*destStream() && toRead > 0) {
    readBytes(*destStream(), b, toRead);
    size_t n = destStream()->gcount();
    //debug("during resume: read %1", n);
    b += n;
    toRead -= n;
  }
  if (toRead > 0 && !*destStream()) {
    debug("  Error toRead=%1 `%L2'", toRead, strerror(errno));
    resumeFailed(); return;
  }

  // Compare
  b = buf;
  while (size > 0 && b < bufEnd) {
    if (*data != *b) {
      resumeFailed();
      debug("  fromfile=%1 fromnet=%2", int(*b), int(*data));
      return;
    }
    ++data; ++b; --size; --resumeLeft;
  }

  string info = subst(_("Resuming... %1kB"), resumeLeft / 1024);
  if (io) io->job_message(&info);

  if (resumeLeft > 0) return;

  /* Success: End of buf reached and all bytes matched. Pass remaining bytes
     from this chunk to IO. */
  progressVal.reset();
  if (size > 0) {
    debug("  End, currentSize now %1", currentSize);
    progressVal.setCurrentSize(currentSize);
    if (writeToDestStream(destOff + currentSize - size, data, size)
        == FAILURE) return;
    if (io) io->dataSource_data(data, size, currentSize);
  }
}


Generated by  Doxygen 1.6.0   Back to index