2 * Copyright (c) 2001, Robert Collins.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* this is the parent class for all IO operations. It's flexable enough to be cover for
17 * HTTP access, local file access, and files being extracted from archives.
18 * It also encapsulates the idea of an archive, and all non-archives become the special
23 static const char *cvsid
=
29 #include "LogSingleton.h"
32 #include "io_stream.h"
33 #include "io_stream_file.h"
34 #include "io_stream_cygfile.h"
40 io_stream::factory (io_stream
* parent
)
45 * switch (magic_id(peek (parent), max_magic_length))
46 * case io_stream * foo = new tar
47 * case io_stream * foo = new bz2
50 log (LOG_TIMESTAMP
) << "io_stream::factory has been called" << endLog
;
55 io_stream::open (String
const &name
, String
const &mode
)
57 if (name
.size() < 7 ||
60 /* iterate through the known url prefix's */
61 if (!name
.casecompare ("file://", 7))
63 io_stream_file
*rv
= new io_stream_file (&name
.cstr_oneuse()[7], mode
.cstr_oneuse());
69 if (!name
.casecompare ("cygfile://", 10))
71 io_stream_cygfile
*rv
= new io_stream_cygfile (&name
.cstr_oneuse()[10], mode
.cstr_oneuse());
81 io_stream::mkpath_p (path_type_t isadir
, String
const &name
)
85 /* iterate through the known url prefix's */
86 if (!name
.casecompare ("file://", 7))
88 return mkdir_p (isadir
== PATH_TO_DIR
? 1 : 0, &name
.cstr_oneuse()[7]);
90 if (!name
.casecompare ("cygfile://", 10))
92 return cygmkdir_p (isadir
, &name
.cstr_oneuse()[10]);
97 /* remove a file or directory. */
99 io_stream::remove (String
const &name
)
103 /* iterate through the known url prefix's */
104 if (!name
.casecompare ("file://", 7))
105 return io_stream_file::remove (&name
.cstr_oneuse()[7]);
106 if (!name
.casecompare ("cygfile://", 10))
107 return io_stream_cygfile::remove (&name
.cstr_oneuse()[10]);
112 io_stream::mklink (String
const &from
, String
const &to
,
113 io_stream_link_t linktype
)
115 log (LOG_BABBLE
) << "io_stream::mklink (" << from
<< "->" << to
<< ")"
117 if (!from
.size() || !to
.size())
119 log (LOG_TIMESTAMP
) << "invalid string in from or to parameters to mklink"
123 /* iterate through the known url prefixes */
124 if (!from
.casecompare ("file://", 7))
126 /* file urls can symlink or hardlink to file url's. */
127 /* TODO: allow linking to cygfile url's */
128 if (!to
.casecompare ("file://", 7))
129 return io_stream_file::mklink (&from
.cstr_oneuse()[7], &to
.cstr_oneuse()[7], linktype
);
130 log (LOG_TIMESTAMP
) << "Attempt to link across url providers" << endLog
;
133 if (!from
.casecompare ("cygfile://", 10))
135 /* cygfile urls can symlink or hardlink to cygfile urls's. */
136 /* TODO: allow -> file urls */
137 if (!to
.casecompare ("cygfile://", 10))
138 return io_stream_cygfile::mklink (&from
.cstr_oneuse()[10], &to
.cstr_oneuse()[10], linktype
);
139 log (LOG_TIMESTAMP
) << "Attempt to link across url providers" << endLog
;
143 if (!strmcasecmp ("http://", from
, 7))
145 /* http urls can symlink to http or ftp url's */
148 log (LOG_TIMESTAMP
) << "Unsupported url providers for " << from
<< endLog
;
153 io_stream::move_copy (String
const &from
, String
const &to
)
155 /* parameters are ok - checked before calling us, and we are private */
156 io_stream
*in
= io_stream::open (to
, "wb");
157 io_stream
*out
= io_stream::open (from
, "rb");
158 if (io_stream::copy (in
, out
))
160 log (LOG_TIMESTAMP
) << "Failed copy of " << from
<< " to " << to
163 io_stream::remove (to
);
168 out->set_mtime (in->get_mtime ());
172 io_stream::remove (from
);
176 ssize_t
io_stream::copy (io_stream
* in
, io_stream
* out
)
185 while ((countin
= in
->read (buffer
, 16384)) > 0)
187 countout
= out
->write (buffer
, countin
);
188 if (countout
!= countin
)
190 log (LOG_TIMESTAMP
) << "io_stream::copy failed to write "
191 << countin
<< " bytes" << endLog
;
192 return countout
? countout
: -1;
195 // XXX FIXME: What if countin < 0? return an error
198 out->set_mtime (in->get_mtime ());
204 io_stream::move (String
const &from
, String
const &to
)
206 if (!from
.size() || !to
.size())
208 log (LOG_TIMESTAMP
) << "invalid string in from or to parameters to move"
212 /* iterate through the known url prefixes */
213 if (!from
.casecompare ("file://", 7))
215 /* TODO: allow 'move' to cygfile url's */
216 if (to
.casecompare ("file://", 7))
217 return io_stream::move_copy (from
, to
);
218 return io_stream_file::move (&from
.cstr_oneuse()[7], &to
.cstr_oneuse()[7]);
220 if (!from
.casecompare ("cygfile://", 10))
222 /* TODO: allow -> file urls */
223 if (to
.casecompare ("cygfile://", 10))
224 return io_stream::move_copy (from
, to
);
225 return io_stream_cygfile::move (&from
.cstr_oneuse()[10], &to
.cstr_oneuse()[10]);
228 if (!strmcasecmp ("http://", from
, 7))
230 /* http urls can symlink to http or ftp url's */
233 log (LOG_TIMESTAMP
) << "Unsupported url providers for " << from
<< endLog
;
238 io_stream::gets (char *buffer
, size_t length
)
242 while (count
+ 1 < length
&& read (pos
, 1) == 1)
246 if (*(pos
- 1) == '\n')
248 --pos
; /* end of line, remove from buffer */
249 if (pos
> buffer
&& *(pos
- 1) == '\r')
254 if (count
== 0 || error ())
255 /* EOF when no chars found, or an error */
262 io_stream::exists (String
const &name
)
266 /* iterate through the known url prefix's */
267 if (!name
.casecompare ("file://", 7))
268 return io_stream_file::exists (&name
.cstr_oneuse()[7]);
269 if (!name
.casecompare ("cygfile://", 10))
270 return io_stream_cygfile::exists (&name
.cstr_oneuse()[10]);
274 /* virtual members */
276 io_stream::~io_stream ()
279 log (LOG_TIMESTAMP
) << "io_stream::~io_stream: It looks like a class "
280 << "hasn't overriden the destructor!" << endLog
;