1use std::io::{self, Read, Write};
2use std::sync::atomic::{AtomicUsize, Ordering};
3use std::sync::{Arc};
4
5pub mod conv;
6
7pub fn read_full(buffer: &mut [u8], r: &mut dyn Read) -> Result<usize, io::Error> {
13 let mut len_read: usize = 0;
14 loop {
15 match r.read(&mut buffer[len_read..]) {
16 Ok(size) => {
17 len_read += size;
18 if size == 0 || buffer.len() == len_read {
19 return Ok(len_read);
20 }
21 }
22 Err(e) => return Err(e),
23 }
24 }
25}
26
27pub struct BlackHole {}
31impl Write for BlackHole {
32 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
33 Ok(buf.len())
34 }
35 fn flush(&mut self) -> io::Result<()> {
36 Ok(())
37 }
38}
39
40struct MeteringReaderHandle<'a> {
41 underlying_reader: &'a mut dyn Read,
42 counter: Arc<AtomicUsize>,
43}
44
45pub struct MeteringReader<'a> {
49 inner: MeteringReaderHandle<'a>,
50 counter: Arc<AtomicUsize>,
51}
52
53impl MeteringReader<'_> {
54 pub fn new(r: &mut dyn Read) -> MeteringReader {
55 let counter = Arc::new(AtomicUsize::new(0));
56 MeteringReader{
57 inner : MeteringReaderHandle{
58 underlying_reader: r,
59 counter: Arc::clone(&counter),
60 },
61 counter: Arc::clone(&counter),
62 }
63 }
64
65 pub fn as_reader(&mut self) -> &mut dyn Read {
66 &mut self.inner
67 }
68
69 pub fn get_counter(&self) -> usize {
70 self.counter.load(Ordering::Relaxed)
71 }
72}
73
74impl Read for MeteringReaderHandle<'_> {
75 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
76 match self.underlying_reader.read(buf) {
77 Ok(size) => {
78 self.counter.fetch_add(size, Ordering::Relaxed);
79 Ok(size)
80 },
81 Err(e) => {
82 Err(e)
83 }
84 }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use crate as lib;
91 use std::io::{self, Read};
92
93 pub struct SlowReader<'a> {
94 underlying_reader: &'a mut dyn (Read),
95 }
96
97 impl Read for SlowReader<'_> {
98 fn read(& mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
99 if buf.len() >= 2 {
101 self.underlying_reader.read(&mut buf[..2])
102 } else {
103 self.underlying_reader.read(&mut buf[..])
104 }
105 }
106 }
107
108 mod test_read_full {
109
110 #[test]
111 fn test_read_full_slow() {
112 let mut underlying_data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
113 let mut reader = super::SlowReader {
114 underlying_reader: &mut underlying_data,
115 };
116 let mut buf = vec![0u8; 4];
117 let res = super::lib::read_full(&mut buf[..4], &mut reader);
118 assert_eq!(res.unwrap(), 4usize);
119 assert_eq!(buf[..4], [0, 1, 2, 3]);
120 let res = super::lib::read_full(&mut buf[..3], &mut reader);
121 assert_eq!(res.unwrap(), 3usize);
122 assert_eq!(buf[..3], [4, 5, 6]);
123 let res = super::lib::read_full(&mut buf[..3], &mut reader);
124 assert_eq!(res.unwrap(), 1usize);
125 assert_eq!(buf[0], 7);
126 }
127
128 #[test]
129 fn test_read_full_once() {
130 let mut underlying_data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
131 let mut buf = vec![0u8; 9];
132 let res = super::lib::read_full(&mut buf[..], &mut underlying_data);
133 assert_eq!(res.unwrap(), 8usize);
134 }
135 }
136
137 mod test_metering_reader {
138 use std::io;
139 use crate::{MeteringReader, BlackHole};
140 use std::sync::{Arc};
141
142 #[test]
143 fn test_metering_reader_update() {
144 let mut input = "123456".as_bytes();
145 let input_len = input.len();
146 let mut meter = MeteringReader::new(&mut input);
147 let mut meter_reader = meter.as_reader();
148 io::copy(&mut meter_reader, &mut BlackHole{}).unwrap();
149 let result = meter.get_counter();
150 assert_eq!(input_len, result);
151 }
152
153 #[test]
154 fn test_metering_drop_counter_when_meter_is_dropped() {
155 let counter_ref;
156 {
157 let mut input = "123456".as_bytes();
158 let input_len = input.len();
159 let mut meter = MeteringReader::new(&mut input);
160 counter_ref = Arc::downgrade(&meter.counter);
161 let mut meter_reader = meter.as_reader();
162 io::copy(&mut meter_reader, &mut BlackHole{}).unwrap();
163 let result = meter.get_counter();
164 assert_eq!(input_len, result);
165 }
166 assert_eq!(counter_ref.upgrade().is_none(), true);
167 }
168 }
169}