1 #include "core/filedownload.hpp"
2 #include "core/moviedata.hpp"
3 #include "interface/romtype.hpp"
4 #include "library/string.hpp"
5 #include "library/zip.hpp"
11 void file_download_thread_trampoline(file_download
* d
, loaded_rom
* rom
)
16 class file_download_handler
: public http_request::output_handler
19 file_download_handler(const std::string
& filename
)
21 fp
.open(filename
, std::ios::binary
);
24 ~file_download_handler()
27 void header(const std::string
& name
, const std::string
& content
)
31 void write(const char* source
, size_t srcsize
)
33 fp
.write(source
, srcsize
);
42 file_download::file_download()
48 file_download::~file_download()
50 if(req
.ohandler
) delete req
.ohandler
;
53 void file_download::cancel()
56 errormsg
= "Canceled";
60 void file_download::do_async(loaded_rom
& rom
)
62 tempname
= get_temp_file();
64 req
.ohandler
= new file_download_handler(tempname
);
69 (new threads::thread(file_download_thread_trampoline
, this, &rom
))->detach();
70 } catch(std::exception
& e
) {
79 std::string
file_download::statusmsg()
81 int64_t dn
, dt
, un
, ut
;
83 return (stringfmt() << "Downloading finished").str();
84 req
.get_xfer_status(dn
, dt
, un
, ut
);
86 return "Connecting...";
88 return (stringfmt() << "Downloading (" << dn
<< "/<unknown>)").str();
90 return (stringfmt() << "Downloading (" << (100 * dn
/ dt
) << "%)").str();
92 return (stringfmt() << "Downloading finished").str();
95 void file_download::_do_async(loaded_rom
& rom
)
97 while(!req
.finished
) {
98 threads::alock
h(req
.m
);
99 req
.finished_cond
.wait(h
);
102 if(req
.errormsg
!= "") {
103 remove(tempname
.c_str());
105 errormsg
= req
.errormsg
;
113 if(req
.http_code
> 299) {
115 errormsg
= (stringfmt() << "Got HTTP error " << req
.http_code
).str();
119 //Okay, we got the file.
120 std::istream
* s
= NULL
;
122 zip::reader
r(tempname
);
128 std::istream
& s
= r
[*r
.begin()];
129 std::ofstream
out(tempname2
= get_temp_file(), std::ios::binary
);
132 s
.read(buf
, sizeof(buf
));
133 out
.write(buf
, s
.gcount());
137 tempname2
= tempname
;
141 tempname2
= tempname
;
143 if(tempname
!= tempname2
) remove(tempname
.c_str());
145 core_type
* gametype
= NULL
;
146 if(!rom
.rtype
->isnull())
147 gametype
= rom
.rtype
;
149 moviefile::brief_info
info(tempname2
);
150 auto sysregs
= core_sysregion::find_matching(info
.sysregion
);
151 for(auto i
: sysregs
)
152 if(i
->get_type().get_core_identifier() == info
.corename
)
153 gametype
= &i
->get_type();
155 for(auto i
: sysregs
)
156 gametype
= &i
->get_type();
158 auto mv
= moviefile::memref(target_slot
);
159 moviefile::memref(target_slot
) = new moviefile(tempname2
, *gametype
);
161 remove(tempname2
.c_str());
162 } catch(std::exception
& e
) {
163 remove(tempname2
.c_str());
176 urirewrite::rewriter lsnes_uri_rewrite
;