taoseng commented on issue #6083:
URL: https://github.com/apache/opendal/issues/6083#issuecomment-2833257615

   I created a prototype locally, which is roughly structured as follows:
   ```diff
   diff --git a/bindings/c/src/reader.rs b/bindings/c/src/reader.rs
   index 1c34658e..4e56403b 100644
   --- a/bindings/c/src/reader.rs
   +++ b/bindings/c/src/reader.rs
   @@ -16,12 +16,16 @@
    // under the License.
    
    use std::ffi::c_void;
   -use std::io::Read;
   +use std::io::{Read, Seek, SeekFrom};
    
    use ::opendal as core;
    
    use super::*;
    
   +pub const OPENDAL_SEEK_SET: i32 = 0;
   +pub const OPENDAL_SEEK_CUR: i32 = 1;
   +pub const OPENDAL_SEEK_END: i32 = 2;
   +
    /// \brief The result type returned by opendal's reader operation.
    ///
    /// \note The opendal_reader actually owns a pointer to
   @@ -72,6 +76,33 @@ impl opendal_reader {
            }
        }
    
   +    /// \brief Seek to an offset, in bytes, in a stream.
   +    #[no_mangle]
   +    pub unsafe extern "C" fn opendal_reader_seek(
   +        &mut self,
   +        offset: i64,
   +        whence: i32,
   +    ) -> *mut opendal_error {
   +        let pos = match whence {
   +            _x @ OPENDAL_SEEK_SET => SeekFrom::Start(offset as u64),
   +            _x @ OPENDAL_SEEK_CUR => SeekFrom::Current(offset),
   +            _x @ OPENDAL_SEEK_END => SeekFrom::End(offset),
   +            _ => {
   +                return opendal_error::new(core::Error::new(
   +                    core::ErrorKind::Unexpected,
   +                    "undefined whence",
   +                ))
   +            }
   +        };
   +
   +        match self.deref_mut().seek(pos) {
   +            Ok(_) => std::ptr::null_mut(),
   +            Err(e) => {
   +                
opendal_error::new(core::Error::new(core::ErrorKind::Unexpected, e.to_string()))
   +            }
   +        }
   +    }
   +
        /// \brief Frees the heap memory used by the opendal_reader.
        #[no_mangle]
        pub unsafe extern "C" fn opendal_reader_free(ptr: *mut opendal_reader) {
   ```
   
   Explanation of the Code:
   ​​1. Why are OPENDAL_SEEK_SET, OPENDAL_SEEK_CUR, and OPENDAL_SEEK_END 
defined separately?​​
   These macros are defined to generate corresponding #define definitions in C.
   Why assign specific values here instead of directly using the definitions 
from <stdio.h>?
   I noticed that the C standard does not define the numerical values for these 
three macros; it only defines their names. This makes me worry about potential 
cross-platform issues.
   ​​
   2. 
   3. Why is an unused _x used in the match statement?​​The reason is that I 
discovered a pitfall in Rust's match when matching against constants.
   You can actually delete the constant definitions for OPENDAL_SEEK_SET, 
OPENDAL_SEEK_CUR, and OPENDAL_SEEK_END, and the match below will ​​not​​ raise 
an error!
   The compiler will treat OPENDAL_SEEK_SET, OPENDAL_SEEK_CUR, and 
OPENDAL_SEEK_END as variable names, which is extremely dangerous. I once 
encountered a bug because of this issue.
   
   I’d love to hear your thoughts. This is my first time contributing a PR, so 
I have quite a few concerns.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to