This commit is contained in:
2022-06-19 23:58:10 +00:00
committed by GitHub
parent d7c6929ae6
commit 54ab8bc0db
3 changed files with 66 additions and 9 deletions

View File

@@ -3,6 +3,7 @@ use super::enums::DownloaderStatus;
use super::error::DownloaderError;
use super::local_file::LocalFile;
use super::pd_file::PdFile;
use super::pd_file::PdFilePartStatus;
use super::pd_file::PdFileResult;
use super::tasks::check_tasks;
use crate::ext::atomic::AtomicQuick;
@@ -462,6 +463,28 @@ impl<T: Write + Seek + Send + Sync + ClearFile + GetTargetFileName> DownloaderIn
}
Ok(())
}
/// Write datas to the file.
/// * `data` - Data
/// * `pd` - The status of the writed part
/// *
pub fn write_part(
&self,
data: &[u8],
pd: &Arc<PdFilePartStatus>,
index: usize,
) -> Result<(), DownloaderError> {
match self.file.get_mut().deref_mut() {
Some(f) => {
let offset =
(self.get_part_size() as u64) * (index as u64) + (pd.downloaded_size() as u64);
f.seek(SeekFrom::Start(offset))?;
f.write_all(data)?;
}
None => {}
}
Ok(())
}
}
/// A file downloader

View File

@@ -276,6 +276,16 @@ impl PdFile {
Ok(())
}
/// Returns true if all parts are downloaded.
pub fn is_all_part_downloaded(&self) -> bool {
for part in self.part_datas.get_ref().iter() {
if !part.is_downloaded() {
return false;
}
}
return true;
}
#[inline]
/// Returns true if the download is completed.
pub fn is_completed(&self) -> bool {

View File

@@ -150,18 +150,32 @@ pub async fn create_download_tasks_multi_first<
>(
d: Arc<DownloaderInternal<T>>,
) -> Result<(), DownloaderError> {
#[cfg(test)]
{
println!("Created first download task in multiple thread mode.");
}
let result = d
.client
.get(d.url.deref().clone(), d.headers.as_ref().clone())
.await
.try_err(gettext("Failed to get url."))?;
let status = result.status();
#[cfg(test)]
{
println!("HTTP status: {}", status);
}
if status.as_u16() >= 400 {
return Err(DownloaderError::from(status));
}
match result.content_length() {
Some(len) => match d.pd.set_file_size(len) {
Ok(_) => {}
Ok(_) => {
#[cfg(test)]
{
println!("Set the file size to {}", len);
println!("Is downloading: {}", d.pd.is_downloading());
}
}
Err(e) => {
println!("{}", e)
}
@@ -212,7 +226,11 @@ pub async fn create_download_tasks_multi<
if status.as_u16() != 206 {
return Err(DownloaderError::from(status));
}
handle_download(d, result, Some(pd), Some(index)).await
let re = handle_download(d, result, Some(pd), Some(index)).await;
if re.is_err() {
// #TODO
}
re
}
/// Handle download process
@@ -244,6 +262,7 @@ pub async fn handle_download<T: Seek + Write + Send + Sync + ClearFile + GetTarg
return Ok(());
}
let len = data.len() as u32;
d.write_part(&data, pd.as_ref().unwrap(), index.unwrap())?;
pd.as_ref().unwrap().inc(len)?;
d.pd.inc(len as u64)?;
d.pd.update_part_data(index.unwrap())?;
@@ -409,20 +428,25 @@ pub async fn check_tasks<
d.add_task(task);
} else if d.is_multi_threads() {
if d.pd.is_started() {
match dur {
Some(dur) => {
if !dur.is_zero() {
tokio::time::sleep(dur).await;
if d.tasks.get_ref().len() == 0 {
match dur {
Some(dur) => {
if !dur.is_zero() {
tokio::time::sleep(dur).await;
}
}
None => {}
}
None => {}
let task = tokio::spawn(create_download_tasks_multi_first(Arc::clone(&d)));
d.add_task(task);
}
let task = tokio::spawn(create_download_tasks_multi_first(Arc::clone(&d)));
d.add_task(task);
} else {
if d.tasks.get_ref().len() < (d.max_threads.qload() as usize) {
add_new_multi_tasks(&d).await?;
}
if d.pd.is_all_part_downloaded() {
need_break = true;
}
}
}
if need_break {