ソースを参照

download_to_file() with offset

David Rose 23 年 前
コミット
5d56f13f1a
2 ファイル変更28 行追加2 行削除
  1. 27 1
      panda/src/downloader/httpChannel.cxx
  2. 1 1
      panda/src/downloader/httpChannel.h

+ 27 - 1
panda/src/downloader/httpChannel.cxx

@@ -415,18 +415,44 @@ read_body() {
 //               At this time, it is possible that a communications
 //               At this time, it is possible that a communications
 //               error will have left a partial file, so
 //               error will have left a partial file, so
 //               is_download_complete() may be called to test this.
 //               is_download_complete() may be called to test this.
+//
+//               If first_byte is nonzero, it specifies the first byte
+//               within the file (zero-based) at which to start
+//               writing the downloaded data.  This can work well in
+//               conjunction with get_subdocument() to restart a
+//               previously-interrupted download.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool HTTPChannel::
 bool HTTPChannel::
-download_to_file(const Filename &filename) {
+download_to_file(const Filename &filename, size_t first_byte) {
   reset_download_to();
   reset_download_to();
   _download_to_filename = filename;
   _download_to_filename = filename;
   _download_to_filename.set_binary();
   _download_to_filename.set_binary();
+  _download_to_file.close();
+  _download_to_file.clear();
+
   if (!_download_to_filename.open_write(_download_to_file)) {
   if (!_download_to_filename.open_write(_download_to_file)) {
     downloader_cat.info()
     downloader_cat.info()
       << "Could not open " << filename << " for writing.\n";
       << "Could not open " << filename << " for writing.\n";
     return false;
     return false;
   }
   }
 
 
+  if (first_byte != 0) {
+    // Windows doesn't complain if you try to seek past the end of
+    // file--it happily appends enough zero bytes to make the
+    // difference.  Blecch.  That means we need to get the file size
+    // first to check it ourselves.
+    _download_to_file.seekp(0, ios::end);
+    if (first_byte > (size_t)_download_to_file.tellp()) {
+      downloader_cat.info()
+        << "Invalid starting position of byte " << first_byte << " within "
+        << _download_to_filename << " (which has " 
+        << _download_to_file.tellp() << " bytes)\n";
+      _download_to_file.close();
+      return false;
+    }
+    _download_to_file.seekp(first_byte);
+  }
+
   _download_dest = DD_file;
   _download_dest = DD_file;
 
 
   if (_nonblocking) {
   if (_nonblocking) {

+ 1 - 1
panda/src/downloader/httpChannel.h

@@ -115,7 +115,7 @@ PUBLISHED:
   bool run();
   bool run();
 
 
   ISocketStream *read_body();
   ISocketStream *read_body();
-  bool download_to_file(const Filename &filename);
+  bool download_to_file(const Filename &filename, size_t first_byte = 0);
   bool download_to_ram(Ramfile *ramfile);
   bool download_to_ram(Ramfile *ramfile);
 
 
   INLINE size_t get_bytes_downloaded() const;
   INLINE size_t get_bytes_downloaded() const;