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
//! Thread safe implementation of the [ReadHandler] type for reading an in-memory array of bytes.
use crate::*;
use std::sync::{Arc, Mutex};
pub struct ByteStream {
bytes: Vec<u8>,
offset: usize,
}
impl ByteStream {
pub fn new(bytes: Vec<u8>) -> Self {
ByteStream { bytes, offset: 0 }
}
}
wrap_read_handler! {
pub struct ByteReadHandler {
stream: Arc<Mutex<ByteStream>>,
}
impl ReadHandler {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn read(&self, ptr: *mut u8, size: usize, n: usize) -> usize {
let Ok(mut stream) = self.stream.lock() else {
return 0;
};
let s = (stream.bytes.len() - stream.offset) / size;
let ret = s.min(n);
let buffer = unsafe { std::slice::from_raw_parts_mut(ptr, ret * size) };
buffer.copy_from_slice(&stream.bytes[stream.offset..stream.offset + ret * size]);
stream.offset += ret * size;
ret
}
fn seek(&self, offset: i64, whence: ::std::os::raw::c_int) -> ::std::os::raw::c_int {
let Ok(mut stream) = self.stream.lock() else {
return -1;
};
const SEEK_SET: i32 = 0;
const SEEK_CUR: i32 = 1;
const SEEK_END: i32 = 2;
match whence {
SEEK_SET => {
if offset < 0 {
return -1;
}
let offset = offset as usize;
if offset > stream.bytes.len() {
return -1;
}
stream.offset = offset;
0
}
SEEK_CUR => {
if offset < 0 {
let offset = -offset as usize;
if offset > stream.offset {
return -1;
}
stream.offset -= offset;
} else {
let offset = offset as usize;
if offset + stream.offset > stream.bytes.len() {
return -1;
}
stream.offset += offset;
}
0
}
SEEK_END => {
if offset > 0 {
return -1;
}
let offset = -offset as usize;
if offset > stream.bytes.len() {
return -1;
}
stream.offset = stream.bytes.len() - offset;
0
}
_ => -1,
}
}
fn tell(&self) -> i64 {
let Ok(stream) = self.stream.lock() else {
return 0;
};
stream.offset as i64
}
fn eof(&self) -> i32 {
let Ok(stream) = self.stream.lock() else {
return 1;
};
if stream.offset >= stream.bytes.len() {
1
} else {
0
}
}
fn may_block(&self) -> i32 {
0
}
}
}