| 26 | type Item = DirEntry; |
| 27 | |
| 28 | fn next(&mut self) -> Option<DirEntry> { |
| 29 | unsafe { |
| 30 | if self.buf.len() < mem::size_of::<wasip1::Dirent>() { |
| 31 | return None; |
| 32 | } |
| 33 | |
| 34 | // Read the data |
| 35 | let dirent_ptr = self.buf.as_ptr() as *const wasip1::Dirent; |
| 36 | let dirent = dirent_ptr.read_unaligned(); |
| 37 | |
| 38 | if self.buf.len() < mem::size_of::<wasip1::Dirent>() + dirent.d_namlen as usize { |
| 39 | return None; |
| 40 | } |
| 41 | |
| 42 | let name_ptr = dirent_ptr.offset(1) as *const u8; |
| 43 | // NOTE Linux syscall returns a NUL-terminated name, but WASI doesn't |
| 44 | let namelen = dirent.d_namlen as usize; |
| 45 | let slice = slice::from_raw_parts(name_ptr, namelen); |
| 46 | let name = str::from_utf8(slice).expect("invalid utf8").to_owned(); |
| 47 | |
| 48 | // Update the internal state |
| 49 | let delta = mem::size_of_val(&dirent) + namelen; |
| 50 | self.buf = &self.buf[delta..]; |
| 51 | |
| 52 | DirEntry { dirent, name }.into() |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | /// Return the entries plus a bool indicating EOF. |