p3dDownload.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file p3dDownload.cxx
  10. * @author drose
  11. * @date 2009-06-11
  12. */
  13. #include "p3dDownload.h"
  14. /**
  15. *
  16. */
  17. P3DDownload::
  18. P3DDownload() {
  19. _status = P3D_RC_in_progress;
  20. _http_status_code = 0;
  21. _total_data = 0;
  22. _total_expected_data = 0;
  23. _last_reported_time = 0;
  24. _progress_known = false;
  25. _canceled = false;
  26. _download_id = 0;
  27. _instance = nullptr;
  28. }
  29. /**
  30. *
  31. */
  32. P3DDownload::
  33. P3DDownload(const P3DDownload &copy) :
  34. _url(copy._url),
  35. _total_expected_data(copy._total_expected_data),
  36. _progress_known(copy._progress_known)
  37. {
  38. _status = P3D_RC_in_progress;
  39. _http_status_code = 0;
  40. _total_data = 0;
  41. _last_reported_time = 0;
  42. _canceled = false;
  43. _download_id = 0;
  44. _instance = nullptr;
  45. }
  46. /**
  47. *
  48. */
  49. P3DDownload::
  50. ~P3DDownload() {
  51. }
  52. /**
  53. * Supplies the source URL for the download.
  54. */
  55. void P3DDownload::
  56. set_url(const string &url) {
  57. _url = url;
  58. }
  59. /**
  60. * Cancels a running download. download_finished() will not be called, but
  61. * the P3DDownload object itself will eventually be deleted by its owning
  62. * P3DInstance.
  63. */
  64. void P3DDownload::
  65. cancel() {
  66. _canceled = true;
  67. if (_status == P3D_RC_in_progress) {
  68. _status = P3D_RC_generic_error;
  69. }
  70. }
  71. /**
  72. * Resets the download to its initial state, for re-trying the same download.
  73. */
  74. void P3DDownload::
  75. clear() {
  76. _status = P3D_RC_in_progress;
  77. _http_status_code = 0;
  78. _total_data = 0;
  79. _last_reported_time = 0;
  80. _canceled = false;
  81. _download_id = 0;
  82. }
  83. /**
  84. * Called by P3DInstance as more data arrives from the host. Returns true on
  85. * success, false if the download should be aborted.
  86. */
  87. bool P3DDownload::
  88. feed_url_stream(P3D_result_code result_code,
  89. int http_status_code,
  90. size_t total_expected_data,
  91. const unsigned char *this_data,
  92. size_t this_data_size) {
  93. if (_canceled) {
  94. return false;
  95. }
  96. _status = result_code;
  97. _http_status_code = http_status_code;
  98. if (this_data_size != 0) {
  99. if (!receive_data(this_data, this_data_size)) {
  100. // Failure writing to disk or some such.
  101. _status = P3D_RC_generic_error;
  102. download_finished(false);
  103. return false;
  104. }
  105. _total_data += this_data_size;
  106. }
  107. total_expected_data = max(total_expected_data, _total_data);
  108. if (total_expected_data > _total_expected_data) {
  109. // If the expected data grows during the download, we don't really know
  110. // how much we're getting.
  111. _progress_known = false;
  112. _total_expected_data = total_expected_data;
  113. }
  114. if (_total_expected_data > 0 &&
  115. (double)_total_data / (double)_total_expected_data < 0.9) {
  116. // But if we're not close to our target yet, let's say we do know (at
  117. // least until we get there and the target moves again).
  118. _progress_known = true;
  119. }
  120. download_progress();
  121. if (_status != P3D_RC_in_progress) {
  122. // We're done.
  123. if (get_download_success()) {
  124. _progress_known = true;
  125. }
  126. download_finished(get_download_success());
  127. }
  128. return true;
  129. }
  130. /**
  131. * Called as new data is downloaded. Returns true on success, false on
  132. * failure.
  133. */
  134. bool P3DDownload::
  135. receive_data(const unsigned char *this_data, size_t this_data_size) {
  136. return false;
  137. }
  138. /**
  139. * Intended to be overloaded to generate an occasional callback as new data
  140. * comes in.
  141. */
  142. void P3DDownload::
  143. download_progress() {
  144. time_t now = time(nullptr);
  145. if (now - _last_reported_time > 10) {
  146. _last_reported_time = now;
  147. nout << "Downloading " << get_url() << ": ";
  148. if (_progress_known) {
  149. nout << int(get_download_progress() * 1000.0) / 10.0 << "%";
  150. } else {
  151. nout << int((double)get_total_data() / 104857.6) / 10.0 << "M";
  152. }
  153. nout << ", " << this << "\n";
  154. }
  155. }
  156. /**
  157. * Intended to be overloaded to generate a callback when the download
  158. * finishes, either successfully or otherwise. The bool parameter is true if
  159. * the download was successful.
  160. */
  161. void P3DDownload::
  162. download_finished(bool success) {
  163. nout << "Downloaded " << get_url() << ": ";
  164. if (_progress_known) {
  165. nout << int(get_download_progress() * 1000.0) / 10.0 << "%";
  166. } else {
  167. nout << int((double)get_total_data() / 104857.6) / 10.0 << "M";
  168. }
  169. nout << ", " << this << ", success = " << success << "\n";
  170. }