Logo Search packages:      
Sourcecode: jigdo version File versions

jigdodownload.cc

/* $Id: jigdodownload.cc,v 1.8 2004/01/12 14:59:55 atterer Exp $ -*- C++ -*-
  __   _
  |_) /|  Copyright (C) 2003  |  richard@
  | \/|  Richard Atterer     |  atterer.net
   '` 
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License, version 2. See
  the file COPYING for details.

  JigdoDownload is a private nested class of MakeImageDl.

  Download .jigdo file. If the data that is fetched from the primary .jigdo
  URL contains [Include] directives, additional JigdoDownloads will be
  started for each one.

*/

#include <config.h>

#include <iostream>

#include <jigdodownload.hh>
#include <log.hh>

using namespace Job;
//______________________________________________________________________

DEBUG_UNIT("jigdodownload")

00030 MakeImageDl::JigdoDownload::JigdoDownload(MakeImageDl* m, JigdoDownload* p,
                                          const string& jigdoUrl,
                                          ConfigFile::iterator destPos)
    : SingleUrl(this, jigdoUrl), master(m), parent(p), ioVal(0),
      gunzipBuf(), gunzip(this), insertPos(destPos) {
  ioVal.set(master->io->makeImageDl_new(this));
}

MakeImageDl::JigdoDownload::~JigdoDownload() {
  master->io->makeImageDl_finished(this);
  if (master->jigdo == this) master->jigdo = 0;
  SingleUrl::io().set(0);
}

00044 void MakeImageDl::JigdoDownload::run() {
  SingleUrl::run(0, 0, 0, 0, false);
}
//______________________________________________________________________

00049 IOPtr<DataSource::IO>& MakeImageDl::JigdoDownload::io() {
  return ioVal;
}

const IOPtr<DataSource::IO>& MakeImageDl::JigdoDownload::io() const {
  return ioVal;
}
//______________________________________________________________________

00058 void MakeImageDl::JigdoDownload::job_deleted() {
  if (ioVal) ioVal->job_deleted();
}

00062 void MakeImageDl::JigdoDownload::job_succeeded() {
  if (ioVal) ioVal->job_succeeded();
  Assert(master->state() == DOWNLOADING_JIGDO);
  master->stateVal = DOWNLOADING_TEMPLATE;
  delete this;
}
00068 void MakeImageDl::JigdoDownload::job_failed(string* message) {
  if (ioVal) ioVal->job_failed(message);
}
00071 void MakeImageDl::JigdoDownload::job_message(string* message) {
  if (ioVal) ioVal->job_message(message);
}
00074 void MakeImageDl::JigdoDownload::dataSource_dataSize(uint64 n) {
  if (ioVal) ioVal->dataSource_dataSize(n);
}
00077 void MakeImageDl::JigdoDownload::dataSource_data(const byte* data,
                                                size_t size,
                                                uint64 currentSize) {
  if (master->state() == ERROR) return;
  Assert(master->state() == DOWNLOADING_JIGDO);
  debug("Got %1 bytes", size);
  try {
    gunzip.inject(data, size);
  } catch (Error e) {
    master->io->job_failed(&e.message);
    master->stateVal = ERROR;
    return;
  }
  if (ioVal) ioVal->dataSource_data(data, size, currentSize);
}
//______________________________________________________________________

00094 void MakeImageDl::JigdoDownload::gunzip_deleted() { }

00096 void MakeImageDl::JigdoDownload::gunzip_needOut(Gunzip*) {
  /* This is only called once, at the very start - afterwards, we always call
     setOut() from gunzip_data, so Gunzip won't call this. */
  gunzip.setOut(gunzipBuf, GUNZIP_BUF_SIZE);
}

/* Uncompressed data arrives. "decompressed" points somewhere inside
   gunzipBuf. Split data apart at \n and add lines to the ConfigFile, then
   copy any remaining unfinished line to the start of gunzipBuf. The first
   byte of gunzipBuf (if it contains valid data) is always the first char of
   a line in the config file. */
00107 void MakeImageDl::JigdoDownload::gunzip_data(Gunzip*, byte* decompressed, unsigned size) {
//   // If an error happened earlier, ignore this call to gunzip_data()
//   if (gunzipBuf == 0) return;

  // Look for end of line.
  byte* p = decompressed;
  const byte* end = decompressed + size;
  const byte* stringStart = gunzipBuf;
  string line;

  while (p < end) {
    if (*p == '\n') {
      // Add new line to ConfigFile
      Paranoid(static_cast<unsigned>(p - stringStart) <= GUNZIP_BUF_SIZE);
      Paranoid(line.empty());
      const char* lineChars = reinterpret_cast<const char*>(stringStart);
      if (g_utf8_validate(lineChars, p - stringStart, NULL) != TRUE)
        throw Error(_("Input .jigdo data is not valid UTF-8"));
      line.append(lineChars, p - stringStart);
      debug("jigdo line: `%1'", line);
      configFile().push_back();
      swap(configFile().back(), line);
      ++p;
      stringStart = p;
      continue;
    }
    if (*p == '\r')
      *p = ' '; // Allow Windows-style line endings by turning CR into space
    else if (*p == 127 || (*p < 32 && *p != '\t')) // Check for evil chars
     throw Error(_("Input .jigdo data contains invalid control characters"));
    ++p;
  }

  if (stringStart == gunzipBuf && p == stringStart + GUNZIP_BUF_SIZE) {
    // A single line fills the whole buffer. Truncate it at that length.
    debug("gunzip_data: long line");
    Paranoid(line.empty());
    const char* lineChars = reinterpret_cast<const char*>(stringStart);
    if (g_utf8_validate(lineChars, p - stringStart, NULL) != TRUE)
      throw Error(_("Input .jigdo data is not valid UTF-8"));
    line.append(lineChars, p - stringStart);
    debug("jigdo line: \"%1\"", line);
    configFile().push_back();
    swap(configFile().back(), line);
    // Trick: To ignore remainder of huge line, prepend a comment char '#'
    gunzipBuf[0] = '#';
    gunzip.setOut(gunzipBuf + 1, GUNZIP_BUF_SIZE - 1);
    return;
  }

  unsigned len = p - stringStart;
  if (len > 0 && stringStart > gunzipBuf) {
    // Unprocessed data left somewhere inside the buffer - copy to buf start
    Assert(len < GUNZIP_BUF_SIZE); // Room must be left in the buffer
    memmove(gunzipBuf, stringStart, len);
  }
  gunzip.setOut(gunzipBuf + len, GUNZIP_BUF_SIZE - len);
}

00166 void MakeImageDl::JigdoDownload::gunzip_failed(string* message) {
  throw Error(*message, true);
}

Generated by  Doxygen 1.6.0   Back to index