1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cmp::{max, min};
use std::ops::Range;
use std::path::PathBuf;
use std::time::SystemTime;
use embedder_traits::FilterPattern;
use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf;
use num_traits::ToPrimitive;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::blob_url_store::{BlobBuf, BlobURLStoreError};
// HACK: Not really process-safe now, we should send Origin
// directly instead of this in future, blocked on #11722
/// File manager store entry's origin
pub type FileOrigin = String;
/// A token modulating access to a file for a blob URL.
pub enum FileTokenCheck {
/// Checking against a token not required,
/// used for accessing a file
/// that isn't linked to from a blob URL.
NotRequired,
/// Checking against token required.
Required(Uuid),
/// Request should always fail,
/// used for cases when a check is required,
/// but no token could be acquired.
ShouldFail,
}
/// Relative slice positions of a sequence,
/// whose semantic should be consistent with (start, end) parameters in
/// <https://w3c.github.io/FileAPI/#dfn-slice>
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct RelativePos {
/// Relative to first byte if non-negative,
/// relative to one past last byte if negative,
pub start: i64,
/// Relative offset from first byte if Some(non-negative),
/// relative to one past last byte if Some(negative),
/// None if one past last byte
pub end: Option<i64>,
}
impl RelativePos {
/// Full range from start to end
pub fn full_range() -> RelativePos {
RelativePos {
start: 0,
end: None,
}
}
/// Instantiate optional slice position parameters
pub fn from_opts(start: Option<i64>, end: Option<i64>) -> RelativePos {
RelativePos {
start: start.unwrap_or(0),
end,
}
}
/// Slice the inner sliced range by repositioning
pub fn slice_inner(&self, rel_pos: &RelativePos) -> RelativePos {
RelativePos {
start: self.start + rel_pos.start,
end: match (self.end, rel_pos.end) {
(Some(old_end), Some(rel_end)) => Some(old_end + rel_end),
(old, None) => old,
(None, rel) => rel,
},
}
}
/// Compute absolute range by giving the total size
/// <https://w3c.github.io/FileAPI/#slice-method-algo>
pub fn to_abs_range(&self, size: usize) -> Range<usize> {
let size = size as i64;
let start = {
if self.start < 0 {
max(size + self.start, 0)
} else {
min(self.start, size)
}
};
let end = match self.end {
Some(rel_end) => {
if rel_end < 0 {
max(size + rel_end, 0)
} else {
min(rel_end, size)
}
},
None => size,
};
let span: i64 = max(end - start, 0);
Range {
start: start.to_usize().unwrap(),
end: (start + span).to_usize().unwrap(),
}
}
}
/// Response to file selection request
#[derive(Debug, Deserialize, Serialize)]
pub struct SelectedFile {
pub id: Uuid,
pub filename: PathBuf,
pub modified: SystemTime,
pub size: u64,
// https://w3c.github.io/FileAPI/#dfn-type
pub type_string: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub enum FileManagerThreadMsg {
/// Select a single file. Last field is pre-selected file path for testing
SelectFile(
Vec<FilterPattern>,
IpcSender<FileManagerResult<SelectedFile>>,
FileOrigin,
Option<String>,
),
/// Select multiple files. Last field is pre-selected file paths for testing
SelectFiles(
Vec<FilterPattern>,
IpcSender<FileManagerResult<Vec<SelectedFile>>>,
FileOrigin,
Option<Vec<String>>,
),
/// Read FileID-indexed file in chunks, optionally check URL validity based on boolean flag
ReadFile(
IpcSender<FileManagerResult<ReadFileProgress>>,
Uuid,
FileOrigin,
),
/// Add an entry as promoted memory-based blob
PromoteMemory(Uuid, BlobBuf, bool, FileOrigin),
/// Add a sliced entry pointing to the parent FileID, and send back the associated FileID
/// as part of a valid Blob URL
AddSlicedURLEntry(
Uuid,
RelativePos,
IpcSender<Result<Uuid, BlobURLStoreError>>,
FileOrigin,
),
/// Decrease reference count and send back the acknowledgement
DecRef(Uuid, FileOrigin, IpcSender<Result<(), BlobURLStoreError>>),
/// Activate an internal FileID so it becomes valid as part of a Blob URL
ActivateBlobURL(Uuid, IpcSender<Result<(), BlobURLStoreError>>, FileOrigin),
/// Revoke Blob URL and send back the acknowledgement
RevokeBlobURL(Uuid, FileOrigin, IpcSender<Result<(), BlobURLStoreError>>),
}
#[derive(Debug, Deserialize, Serialize)]
pub enum ReadFileProgress {
Meta(BlobBuf),
Partial(Vec<u8>),
EOF,
}
pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;
#[derive(Debug, Deserialize, Serialize)]
pub enum FileManagerThreadError {
/// The selection action is invalid due to exceptional reason
InvalidSelection,
/// The selection action is cancelled by user
UserCancelled,
/// Errors returned from file system request
FileSystemError(String),
/// Blob URL Store error
BlobURLStoreError(BlobURLStoreError),
}