1use crate::out_stream::{BlobStreamOut, OutStreamError};
6use crate::prelude::{SetChunkData, SetChunkFrontData, TransferId};
7use std::time::{Duration, Instant};
8
9#[allow(unused)]
10#[derive(Debug)]
11pub struct Logic {
12 out_stream: BlobStreamOut,
13 blob: Vec<u8>,
14 fixed_chunk_size: usize,
15 transfer_id: TransferId,
16}
17
18impl Logic {
19 pub fn new(
20 transfer_id: TransferId,
21 fixed_chunk_size: usize,
22 resend_duration: Duration,
23 blob: &[u8],
24 ) -> Self {
25 let chunk_count = blob.len().div_ceil(fixed_chunk_size);
26 Self {
27 out_stream: BlobStreamOut::new(chunk_count, resend_duration),
28 blob: blob.to_vec(),
29 transfer_id,
30 fixed_chunk_size,
31 }
32 }
33
34 #[inline]
35 fn get_range(&self, index: usize) -> (usize, usize) {
36 assert!(index < self.blob.len(), "out logic index out of bounds");
37 let start = index * self.fixed_chunk_size;
38 let is_last_chunk = index + 1 == self.out_stream.chunk_count();
39 let count = if is_last_chunk {
40 let remaining_size = self.blob.len() % self.fixed_chunk_size;
41 if remaining_size == 0 {
42 self.fixed_chunk_size
43 } else {
44 remaining_size
45 }
46 } else {
47 self.fixed_chunk_size
48 };
49
50 (start, start + count)
51 }
52
53 #[must_use]
54 pub fn send(&mut self, now: Instant, max_count: usize) -> Vec<SetChunkFrontData> {
55 let indices = self.out_stream.send(now, max_count);
56 let mut set_chunks = Vec::new();
57 for chunk_index in indices {
58 let (start, end) = self.get_range(chunk_index);
59 let payload = &self.blob[start..end];
60 let set_chunk = SetChunkFrontData {
61 transfer_id: self.transfer_id,
62 data: SetChunkData {
63 chunk_index: chunk_index as u32,
64 payload: payload.to_vec(),
65 },
66 };
67 set_chunks.push(set_chunk);
68 }
69 set_chunks
70 }
71
72 pub fn set_waiting_for_chunk_index(
73 &mut self,
74 waiting_for_index: usize,
75 receive_mask: u64,
76 ) -> Result<(), OutStreamError> {
77 self.out_stream
78 .set_waiting_for_chunk_index(waiting_for_index, receive_mask)
79 }
80
81 #[must_use]
82 pub fn is_received_by_remote(&self) -> bool {
83 self.out_stream.is_received_by_remote()
84 }
85
86 #[must_use]
87 pub fn octet_size(&self) -> usize {
88 self.blob.len()
89 }
90
91 #[must_use]
92 pub fn chunk_size(&self) -> usize {
93 self.fixed_chunk_size
94 }
95
96 #[must_use]
97 pub fn transfer_id(&self) -> TransferId {
98 self.transfer_id
99 }
100}