1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use super::{BytesReader, Cacheable, NBytesReadable, Position, RemainderCountable};
15 use std::convert::Infallible;
16 
17 /// Reader for reading slices. This reader implements `BytesReader` trait,
18 /// `Cacheable` trait and `Countable` trait.
19 ///
20 /// let slice = "Hello World";
21 /// let mut reader = SliceReader::new(slice.as_bytes());
22 /// assert_eq!(reader.next(), Ok(Some(b'H')));
23 /// assert_eq!(reader.peek(), Ok(Some(b'e')));
24 /// assert_eq!(reader.peek(), Ok(Some(b'e')));
25 pub(crate) struct SliceReader<'a> {
26     slice: &'a [u8],
27     index: usize,         // A cursor to the next character to be read.
28     cache: Option<Cache>, // A cache for storing accumulated characters.
29 }
30 
31 // A simple cache implementation for `SliceReader`. We just need to save a
32 // starting position.
33 struct Cache(usize);
34 
35 impl<'a> SliceReader<'a> {
36     /// Create a new `SliceReader` from the given slice.
37     ///
38     /// let slice = "Hello World";
39     /// let reader = SliceReader::new(slice.as_bytes());
40     #[inline]
new(slice: &'a [u8]) -> Self41     pub(crate) fn new(slice: &'a [u8]) -> Self {
42         Self {
43             slice,
44             index: 0,
45             cache: None,
46         }
47     }
48 }
49 
50 impl<'a> BytesReader for SliceReader<'a> {
51     type Error = Infallible; // Use Infallible because no error will be returned in SliceReader.
52 
53     #[inline]
next(&mut self) -> Result<Option<u8>, Self::Error>54     fn next(&mut self) -> Result<Option<u8>, Self::Error> {
55         if self.index >= self.slice.len() {
56             return Ok(None);
57         }
58         let ch = self.slice[self.index];
59         self.index += 1;
60         Ok(Some(ch))
61     }
62 
63     #[inline]
peek(&mut self) -> Result<Option<u8>, Self::Error>64     fn peek(&mut self) -> Result<Option<u8>, Self::Error> {
65         if self.index >= self.slice.len() {
66             return Ok(None);
67         }
68         Ok(Some(self.slice[self.index]))
69     }
70 
71     #[inline]
discard(&mut self)72     fn discard(&mut self) {
73         if self.index < self.slice.len() {
74             self.index += 1;
75         }
76     }
77 
78     #[inline]
index(&self) -> usize79     fn index(&self) -> usize {
80         self.index
81     }
82 
position(&self) -> Position83     fn position(&self) -> Position {
84         // The traversal method is used to calculate the `Position`, which
85         // is expensive, and it is not recommended to call it frequently.
86         let index = core::cmp::min(self.index, self.slice.len());
87 
88         let mut position = Position { line: 1, column: 1 };
89         for i in 0..index {
90             match self.slice[i] {
91                 b'\n' => {
92                     position.line += 1;
93                     position.column = 1;
94                 }
95                 _ => {
96                     position.column += 1;
97                 }
98             }
99         }
100         position
101     }
102 }
103 
104 impl<'a> Cacheable for SliceReader<'a> {
105     #[inline]
start_caching(&mut self)106     fn start_caching(&mut self) {
107         self.cache = Some(Cache(self.index));
108     }
109 
110     #[inline]
cached_len(&mut self) -> Option<usize>111     fn cached_len(&mut self) -> Option<usize> {
112         self.cache.as_ref().map(|c| self.index - c.0)
113     }
114 
115     #[inline]
cached_slice(&mut self) -> Option<&[u8]>116     fn cached_slice(&mut self) -> Option<&[u8]> {
117         self.cache.as_ref().map(|c| &self.slice[c.0..self.index])
118     }
119 
120     #[inline]
cached_data(&mut self) -> Option<Vec<u8>>121     fn cached_data(&mut self) -> Option<Vec<u8>> {
122         self.cache
123             .as_ref()
124             .map(|c| self.slice[c.0..self.index].to_vec())
125     }
126 
127     #[inline]
end_caching(&mut self)128     fn end_caching(&mut self) {
129         self.cache = None;
130     }
131 
132     #[inline]
take_cached_data(&mut self) -> Option<Vec<u8>>133     fn take_cached_data(&mut self) -> Option<Vec<u8>> {
134         self.cache
135             .take()
136             .map(|c| self.slice[c.0..self.index].to_vec())
137     }
138 }
139 
140 impl<'a> RemainderCountable for SliceReader<'a> {
141     #[inline]
remainder_len(&self) -> usize142     fn remainder_len(&self) -> usize {
143         self.slice.len() - self.index
144     }
145 
146     #[inline]
remainder_slice(&self) -> &[u8]147     fn remainder_slice(&self) -> &[u8] {
148         &self.slice[self.index..]
149     }
150 
151     #[inline]
remainder_data(&self) -> Vec<u8>152     fn remainder_data(&self) -> Vec<u8> {
153         self.remainder_slice().to_vec()
154     }
155 }
156 
157 impl<'a> NBytesReadable for SliceReader<'a> {
next_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>158     fn next_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error> {
159         if self.index + n > self.slice.len() {
160             return Ok(None);
161         }
162         let result = &self.slice[self.index..self.index + n];
163         self.index += n;
164         Ok(Some(result))
165     }
166 
peek_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>167     fn peek_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error> {
168         if self.index + n > self.slice.len() {
169             return Ok(None);
170         }
171         Ok(Some(&self.slice[self.index..self.index + n]))
172     }
173 
discard_n(&mut self, n: usize)174     fn discard_n(&mut self, n: usize) {
175         if self.index + n > self.slice.len() {
176             return;
177         }
178         self.index += n;
179     }
180 }
181 
182 #[cfg(test)]
183 mod ut_slice_reader {
184     use super::{BytesReader, Cacheable, NBytesReadable, RemainderCountable, SliceReader};
185 
186     /// UT test case for `SliceReader::new`.
187     ///
188     /// # Title
189     /// ut_slice_reader_new
190     ///
191     /// # Brief
192     /// 1. Call `SliceReader::new`.
193     /// 2. Check that parts of the return value are default values.
194     #[test]
ut_slice_reader_new()195     fn ut_slice_reader_new() {
196         let slice = "A";
197         let slice_reader = SliceReader::new(slice.as_bytes());
198         assert_eq!(slice_reader.slice, slice.as_bytes());
199         assert_eq!(slice_reader.index, 0);
200         assert!(slice_reader.cache.is_none());
201     }
202 
203     /// UT test case for `SliceReader::next`.
204     ///
205     /// # Title
206     /// ut_slice_reader_next
207     ///
208     /// # Brief
209     /// 1. Create a `SliceReader`.
210     /// 2. Call `SliceReader::next`.
211     /// 3. Check the return value against the following conditions:
212     ///     - If the end is not read, it returns `Ok(Some(..))`, and the index
213     ///     is moved backward; if the end is read, it returns `Ok(None)`, and
214     ///     the index is not moved.
215     #[test]
ut_slice_reader_next()216     fn ut_slice_reader_next() {
217         let slice = "A";
218         let mut slice_reader = SliceReader::new(slice.as_bytes());
219         assert_eq!(slice_reader.next(), Ok(Some(b'A')));
220         assert_eq!(slice_reader.next(), Ok(None));
221     }
222 
223     /// UT test case for `SliceReader::peek`.
224     ///
225     /// # Title
226     /// ut_slice_reader_peek
227     ///
228     /// # Brief
229     /// 1. Create a `SliceReader`.
230     /// 2. Call `SliceReader::peek`.
231     /// 3. Check the return value against the following conditions:
232     ///     - If the end is not read, it returns `Ok(Some(..))`; if the end is
233     ///     read, it returns `Ok(None)`.
234     #[test]
ut_slice_reader_peek()235     fn ut_slice_reader_peek() {
236         let slice = "A";
237         let mut slice_reader = SliceReader::new(slice.as_bytes());
238         assert_eq!(slice_reader.peek(), Ok(Some(b'A')));
239         assert_eq!(slice_reader.peek(), Ok(Some(b'A')));
240         assert_eq!(slice_reader.next(), Ok(Some(b'A')));
241         assert_eq!(slice_reader.peek(), Ok(None));
242     }
243 
244     /// UT test case for `SliceReader::discard`.
245     ///
246     /// # Title
247     /// ut_slice_reader_discard
248     ///
249     /// # Brief
250     /// 1. Create a `SliceReader`.
251     /// 2. Call `SliceReader::discard`.
252     /// 3. Check `index` against the following conditions:
253     ///     - If the end is not read, the index is moved backward; if the end is
254     ///     read, the index is not moved.
255     #[test]
ut_slice_reader_discard()256     fn ut_slice_reader_discard() {
257         let slice = "A";
258         let mut slice_reader = SliceReader::new(slice.as_bytes());
259         assert_eq!(slice_reader.index, 0);
260         slice_reader.discard();
261         assert_eq!(slice_reader.index, 1);
262         slice_reader.discard();
263         assert_eq!(slice_reader.index, 1);
264     }
265 
266     /// UT test case for `SliceReader::index`.
267     ///
268     /// # Title
269     /// ut_slice_reader_index
270     ///
271     /// # Brief
272     /// 1. Create a `SliceReader`.
273     /// 2. Call `SliceReader::index`.
274     /// 3. Check if the `index` is correct.
275     #[test]
ut_slice_reader_index()276     fn ut_slice_reader_index() {
277         let slice = "A";
278         let slice_reader = SliceReader::new(slice.as_bytes());
279         assert_eq!(slice_reader.index(), 0);
280     }
281 
282     /// UT test case for `SliceReader::position`.
283     ///
284     /// # Title
285     /// ut_slice_reader_position
286     ///
287     /// # Brief
288     /// 1. Create a `SliceReader`.
289     /// 2. Call `SliceReader::position`.
290     /// 3. Check the return value against the following conditions:
291     ///     - If `'\n'` is read, the line number will increase and the column
292     ///     number will return to 1; if other characters are read, the line
293     ///     number will remain unchanged and the column number will increase.
294     #[test]
ut_slice_reader_position()295     fn ut_slice_reader_position() {
296         let slice = "A\nB";
297         let mut slice_reader = SliceReader::new(slice.as_bytes());
298         let position = slice_reader.position();
299         assert_eq!(position.line(), 1);
300         assert_eq!(position.column(), 1);
301         assert_eq!(slice_reader.next(), Ok(Some(b'A')));
302 
303         let position = slice_reader.position();
304         assert_eq!(position.line(), 1);
305         assert_eq!(position.column(), 2);
306         assert_eq!(slice_reader.next(), Ok(Some(b'\n')));
307 
308         let position = slice_reader.position();
309         assert_eq!(position.line(), 2);
310         assert_eq!(position.column(), 1);
311         assert_eq!(slice_reader.next(), Ok(Some(b'B')));
312 
313         let position = slice_reader.position();
314         assert_eq!(position.line(), 2);
315         assert_eq!(position.column(), 2);
316 
317         assert_eq!(slice_reader.next(), Ok(None));
318         let position = slice_reader.position();
319         assert_eq!(position.line(), 2);
320         assert_eq!(position.column(), 2);
321     }
322 
323     /// UT test case for `SliceReader::start_caching`.
324     ///
325     /// # Title
326     /// ut_slice_reader_start_caching
327     ///
328     /// # Brief
329     /// 1. Create a `SliceReader`.
330     /// 2. Call `SliceReader::start_caching`.
331     /// 3. Check if `cache` is correct.
332     #[test]
ut_slice_reader_start_caching()333     fn ut_slice_reader_start_caching() {
334         let slice = "A";
335         let mut slice_reader = SliceReader::new(slice.as_bytes());
336         assert!(slice_reader.cache.is_none());
337         slice_reader.start_caching();
338         assert_eq!(slice_reader.cache.as_ref().unwrap().0, 0);
339     }
340 
341     /// UT test case for `SliceReader::cached_len`.
342     ///
343     /// # Title
344     /// ut_slice_reader_cached_len
345     ///
346     /// # Brief
347     /// 1. Create a `SliceReader`.
348     /// 2. Call `SliceReader::cached_len`.
349     /// 3. Check the return value against the following conditions:
350     ///     - Returns `None` if caching is not enabled, otherwise returns
351     ///     `Some(..)`.
352     #[test]
ut_slice_reader_cached_len()353     fn ut_slice_reader_cached_len() {
354         let slice = "A";
355         let mut slice_reader = SliceReader::new(slice.as_bytes());
356         assert_eq!(slice_reader.cached_len(), None);
357         slice_reader.start_caching();
358         assert_eq!(slice_reader.cached_len(), Some(0));
359     }
360 
361     /// UT test case for `SliceReader::cached_slice`.
362     ///
363     /// # Title
364     /// ut_slice_reader_cached_slice
365     ///
366     /// # Brief
367     /// 1. Create a `SliceReader`.
368     /// 2. Call `SliceReader::cached_slice`.
369     /// 3. Check the return value against the following conditions:
370     ///     - Returns `None` if caching is not enabled, otherwise returns
371     ///     `Some(..)`.
372     #[test]
ut_slice_reader_cached_slice()373     fn ut_slice_reader_cached_slice() {
374         let slice = "A";
375         let mut slice_reader = SliceReader::new(slice.as_bytes());
376         assert_eq!(slice_reader.cached_slice(), None);
377         slice_reader.start_caching();
378         assert_eq!(slice_reader.cached_slice(), Some([].as_slice()));
379     }
380 
381     /// UT test case for `SliceReader::cached_data`.
382     ///
383     /// # Title
384     /// ut_slice_reader_cached_slice
385     ///
386     /// # Brief
387     /// 1. Create a `SliceReader`.
388     /// 2. Call `SliceReader::cached_data`.
389     /// 3. Check the return value against the following conditions:
390     ///     - Returns `None` if caching is not enabled, otherwise returns
391     ///     `Some(..)`.
392     #[test]
ut_slice_reader_cached_data()393     fn ut_slice_reader_cached_data() {
394         let slice = "A";
395         let mut slice_reader = SliceReader::new(slice.as_bytes());
396         assert_eq!(slice_reader.cached_data(), None);
397         slice_reader.start_caching();
398         assert_eq!(slice_reader.cached_data(), Some(Vec::new()));
399     }
400 
401     /// UT test case for `SliceReader::end_caching`.
402     ///
403     /// # Title
404     /// ut_slice_reader_end_caching
405     ///
406     /// # Brief
407     /// 1. Create a `SliceReader`.
408     /// 2. Call `SliceReader::end_caching`.
409     /// 3. Check if `cache` is correct.
410     #[test]
ut_slice_reader_end_caching()411     fn ut_slice_reader_end_caching() {
412         let slice = "A";
413         let mut slice_reader = SliceReader::new(slice.as_bytes());
414         slice_reader.start_caching();
415         assert!(slice_reader.cache.is_some());
416         slice_reader.end_caching();
417         assert!(slice_reader.cache.is_none());
418     }
419 
420     /// UT test case for `SliceReader::take_cached_data`.
421     ///
422     /// # Title
423     /// ut_slice_reader_take_cached_data
424     ///
425     /// # Brief
426     /// 1. Create a `SliceReader`.
427     /// 2. Call `SliceReader::take_cached_data`.
428     /// 3. Check if the return value is correct.
429     #[test]
ut_slice_reader_take_cached_data()430     fn ut_slice_reader_take_cached_data() {
431         let slice = "A";
432         let mut slice_reader = SliceReader::new(slice.as_bytes());
433         slice_reader.start_caching();
434         assert!(slice_reader.cache.is_some());
435         assert_eq!(slice_reader.take_cached_data(), Some(Vec::new()));
436         assert!(slice_reader.cache.is_none());
437     }
438 
439     /// UT test case for `SliceReader::remainder_len`.
440     ///
441     /// # Title
442     /// ut_slice_reader_remainder_len
443     ///
444     /// # Brief
445     /// 1. Create a `SliceReader`.
446     /// 2. Call `SliceReader::remainder_len`.
447     /// 3. Check if the return value is correct.
448     #[test]
ut_slice_reader_remainder_len()449     fn ut_slice_reader_remainder_len() {
450         let slice = "A";
451         let slice_reader = SliceReader::new(slice.as_bytes());
452         assert_eq!(slice_reader.remainder_len(), 1);
453     }
454 
455     /// UT test case for `SliceReader::remainder_slice`.
456     ///
457     /// # Title
458     /// ut_slice_reader_remainder_slice
459     ///
460     /// # Brief
461     /// 1. Create a `SliceReader`.
462     /// 2. Call `SliceReader::remainder_slice`.
463     /// 3. Check if the return value is correct.
464     #[test]
ut_slice_reader_remainder_slice()465     fn ut_slice_reader_remainder_slice() {
466         let slice = "A";
467         let slice_reader = SliceReader::new(slice.as_bytes());
468         assert_eq!(slice_reader.remainder_slice(), slice.as_bytes());
469     }
470 
471     /// UT test case for `SliceReader::remainder_data`.
472     ///
473     /// # Title
474     /// ut_slice_reader_remainder_slice
475     ///
476     /// # Brief
477     /// 1. Create a `SliceReader`.
478     /// 2. Call `SliceReader::remainder_slice`.
479     /// 3. Check if the return value is correct.
480     #[test]
ut_slice_reader_remainder_data()481     fn ut_slice_reader_remainder_data() {
482         let slice = "A";
483         let slice_reader = SliceReader::new(slice.as_bytes());
484         assert_eq!(slice_reader.remainder_data(), slice.as_bytes().to_vec());
485     }
486 
487     /// UT test case for `SliceReader::next_n`.
488     ///
489     /// # Title
490     /// ut_slice_reader_next_n
491     ///
492     /// # Brief
493     /// 1. Create a `SliceReader`.
494     /// 2. Call `SliceReader::next_n`.
495     /// 3. Check if the return value is correct.
496     #[test]
ut_slice_reader_next_n()497     fn ut_slice_reader_next_n() {
498         let slice = "ABC";
499         let mut slice_reader = SliceReader::new(slice.as_bytes());
500         assert_eq!(slice_reader.next_n(2).unwrap(), Some("AB".as_bytes()));
501         assert_eq!(slice_reader.next_n(2).unwrap(), None);
502     }
503 
504     /// UT test case for `SliceReader::peek_n`.
505     ///
506     /// # Title
507     /// ut_slice_reader_peek_n
508     ///
509     /// # Brief
510     /// 1. Create a `SliceReader`.
511     /// 2. Call `SliceReader::peek_n`.
512     /// 3. Check if the return value is correct.
513     #[test]
ut_slice_reader_peek_n()514     fn ut_slice_reader_peek_n() {
515         let slice = "ABC";
516         let mut slice_reader = SliceReader::new(slice.as_bytes());
517         assert_eq!(slice_reader.peek_n(2).unwrap(), Some("AB".as_bytes()));
518         assert_eq!(slice_reader.peek_n(4).unwrap(), None);
519     }
520 
521     /// UT test case for `SliceReader::discard_n`.
522     ///
523     /// # Title
524     /// ut_slice_reader_discard_n
525     ///
526     /// # Brief
527     /// 1. Create a `SliceReader`.
528     /// 2. Call `SliceReader::discard_n`.
529     /// 3. Check if the return value is correct.
530     #[test]
ut_slice_reader_discard_n()531     fn ut_slice_reader_discard_n() {
532         let slice = "ABC";
533         let mut slice_reader = SliceReader::new(slice.as_bytes());
534         slice_reader.discard_n(2);
535         assert_eq!(slice_reader.next().unwrap(), Some(b'C'));
536     }
537 }
538