-- 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 FFIResult a = FFIResult
  { forall a. FFIResult a -> CUInt
ffiCode :: CUInt,
    forall a. FFIResult a -> Ptr a
dataPtr :: Ptr a,
    forall a. FFIResult a -> CString
errorMessage :: CString
  }
  deriving (Int -> FFIResult a -> ShowS
forall a. Int -> FFIResult a -> ShowS
forall a. [FFIResult a] -> ShowS
forall a. FFIResult a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FFIResult a] -> ShowS
$cshowList :: forall a. [FFIResult a] -> ShowS
show :: FFIResult a -> String
$cshow :: forall a. FFIResult a -> String
showsPrec :: Int -> FFIResult a -> ShowS
$cshowsPrec :: forall a. Int -> FFIResult a -> ShowS
Show)

instance Storable (FFIResult a) where
  sizeOf :: FFIResult a -> Int
sizeOf FFIResult a
_ = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize) forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr ()) forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
  alignment :: FFIResult a -> Int
alignment FFIResult a
_ = forall a. Storable a => a -> Int
alignment (forall a. HasCallStack => a
undefined :: CSize)
  peek :: Ptr (FFIResult a) -> IO (FFIResult a)
peek Ptr (FFIResult a)
ptr = do
    CUInt
s <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (FFIResult a)
ptr Int
codeOffset
    Ptr a
d <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (FFIResult a)
ptr Int
dataPtrOffset
    CString
errMsg <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (FFIResult a)
ptr Int
errorMessageOffset
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. CUInt -> Ptr a -> CString -> FFIResult a
FFIResult CUInt
s Ptr a
d CString
errMsg
    where
      codeOffset :: Int
codeOffset = Int
0
      dataPtrOffset :: Int
dataPtrOffset = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize)
      errorMessageOffset :: Int
errorMessageOffset = Int
dataPtrOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr ())
  poke :: Ptr (FFIResult a) -> FFIResult a -> IO ()
poke Ptr (FFIResult a)
ptr (FFIResult CUInt
s Ptr a
d CString
errMsg) = do
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (FFIResult a)
ptr Int
codeOffset CUInt
s
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (FFIResult a)
ptr Int
dataPtrOffset Ptr a
d
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (FFIResult a)
ptr Int
errorMessageOffset CString
errMsg
    where
      codeOffset :: Int
codeOffset = Int
0
      dataPtrOffset :: Int
dataPtrOffset = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize)
      errorMessageOffset :: Int
errorMessageOffset = Int
dataPtrOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr ())

data ByteSlice = ByteSlice
  { ByteSlice -> CString
bsData :: Ptr CChar,
    ByteSlice -> CSize
bsLen :: CSize
  }

instance Storable ByteSlice where
  sizeOf :: ByteSlice -> Int
sizeOf ByteSlice
_ = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr CChar) forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize)
  alignment :: ByteSlice -> Int
alignment ByteSlice
_ = forall a. Storable a => a -> Int
alignment (forall a. HasCallStack => a
undefined :: CSize)
  peek :: Ptr ByteSlice -> IO ByteSlice
peek Ptr ByteSlice
ptr = do
    CString
bsDataPtr <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr ByteSlice
ptr Int
dataOffset
    CSize
len <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr ByteSlice
ptr Int
lenOffset
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ CString -> CSize -> ByteSlice
ByteSlice CString
bsDataPtr CSize
len
    where
      dataOffset :: Int
dataOffset = Int
0
      lenOffset :: Int
lenOffset = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr ())
  poke :: Ptr ByteSlice -> ByteSlice -> IO ()
poke Ptr ByteSlice
ptr (ByteSlice CString
bsDataPtr CSize
len) = do
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr ByteSlice
ptr Int
dataOffset CString
bsDataPtr
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr ByteSlice
ptr Int
lenOffset CSize
len
    where
      dataOffset :: Int
dataOffset = Int
0
      lenOffset :: Int
lenOffset = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: Ptr ())

