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