4 * Copyright (c) 2000, 2001, Red Hat, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * A copy of the GNU General Public License can be found at
14 * Written by DJ Delorie <dj@cygnus.com>
18 /* The purpose of this file is to act as a pretty interface to
19 netio.cc. We add a progress dialog and some convenience functions
20 (like collect to string or file */
34 #include "io_stream.h"
35 #include "io_stream_memory.h"
39 #include "filemanip.h"
43 #include "Exception.h"
45 #include "LogSingleton.h"
47 extern ThreeBarProgressPage Progress
;
49 static int max_bytes
= 0;
50 static int is_local_install
= 0;
52 long long int total_download_bytes
= 0;
53 long long int total_download_bytes_sofar
= 0;
55 static DWORD start_tics
;
58 init_dialog (const std::string
&url
, int length
)
63 std::string::size_type divide
= url
.find_last_of('/');
65 Progress
.SetText1(IDS_PROGRESS_DOWNLOADING
);
66 std::wstring fmt
= LoadStringW(IDS_PROGRESS_DOWNLOADING_FROM
);
67 std::wstring s
= format(fmt
,
68 url
.substr(divide
+ 1).c_str(),
69 url
.substr(0, divide
).c_str());
70 Progress
.SetText2(s
.c_str());
71 Progress
.SetText3(IDS_PROGRESS_CONNECTING
);
73 start_tics
= GetTickCount ();
84 static unsigned int last_tics
= 0;
85 DWORD tics
= GetTickCount ();
86 if (tics
== start_tics
) // to prevent division by zero
88 if (tics
< last_tics
+ 200) // to prevent flickering updates
92 kbps
= ((double)bytes
) / (double)(tics
- start_tics
);
95 int perc
= (int)(100.0 * ((double)bytes
) / (double)max_bytes
);
96 Progress
.SetBar1(bytes
, max_bytes
);
97 sprintf (buf
, "%d %% (%dk/%dk) %03.1f kB/s",
98 perc
, bytes
/ 1000, max_bytes
/ 1000, kbps
);
99 if (total_download_bytes
> 0)
100 Progress
.SetBar2(total_download_bytes_sofar
+ bytes
,
101 total_download_bytes
);
104 sprintf (buf
, "%d %2.1f kB/s", bytes
, kbps
);
106 Progress
.SetText3(buf
);
110 getUrlToStream (const std::string
&_url
, io_stream
*output
)
112 is_local_install
= (source
== IDC_SOURCE_LOCALDIR
);
113 init_dialog (_url
, 0);
114 NetIO
*n
= NetIO::open (_url
.c_str(), true);
118 throw new Exception (TOSTRING(__LINE__
) " " __FILE__
, "Error opening url", APPERR_IO_ERROR
);
122 max_bytes
= n
->file_size
;
130 rlen
= n
->read (buf
, 2048);
133 wlen
= output
->write (buf
, rlen
);
135 /* FIXME: Show an error message */
138 progress (total_bytes
);
145 /* reseeking is up to the recipient if desired */
147 Log (LOG_BABBLE
) << "Fetched URL: " << _url
<< endLog
;
151 get_url_to_membuf (const std::string
&_url
, HWND owner
)
153 io_stream_memory
*membuf
= new io_stream_memory ();
156 getUrlToStream (_url
, membuf
);
158 if (membuf
->seek (0, IO_SEEK_SET
))
162 Log (LOG_BABBLE
) << "get_url_to_membuf(): seek (0) failed for membuf!" << endLog
;
169 if (e
->errNo() != APPERR_IO_ERROR
)
176 // predicate: url has no '\0''s in it.
178 get_url_to_string (const std::string
&_url
, HWND owner
)
180 io_stream
*stream
= get_url_to_membuf (_url
, owner
);
182 return std::string();
183 size_t bytes
= stream
->get_size ();
186 /* zero length, or error retrieving length */
188 Log (LOG_BABBLE
) << "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer" << endLog
;
189 return std::string();
191 char temp
[bytes
+ 1];
192 /* membufs are quite safe */
193 stream
->read (temp
, bytes
);
196 return std::string(temp
);
200 get_url_to_file (const std::string
&_url
,
201 const std::string
&_filename
,
205 Log (LOG_BABBLE
) << "get_url_to_file " << _url
<< " " << _filename
<< endLog
;
206 if (total_download_bytes
> 0)
208 int df
= diskfull (get_root_dir ().c_str());
209 Progress
.SetBar3(df
);
211 init_dialog (_url
, expected_length
);
213 remove (_filename
.c_str()); /* but ignore errors */
215 NetIO
*n
= NetIO::open (_url
.c_str(), false);
222 FILE *f
= nt_fopen (_filename
.c_str(), "wb");
225 const char *err
= strerror (errno
);
227 err
= "(unknown error)";
228 fatal (owner
, IDS_ERR_OPEN_WRITE
, _filename
.c_str(), err
);
232 max_bytes
= n
->file_size
;
240 count
= n
->read (buf
, sizeof (buf
));
243 fwrite (buf
, 1, count
, f
);
244 total_bytes
+= count
;
245 progress (total_bytes
);
248 total_download_bytes_sofar
+= total_bytes
;
254 if (total_download_bytes
> 0)
256 int df
= diskfull (get_root_dir ().c_str());
257 Progress
.SetBar3(df
);
259 Progress
.SetText3("");