data FFIMetadata = FFIMetadata
  { FFIMetadata -> CUInt
ffiMode :: CUInt,
    FFIMetadata -> CString
ffiCacheControl :: CString,
    FFIMetadata -> CString
ffiContentDisposition :: CString,
    FFIMetadata -> CULong
ffiContentLength :: CULong,
    FFIMetadata -> CString
ffiContentMD5 :: CString,
    FFIMetadata -> CString
ffiContentType :: CString,
    FFIMetadata -> CString
ffiETag :: CString,
    FFIMetadata -> CString
ffiLastModified :: CString
  }
  deriving (Int -> FFIMetadata -> ShowS
[FFIMetadata] -> ShowS
FFIMetadata -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FFIMetadata] -> ShowS
$cshowList :: [FFIMetadata] -> ShowS
show :: FFIMetadata -> String
$cshow :: FFIMetadata -> String
showsPrec :: Int -> FFIMetadata -> ShowS
$cshowsPrec :: Int -> FFIMetadata -> ShowS
Show)

instance Storable FFIMetadata where
  sizeOf :: FFIMetadata -> Int
sizeOf FFIMetadata
_ = forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize) forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString) forall a. Num a => a -> a -> a
* Int
6 forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CULong)
  alignment :: FFIMetadata -> Int
alignment FFIMetadata
_ = forall a. Storable a => a -> Int
alignment (forall a. HasCallStack => a
undefined :: CSize)
  peek :: Ptr FFIMetadata -> IO FFIMetadata
peek Ptr FFIMetadata
ptr = do
    CUInt
mode <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
modeOffset
    CString
cacheControl <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
cacheControlOffset
    CString
contentDisposition <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
contentDispositionOffset
    CULong
contentLength <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
contentLengthOffset
    CString
contentMD5 <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
contentMD5Offset
    CString
contentType <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
contentTypeOffset
    CString
eTag <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
eTagOffset
    CString
lastModified <- forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr FFIMetadata
ptr Int
lastModifiedOffset
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ CUInt
-> CString
-> CString
-> CULong
-> CString
-> CString
-> CString
-> CString
-> FFIMetadata
FFIMetadata CUInt
mode CString
cacheControl CString
contentDisposition CULong
contentLength CString
contentMD5 CString
contentType CString
eTag CString
lastModified
    where
      modeOffset :: Int
modeOffset = Int
0
      cacheControlOffset :: Int
cacheControlOffset = Int
modeOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize)
      contentDispositionOffset :: Int
contentDispositionOffset = Int
cacheControlOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      contentLengthOffset :: Int
contentLengthOffset = Int
contentDispositionOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      contentMD5Offset :: Int
contentMD5Offset = Int
contentLengthOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CULong)
      contentTypeOffset :: Int
contentTypeOffset = Int
contentMD5Offset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      eTagOffset :: Int
eTagOffset = Int
contentTypeOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      lastModifiedOffset :: Int
lastModifiedOffset = Int
eTagOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
  poke :: Ptr FFIMetadata -> FFIMetadata -> IO ()
poke Ptr FFIMetadata
ptr (FFIMetadata CUInt
mode CString
cacheControl CString
contentDisposition CULong
contentLength CString
contentMD5 CString
contentType CString
eTag CString
lastModified) = do
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
modeOffset CUInt
mode
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
cacheControlOffset CString
cacheControl
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
contentDispositionOffset CString
contentDisposition
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
contentLengthOffset CULong
contentLength
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
contentMD5Offset CString
contentMD5
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
contentTypeOffset CString
contentType
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
eTagOffset CString
eTag
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr FFIMetadata
ptr Int
lastModifiedOffset CString
lastModified
    where
      modeOffset :: Int
modeOffset = Int
0
      cacheControlOffset :: Int
cacheControlOffset = Int
modeOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CSize)
      contentDispositionOffset :: Int
contentDispositionOffset = Int
cacheControlOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      contentLengthOffset :: Int
contentLengthOffset = Int
contentDispositionOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      contentMD5Offset :: Int
contentMD5Offset = Int
contentLengthOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CULong)
      contentTypeOffset :: Int
contentTypeOffset = Int
contentMD5Offset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      eTagOffset :: Int
eTagOffset = Int
contentTypeOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CString)
      lastModifiedOffset :: Int
lastModifiedOffset = Int
eTagOffset forall a. Num a => a -> a -> a
+ forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
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 ())