]> cygwin.com Git - cygwin-apps/setup.git/blame - io_stream.cc
2007-02-17 Brian Dessent <brian@dessent.net>
[cygwin-apps/setup.git] / io_stream.cc
CommitLineData
b24c88b3 1/*
19911586 2 * Copyright (c) 2001, 2002, Robert Collins.
b24c88b3
RC
3 *
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.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
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
19 * case.
20 */
21
22#if 0
23static const char *cvsid =
24 "\n%%% $Id$\n";
25#endif
26
bf4ffcd9 27#include "LogSingleton.h"
b24c88b3
RC
28
29#include "io_stream.h"
a3a02820 30
19911586
RC
31#include <stdexcept>
32#include "IOStreamProvider.h"
080bec6e 33#include <map>
a3a02820 34#include "String++.h"
19911586 35
6625e635
RC
36using namespace std;
37
a3a02820 38typedef map <std::string, IOStreamProvider *, casecompare_lt_op> providersType;
080bec6e 39static providersType *providers;
19911586
RC
40static size_t longestPrefix = 0;
41static int inited = 0;
42
43void
44io_stream::registerProvider (IOStreamProvider &theProvider,
a3a02820 45 const std::string& urlPrefix)
19911586
RC
46{
47 if (!inited)
48 {
080bec6e 49 providers = new providersType;
19911586
RC
50 inited = true;
51 }
52 theProvider.key = urlPrefix;
080bec6e 53 if (providers->find (urlPrefix) != providers->end())
19911586 54 throw new invalid_argument ("urlPrefix already registered!");
080bec6e 55 (*providers)[urlPrefix] = &theProvider;
19911586
RC
56 if (urlPrefix.size() > longestPrefix)
57 longestPrefix = urlPrefix.size();
58}
59
60static IOStreamProvider const *
a3a02820 61findProvider (const std::string& path)
19911586
RC
62{
63 if (path.size() < longestPrefix)
64 return NULL;
080bec6e
RC
65 for (providersType::const_iterator i = providers->begin();
66 i != providers->end(); ++i)
19911586 67 {
afa76033 68 if (!casecompare(path, i->first, i->first.size()))
080bec6e 69 return i->second;
19911586
RC
70 }
71 return NULL;
72}
b24c88b3
RC
73
74/* Static members */
75io_stream *
76io_stream::factory (io_stream * parent)
77{
78 /* something like,
79 * if !next_file_name
80 * return NULL
81 * switch (magic_id(peek (parent), max_magic_length))
82 * case io_stream * foo = new tar
83 * case io_stream * foo = new bz2
84 * return foo
85 */
bf4ffcd9 86 log (LOG_TIMESTAMP) << "io_stream::factory has been called" << endLog;
b24c88b3
RC
87 return NULL;
88}
89
3d3c6047 90#define url_scheme_not_registered(name) \
a3a02820 91 throw new invalid_argument ((std::string("URL Scheme for '")+ \
3d3c6047
IP
92 name+"' not registered!").c_str())
93
b24c88b3 94io_stream *
a3a02820 95io_stream::open (const std::string& name, const std::string& mode)
b24c88b3 96{
19911586
RC
97 IOStreamProvider const *p = findProvider (name);
98 if (!p)
3d3c6047 99 url_scheme_not_registered (name);
d2a3615c 100 io_stream *rv = p->open (&name.c_str()[p->key.size()], mode);
19911586
RC
101 if (!rv->error ())
102 return rv;
103 delete rv;
b24c88b3
RC
104 return NULL;
105}
106
107int
a3a02820 108io_stream::mkpath_p (path_type_t isadir, const std::string& name)
b24c88b3 109{
19911586
RC
110 IOStreamProvider const *p = findProvider (name);
111 if (!p)
3d3c6047 112 url_scheme_not_registered (name);
d2a3615c 113 return p->mkdir_p (isadir, &name.c_str()[p->key.size()]);
b24c88b3
RC
114}
115
116/* remove a file or directory. */
117int
a3a02820 118io_stream::remove (const std::string& name)
b24c88b3 119{
19911586
RC
120 IOStreamProvider const *p = findProvider (name);
121 if (!p)
3d3c6047 122 url_scheme_not_registered (name);
d2a3615c 123 return p->remove (&name.c_str()[p->key.size()]);
b24c88b3
RC
124}
125
126int
a3a02820 127io_stream::mklink (const std::string& from, const std::string& to,
b24c88b3
RC
128 io_stream_link_t linktype)
129{
bf4ffcd9
RC
130 log (LOG_BABBLE) << "io_stream::mklink (" << from << "->" << to << ")"
131 << endLog;
19911586
RC
132 IOStreamProvider const *fromp = findProvider (from);
133 IOStreamProvider const *top = findProvider (to);
3d3c6047
IP
134 if (!fromp)
135 url_scheme_not_registered (from);
136 if (!top)
137 url_scheme_not_registered (to);
19911586
RC
138 if (fromp != top)
139 throw new invalid_argument ("Attempt to link across url providers.");
d2a3615c
MB
140 return fromp->mklink (&from.c_str()[fromp->key.size()],
141 &to.c_str()[top->key.size()], linktype);
7c7034e8
RC
142}
143
144int
a3a02820 145io_stream::move_copy (const std::string& from, const std::string& to)
7c7034e8
RC
146{
147 /* parameters are ok - checked before calling us, and we are private */
148 io_stream *in = io_stream::open (to, "wb");
149 io_stream *out = io_stream::open (from, "rb");
341988b9
RC
150 if (io_stream::copy (in, out))
151 {
bf4ffcd9
RC
152 log (LOG_TIMESTAMP) << "Failed copy of " << from << " to " << to
153 << endLog;
341988b9
RC
154 delete out;
155 io_stream::remove (to);
156 delete in;
157 return 1;
158 }
159 /* TODO:
160 out->set_mtime (in->get_mtime ());
161 */
162 delete in;
163 delete out;
164 io_stream::remove (from);
165 return 0;
166}
167
df62e023 168ssize_t io_stream::copy (io_stream * in, io_stream * out)
341988b9
RC
169{
170 if (!in || !out)
171 return -1;
df62e023
RC
172 char
173 buffer[16384];
174 ssize_t
175 countin,
176 countout;
7c7034e8
RC
177 while ((countin = in->read (buffer, 16384)) > 0)
178 {
179 countout = out->write (buffer, countin);
180 if (countout != countin)
df62e023 181 {
bf4ffcd9
RC
182 log (LOG_TIMESTAMP) << "io_stream::copy failed to write "
183 << countin << " bytes" << endLog;
df62e023
RC
184 return countout ? countout : -1;
185 }
7c7034e8 186 }
3c054baf 187 // XXX FIXME: What if countin < 0? return an error
341988b9 188
7c7034e8
RC
189 /* TODO:
190 out->set_mtime (in->get_mtime ());
191 */
7c7034e8
RC
192 return 0;
193}
194
195int
a3a02820 196io_stream::move (const std::string& from, const std::string& to)
7c7034e8 197{
19911586
RC
198 IOStreamProvider const *fromp = findProvider (from);
199 IOStreamProvider const *top = findProvider (to);
3d3c6047
IP
200 if (!fromp)
201 url_scheme_not_registered (from);
202 if (!top)
203 url_scheme_not_registered (to);
19911586
RC
204 if (fromp != top)
205 return io_stream::move_copy (from, to);
d2a3615c
MB
206 return fromp->move (&from.c_str()[fromp->key.size()],
207 &to.c_str()[top->key.size()]);
b24c88b3
RC
208}
209
210char *
211io_stream::gets (char *buffer, size_t length)
212{
213 char *pos = buffer;
214 size_t count = 0;
215 while (count + 1 < length && read (pos, 1) == 1)
216 {
217 count++;
218 pos++;
219 if (*(pos - 1) == '\n')
220 {
edef4f57
CV
221 --pos; /* end of line, remove from buffer */
222 if (pos > buffer && *(pos - 1) == '\r')
223 --pos;
b24c88b3
RC
224 break;
225 }
226 }
227 if (count == 0 || error ())
228 /* EOF when no chars found, or an error */
229 return NULL;
230 *pos = '\0';
231 return buffer;
232}
233
234int
a3a02820 235io_stream::exists (const std::string& name)
b24c88b3 236{
19911586
RC
237 IOStreamProvider const *p = findProvider (name);
238 if (!p)
3d3c6047 239 url_scheme_not_registered (name);
d2a3615c 240 return p->exists (&name.c_str()[p->key.size()]);
b24c88b3
RC
241}
242
243/* virtual members */
244
6b68e703 245io_stream::~io_stream () {}
This page took 0.065282 seconds and 5 git commands to generate.