|
1 | | -use std::{ffi::CString, marker::PhantomData, path::Path, ptr}; |
| 1 | +use std::{ffi::CString, marker::PhantomData, os::fd::RawFd, path::Path, ptr}; |
2 | 2 |
|
3 | 3 | use librdb_sys::{ |
4 | 4 | self, RdbHandlersDataCallbacks, RdbStatus_RDB_STATUS_ERROR, RdbStatus_RDB_STATUS_OK, |
@@ -116,6 +116,35 @@ impl<H: RdbHandlers> Parser<H> { |
116 | 116 | self.run_parse() |
117 | 117 | } |
118 | 118 |
|
| 119 | + /// Attach a file-descriptor reader and parse the RDB data. |
| 120 | + /// |
| 121 | + /// If `close_when_done` is true, librdb will close the fd after parsing. |
| 122 | + /// The fd must be in blocking mode. |
| 123 | + /// |
| 124 | + /// # Errors |
| 125 | + /// Returns an error if the reader cannot be created, the RDB data is |
| 126 | + /// malformed, or a handler callback returns `Err`. |
| 127 | + pub fn parse_fd(&mut self, fd: RawFd, close_when_done: bool) -> Result<()> { |
| 128 | + if self.parsed { |
| 129 | + return Err(RdbError::Parser { |
| 130 | + code: 0, |
| 131 | + message: "parser already used; create a new Parser instance".into(), |
| 132 | + }); |
| 133 | + } |
| 134 | + |
| 135 | + // SAFETY: self.raw is a valid parser in CONFIGURING state. The caller |
| 136 | + // is responsible for providing a valid, blocking fd. |
| 137 | + let reader = unsafe { |
| 138 | + librdb_sys::RDBX_createReaderFileDesc(self.raw, fd, i32::from(close_when_done)) |
| 139 | + }; |
| 140 | + if reader.is_null() { |
| 141 | + return Err(self.extract_c_error("RDBX_createReaderFileDesc returned null")); |
| 142 | + } |
| 143 | + |
| 144 | + self.parsed = true; |
| 145 | + self.run_parse() |
| 146 | + } |
| 147 | + |
119 | 148 | fn run_parse(&mut self) -> Result<()> { |
120 | 149 | // SAFETY: parser and reader are valid, callbacks are wired. |
121 | 150 | let status = unsafe { librdb_sys::RDB_parse(self.raw) }; |
|
0 commit comments