| -- Licensed to the Apache Software Foundation (ASF) under one |
| -- or more contributor license agreements. See the NOTICE file |
| -- distributed with this work for additional information |
| -- regarding copyright ownership. The ASF licenses this file |
| -- to you under the Apache License, Version 2.0 (the |
| -- "License"); you may not use this file except in compliance |
| -- with the License. You may obtain a copy of the License at |
| -- |
| -- http://www.apache.org/licenses/LICENSE-2.0 |
| -- |
| -- Unless required by applicable law or agreed to in writing, |
| -- software distributed under the License is distributed on an |
| -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| -- KIND, either express or implied. See the License for the |
| -- specific language governing permissions and limitations |
| -- under the License. |
| |
| module OpenDAL.FFI where |
| |
| import Foreign |
| import Foreign.C.String |
| import Foreign.C.Types |
| |
| data RawOperator |
| |
| data RawLister |
| |
| data RawWriter |
| |
| data FFIResult a = FFIResult |
| { ffiCode :: CUInt, |
| dataPtr :: Ptr a, |
| errorMessage :: CString |
| } |
| deriving (Show) |
| |
| instance Storable (FFIResult a) where |
| sizeOf _ = sizeOf (undefined :: CSize) + sizeOf (undefined :: Ptr ()) + sizeOf (undefined :: CString) |
| alignment _ = alignment (undefined :: CSize) |
| peek ptr = do |
| s <- peekByteOff ptr codeOffset |
| d <- peekByteOff ptr dataPtrOffset |
| errMsg <- peekByteOff ptr errorMessageOffset |
| return $ FFIResult s d errMsg |
| where |
| codeOffset = 0 |
| dataPtrOffset = sizeOf (undefined :: CSize) |
| errorMessageOffset = dataPtrOffset + sizeOf (undefined :: Ptr ()) |
| poke ptr (FFIResult s d errMsg) = do |
| pokeByteOff ptr codeOffset s |
| pokeByteOff ptr dataPtrOffset d |
| pokeByteOff ptr errorMessageOffset errMsg |
| where |
| codeOffset = 0 |
| dataPtrOffset = sizeOf (undefined :: CSize) |
| errorMessageOffset = dataPtrOffset + sizeOf (undefined :: Ptr ()) |
| |
| data ByteSlice = ByteSlice |
| { bsData :: Ptr CChar, |
| bsLen :: CSize |
| } |
| |
| instance Storable ByteSlice where |
| sizeOf _ = sizeOf (undefined :: Ptr CChar) + sizeOf (undefined :: CSize) |
| alignment _ = alignment (undefined :: CSize) |
| peek ptr = do |
| bsDataPtr <- peekByteOff ptr dataOffset |
| len <- peekByteOff ptr lenOffset |
| return $ ByteSlice bsDataPtr len |
| where |
| dataOffset = 0 |
| lenOffset = sizeOf (undefined :: Ptr ()) |
| poke ptr (ByteSlice bsDataPtr len) = do |
| pokeByteOff ptr dataOffset bsDataPtr |
| pokeByteOff ptr lenOffset len |
| where |
| dataOffset = 0 |
| lenOffset = sizeOf (undefined :: Ptr ()) |
| |
| data FFIMetadata = FFIMetadata |
| { ffiMode :: CUInt, |
| ffiCacheControl :: CString, |
| ffiContentDisposition :: CString, |
| ffiContentLength :: CULong, |
| ffiContentMD5 :: CString, |
| ffiContentType :: CString, |
| ffiETag :: CString, |
| ffiLastModified :: CString |
| } |
| deriving (Show) |
| |
| instance Storable FFIMetadata where |
| sizeOf _ = sizeOf (undefined :: CSize) + sizeOf (undefined :: CString) * 6 + sizeOf (undefined :: CULong) |
| alignment _ = alignment (undefined :: CSize) |
| peek ptr = do |
| mode <- peekByteOff ptr modeOffset |
| cacheControl <- peekByteOff ptr cacheControlOffset |
| contentDisposition <- peekByteOff ptr contentDispositionOffset |
| contentLength <- peekByteOff ptr contentLengthOffset |
| contentMD5 <- peekByteOff ptr contentMD5Offset |
| contentType <- peekByteOff ptr contentTypeOffset |
| eTag <- peekByteOff ptr eTagOffset |
| lastModified <- peekByteOff ptr lastModifiedOffset |
| return $ FFIMetadata mode cacheControl contentDisposition contentLength contentMD5 contentType eTag lastModified |
| where |
| modeOffset = 0 |
| cacheControlOffset = modeOffset + sizeOf (undefined :: CSize) |
| contentDispositionOffset = cacheControlOffset + sizeOf (undefined :: CString) |
| contentLengthOffset = contentDispositionOffset + sizeOf (undefined :: CString) |
| contentMD5Offset = contentLengthOffset + sizeOf (undefined :: CULong) |
| contentTypeOffset = contentMD5Offset + sizeOf (undefined :: CString) |
| eTagOffset = contentTypeOffset + sizeOf (undefined :: CString) |
| lastModifiedOffset = eTagOffset + sizeOf (undefined :: CString) |
| poke ptr (FFIMetadata mode cacheControl contentDisposition contentLength contentMD5 contentType eTag lastModified) = do |
| pokeByteOff ptr modeOffset mode |
| pokeByteOff ptr cacheControlOffset cacheControl |
| pokeByteOff ptr contentDispositionOffset contentDisposition |
| pokeByteOff ptr contentLengthOffset contentLength |
| pokeByteOff ptr contentMD5Offset contentMD5 |
| pokeByteOff ptr contentTypeOffset contentType |
| pokeByteOff ptr eTagOffset eTag |
| pokeByteOff ptr lastModifiedOffset lastModified |
| where |
| modeOffset = 0 |
| cacheControlOffset = modeOffset + sizeOf (undefined :: CSize) |
| contentDispositionOffset = cacheControlOffset + sizeOf (undefined :: CString) |
| contentLengthOffset = contentDispositionOffset + sizeOf (undefined :: CString) |
| contentMD5Offset = contentLengthOffset + sizeOf (undefined :: CULong) |
| contentTypeOffset = contentMD5Offset + sizeOf (undefined :: CString) |
| eTagOffset = contentTypeOffset + sizeOf (undefined :: CString) |
| lastModifiedOffset = eTagOffset + sizeOf (undefined :: CString) |
| |
| foreign import ccall "via_map_ffi" |
| c_via_map_ffi :: |
| CString -> Ptr CString -> Ptr CString -> CSize -> FunPtr (CUInt -> CString -> IO ()) -> Ptr (FFIResult RawOperator) -> IO () |
| |
| foreign import ccall "wrapper" |
| wrapLogFn :: (CUInt -> CString -> IO ()) -> IO (FunPtr (CUInt -> CString -> IO ())) |
| |
| foreign import ccall "&free_operator" c_free_operator :: FunPtr (Ptr RawOperator -> IO ()) |
| |
| foreign import ccall "free_byteslice" c_free_byteslice :: Ptr CChar -> CSize -> IO () |
| |
| foreign import ccall "blocking_read" c_blocking_read :: Ptr RawOperator -> CString -> Ptr (FFIResult ByteSlice) -> IO () |
| |
| foreign import ccall "blocking_write" c_blocking_write :: Ptr RawOperator -> CString -> Ptr CChar -> CSize -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "blocking_is_exist" c_blocking_is_exist :: Ptr RawOperator -> CString -> Ptr (FFIResult CBool) -> IO () |
| |
| foreign import ccall "blocking_create_dir" c_blocking_create_dir :: Ptr RawOperator -> CString -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "blocking_copy" c_blocking_copy :: Ptr RawOperator -> CString -> CString -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "blocking_rename" c_blocking_rename :: Ptr RawOperator -> CString -> CString -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "blocking_delete" c_blocking_delete :: Ptr RawOperator -> CString -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "blocking_stat" c_blocking_stat :: Ptr RawOperator -> CString -> Ptr (FFIResult FFIMetadata) -> IO () |
| |
| foreign import ccall "blocking_list" c_blocking_list :: Ptr RawOperator -> CString -> Ptr (FFIResult (Ptr RawLister)) -> IO () |
| |
| foreign import ccall "blocking_scan" c_blocking_scan :: Ptr RawOperator -> CString -> Ptr (FFIResult (Ptr RawLister)) -> IO () |
| |
| foreign import ccall "lister_next" c_lister_next :: Ptr RawLister -> Ptr (FFIResult CString) -> IO () |
| |
| foreign import ccall "&free_lister" c_free_lister :: FunPtr (Ptr RawLister -> IO ()) |
| |
| |
| foreign import ccall "operator_info" c_operator_info :: Ptr RawOperator -> Ptr (FFIResult CString) -> IO () |
| |
| foreign import ccall "blocking_writer" c_blocking_writer :: Ptr RawOperator -> CString -> Ptr (FFIResult (Ptr RawWriter)) -> IO () |
| |
| foreign import ccall "blocking_writer_append" c_blocking_writer_append :: Ptr RawOperator -> CString -> Ptr (FFIResult (Ptr RawWriter)) -> IO () |
| |
| foreign import ccall "writer_write" c_writer_write :: Ptr RawWriter -> Ptr CChar -> CSize -> Ptr (FFIResult ()) -> IO () |
| |
| foreign import ccall "writer_close" c_writer_close :: Ptr RawWriter -> Ptr (FFIResult FFIMetadata) -> IO () |
| |
| foreign import ccall "&free_writer" c_free_writer :: FunPtr (Ptr RawWriter -> IO ()) |
| |
| foreign import ccall "blocking_remove_all" c_blocking_remove_all :: Ptr RawOperator -> CString -> Ptr (FFIResult ()) -> IO () |