1use std::cmp::{max, min};
6use std::ops::Range;
7
8use embedder_traits::{EmbedderControlId, EmbedderControlResponse, FilePickerRequest};
9use ipc_channel::ipc::IpcSender;
10use malloc_size_of_derive::MallocSizeOf;
11use num_traits::ToPrimitive;
12use profile_traits::generic_callback::GenericCallback;
13use serde::{Deserialize, Serialize};
14use servo_base::generic_channel::GenericSender;
15use servo_url::ImmutableOrigin;
16use uuid::Uuid;
17
18use crate::CoreResourceMsg;
19use crate::blob_url_store::{BlobBuf, BlobURLStoreError};
20
21#[derive(Clone, Debug)]
23pub enum FileTokenCheck {
24 NotRequired,
28 Required(Uuid),
30 ShouldFail,
34}
35
36#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
40pub struct RelativePos {
41 pub start: i64,
44 pub end: Option<i64>,
48}
49
50impl RelativePos {
51 pub fn full_range() -> RelativePos {
53 RelativePos {
54 start: 0,
55 end: None,
56 }
57 }
58
59 pub fn from_opts(start: Option<i64>, end: Option<i64>) -> RelativePos {
61 RelativePos {
62 start: start.unwrap_or(0),
63 end,
64 }
65 }
66
67 pub fn slice_inner(&self, rel_pos: &RelativePos) -> RelativePos {
69 RelativePos {
70 start: self.start + rel_pos.start,
71 end: match (self.end, rel_pos.end) {
72 (Some(old_end), Some(rel_end)) => Some(old_end + rel_end),
73 (old, None) => old,
74 (None, rel) => rel,
75 },
76 }
77 }
78
79 pub fn to_abs_range(&self, size: usize) -> Range<usize> {
82 let size = size as i64;
83
84 let start = {
85 if self.start < 0 {
86 max(size + self.start, 0)
87 } else {
88 min(self.start, size)
89 }
90 };
91
92 let end = match self.end {
93 Some(rel_end) => {
94 if rel_end < 0 {
95 max(size + rel_end, 0)
96 } else {
97 min(rel_end, size)
98 }
99 },
100 None => size,
101 };
102
103 let span: i64 = max(end - start, 0);
104
105 Range {
106 start: start.to_usize().unwrap(),
107 end: (start + span).to_usize().unwrap(),
108 }
109 }
110
111 pub fn to_abs_blob_range(&self, size: usize) -> Range<usize> {
115 let orig_range = self.to_abs_range(size);
116 let start = orig_range.start;
117 let end = usize::min(orig_range.end + 1, size);
118 Range { start, end }
119 }
120}
121
122#[derive(Debug, Deserialize, Serialize)]
123pub enum FileManagerThreadMsg {
124 SelectFiles(
126 EmbedderControlId,
127 FilePickerRequest,
128 GenericCallback<EmbedderControlResponse>,
129 ),
130
131 ReadFile(
133 IpcSender<FileManagerResult<ReadFileProgress>>,
134 Uuid,
135 ImmutableOrigin,
136 ),
137
138 PromoteMemory(Uuid, BlobBuf, bool, ImmutableOrigin),
140
141 AddSlicedURLEntry(
144 Uuid,
145 RelativePos,
146 GenericSender<Result<Uuid, BlobURLStoreError>>,
147 ImmutableOrigin,
148 ),
149
150 DecRef(
152 Uuid,
153 ImmutableOrigin,
154 GenericSender<Result<(), BlobURLStoreError>>,
155 ),
156
157 ActivateBlobURL(
159 Uuid,
160 IpcSender<Result<(), BlobURLStoreError>>,
161 ImmutableOrigin,
162 ),
163
164 RevokeBlobURL(
166 Uuid,
167 ImmutableOrigin,
168 GenericSender<Result<(), BlobURLStoreError>>,
169 ),
170
171 GetTokenForFile(Uuid, ImmutableOrigin, GenericSender<GetTokenForFileReply>),
172 RevokeTokenForFile(Uuid, Uuid),
173}
174
175#[derive(Debug, Deserialize, Serialize)]
176pub struct GetTokenForFileReply {
177 pub token: Option<Uuid>,
178 pub revoke_sender: GenericSender<CoreResourceMsg>,
179 pub refresh_sender: GenericSender<CoreResourceMsg>,
180}
181
182#[derive(Debug, Deserialize, Serialize)]
183pub enum ReadFileProgress {
184 Meta(BlobBuf),
185 Partial(Vec<u8>),
186 EOF,
187}
188
189pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;
190
191#[derive(Debug, Deserialize, Serialize)]
192pub enum FileManagerThreadError {
193 InvalidSelection,
195 UserCancelled,
197 FileSystemError(String),
199 BlobURLStoreError(BlobURLStoreError),
201}