1 /* $Id: jigdo-io.hh,v 1.8 2004/02/04 15:34:40 atterer Exp $ -*- C++ -*-
3 |_) /| Copyright (C) 2003 | richard@
4 | \/¯| Richard Atterer | atterer.net
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2. See
8 the file COPYING for details.
10 IO object for .jigdo downloads; download, gunzip, interpret
12 Data (=downloaded bytes, status info) flows as follows:
14 class: Download -> SingleUrl -> JigdoIO -> GtkSingleUrl
15 data member: childDl->source() this frontend
17 The JigdoIO owns the SingleUrl (and the Download *object* inside it), but
18 it doesn't own the GtkSingleUrl.
29 #include <datasource.hh>
31 #include <jigdo-io.fh>
32 #include <makeimagedl.hh>
36 //______________________________________________________________________
43 class Job::JigdoIO : NoCopy, public Job::DataSource::IO, Gunzip::IO {
46 /** The supported major version format number inside .jigdo files. E.g. "1"
47 means that this code will accept all .jigdo files whose [Jigdo]
48 sections contain "Version=" lines followed by 0.x or 1.x version
49 numbers. A hard (non-recoverable) error happens for 2.x or bigger
51 static const int SUPPORTED_FORMAT = 1;
53 /** Create a new JigdoIO which is owned by m, gets data from download (will
54 register itself with download's IOPtr) and passes it on to childIo.
55 @param c Object which owns us (it is the MakeImageDl's child, but our
57 @param download Gives the data of the .jigdo file to us
58 @param childIo Provided by the frontend, e.g. a GtkSingleUrl object */
59 JigdoIO(MakeImageDl::Child* c, const string& url,
60 DataSource::IO* frontendIo);
62 virtual Job::IO* job_removeIo(Job::IO* rmIo);
64 inline MakeImageDl* master() const;
65 inline DataSource* source() const;
68 friend struct Job::JigdoIOTest;
70 /* Create object for an [Include]d file */
71 JigdoIO(MakeImageDl::Child* c, const string& url,
72 DataSource::IO* frontendIo, JigdoIO* parentJigdo,
75 /** @return Root object of the include tree */
76 inline JigdoIO* root();
77 inline const JigdoIO* root() const;
78 /** @return true iff this object is the root of the include tree. */
79 inline bool isRoot() const;
80 /** Return the ptr to the image section candidate object; the JigdoIO which
81 might or might not contain the first [Image] section. If new data is
82 received for that object and that new data contains an [Image], we know
83 it's the first [Image]. If all data is recvd without any [Image]
84 turning up, we continue walking the include tree depth-first. */
85 inline JigdoIO* imgSectCandidate() const;
86 /** Set the ptr to the image section candidate object */
87 inline void setImgSectCandidate(JigdoIO* c);
88 // The methods below are called in various places to find 1st image section
89 inline void imgSect_newChild(JigdoIO* child); // Child created after [Incl.
90 inline void imgSect_parsed(); // [Image] occurred in current .jigdo data
91 /* End of current file without any [Image]. Returns 1 if OK and all
93 inline XStatus imgSect_eof();
95 // Create error message with URL and line number
96 void generateError(const string& msg);
97 void generateError(const char* msg);
98 // As above, but directly pass on error string, do not add URL/line
99 void generateError_plain(string* err);
100 // True after above was called
101 inline bool failed() const;
102 // Called by gunzip_data(): New .jigdo line ready. Arg is empty on exit.
103 void jigdoLine(string* l);
104 void include(string* url); // "[Include http://xxx]" found
105 void entry(string* label, string* data, unsigned valueOff);
106 /* Called at the end of a [Section] (=start of another section or EOF)
107 Returns FAILURE if there is an error. */
110 // Virtual methods from DataSource::IO
111 virtual void job_deleted();
112 virtual void job_succeeded();
113 virtual void job_failed(string* message);
114 virtual void job_message(string* message);
115 virtual void dataSource_dataSize(uint64 n);
116 virtual void dataSource_data(const byte* data, size_t size,
119 // Virtual methods from Gunzip::IO
120 virtual void gunzip_deleted();
121 virtual void gunzip_data(Gunzip*, byte* decompressed, unsigned size);
122 virtual void gunzip_needOut(Gunzip*);
123 virtual void gunzip_failed(string* message);
125 MakeImageDl::Child* childDl;
127 DataSource::IO* frontend; // Object provided by frontend for this download
129 /* Representation of the tree of [Include] directives. Most of the time,
130 the order of data in the .jigdo files is not relevant, with one
131 exception: We must interpret the first [Image] section only, and ignore
132 all following ones. */
133 JigdoIO* parent; // .jigdo file which [Include]d us, or null if top-level
134 int includeLine; // If parent!=null, line num of [Include] in parent
135 JigdoIO* firstChild; // First file we [Include], or null if none
136 JigdoIO* next; // Right sibling, or null if none
137 /* For the root object, contains imgSectCandidate, else ptr to root object.
138 Don't access directly, use accessor methods. */
139 JigdoIO* rootAndImageSectionCandidate;
141 int line; // Line number, for errors. 0 if no data yet, -1 if finished
142 bool finished() { return line < 0; }
143 void setFinished() { line = -1; }
144 string section; // Current section name, empty if none yet
146 // Info about first image section of this .jigdo, if any
147 int imageSectionLine; // 0 if no [Image] found yet
149 string imageInfo, imageShortInfo;
153 /* When an error happens inside gunzip_data(), cannot immediately tell the
154 master about it, because it would delete the DataSource => the Download
155 would be deleted from within download_data(). */
156 static gboolean childFailed_callback(gpointer data);
159 /* Transparent gunzipping of .jigdo file. GUNZIP_BUF_SIZE is also the max
160 size a single line in the .jigdo is allowed to have */
161 static const unsigned GUNZIP_BUF_SIZE = 16384;
163 byte gunzipBuf[GUNZIP_BUF_SIZE];
165 //______________________________________________________________________
167 Job::JigdoIO* Job::JigdoIO::root() {
168 if (isRoot()) return this; else return rootAndImageSectionCandidate;
170 const Job::JigdoIO* Job::JigdoIO::root() const {
171 if (isRoot()) return this; else return rootAndImageSectionCandidate;
173 bool Job::JigdoIO::isRoot() const {
177 Job::JigdoIO* Job::JigdoIO::imgSectCandidate() const {
179 return rootAndImageSectionCandidate;
181 return rootAndImageSectionCandidate->rootAndImageSectionCandidate;
183 void Job::JigdoIO::setImgSectCandidate(JigdoIO* c) {
185 rootAndImageSectionCandidate = c;
187 rootAndImageSectionCandidate->rootAndImageSectionCandidate = c;
190 Job::MakeImageDl* Job::JigdoIO::master() const { return childDl->master(); }
191 Job::DataSource* Job::JigdoIO::source() const { return childDl->source(); }
193 bool Job::JigdoIO::failed() const {
194 return (imageName.length() == 1 && imageName[0] == '\0');
195 //return (childFailedId != 0);