module Database.TokyoCabinet.List ( new , new2 , copy , delete , len , get , push , pop , unshift , shift , insert , remove , over , sort , lsearch , bsearch , clear , dump , load , List ) where import Foreign.Ptr import Foreign.ForeignPtr import Foreign.Storable (peek) import Foreign.Marshal (alloca, free, mallocBytes) import Foreign.Marshal.Utils (maybePeek, copyBytes) import Database.TokyoCabinet.List.C import Database.TokyoCabinet.Storable import Data.ByteString.Unsafe import qualified Data.ByteString as B new :: IO (List a) new = c_tclistnew >>= newForeignPtr tclistFinalizer >>= return . List new2 :: Int -> IO (List a) new2 n = do l <- c_tclistnew2 (fromIntegral n) p <- newForeignPtr tclistFinalizer l return $ List p copy :: List a -> IO (List a) copy tcls = withForeignPtr (unTCList tcls) $ \p -> do l <- c_tclistdup p List `fmap` newForeignPtr tclistFinalizer l delete :: List a -> IO () delete tcls = finalizeForeignPtr (unTCList tcls) len :: List a -> IO Int len tcls = withForeignPtr (unTCList tcls) $ \p -> do n <- c_tclistnum p return $ fromIntegral n get :: (Storable a) => List a -> Int -> IO (Maybe a) get tcls index = withForeignPtr (unTCList tcls) $ \p -> alloca $ \sizbuf -> do vbuf <- c_tclistval p (fromIntegral index) sizbuf flip maybePeek vbuf $ \vp -> do siz <- peek sizbuf buf <- mallocBytes (fromIntegral siz) copyBytes buf vp (fromIntegral siz) peekPtrLen (buf, fromIntegral siz) push :: (Storable a) => List a -> a -> IO () push tcls val = withForeignPtr (unTCList tcls) $ \p -> withPtrLen val $ \(vbuf, vsiz) -> c_tclistpush p (castPtr vbuf) (fromIntegral vsiz) pop :: (Storable a) => List a -> IO (Maybe a) pop tcls = withForeignPtr (unTCList tcls) $ \p -> alloca $ \sizbuf -> do vbuf <- c_tclistpop p sizbuf flip maybePeek vbuf $ \vp -> do siz <- peek sizbuf peekPtrLen (vp, fromIntegral siz) unshift :: (Storable a) => List a -> a -> IO () unshift tcls val = withForeignPtr (unTCList tcls) $ \p -> withPtrLen val $ \(vbuf, vsiz) -> c_tclistunshift p (castPtr vbuf) (fromIntegral vsiz) shift :: (Storable a) => List a -> IO (Maybe a) shift tcls = withForeignPtr (unTCList tcls) $ \p -> alloca $ \sizbuf -> do vbuf <- c_tclistshift p sizbuf flip maybePeek vbuf $ \vp -> do siz <- peek sizbuf peekPtrLen (vp, fromIntegral siz) insert :: (Storable a) => List a -> Int -> a -> IO () insert tcls index val = withForeignPtr (unTCList tcls) $ \p -> withPtrLen val $ \(vbuf, vsiz) -> c_tclistinsert p (fromIntegral index) (castPtr vbuf) (fromIntegral vsiz) remove :: (Storable a) => List a -> Int -> IO (Maybe a) remove tcls index = withForeignPtr (unTCList tcls) $ \p -> alloca $ \sizbuf -> do vbuf <- c_tclistremove p (fromIntegral index) sizbuf flip maybePeek vbuf $ \vp -> do siz <- peek sizbuf peekPtrLen (vp, fromIntegral siz) over :: (Storable a) => List a -> Int -> a -> IO () over tcls index val = withForeignPtr (unTCList tcls) $ \p -> withPtrLen val $ \(vbuf, vsiz) -> c_tclistover p (fromIntegral index) (castPtr vbuf) (fromIntegral vsiz) sort :: List a -> IO () sort tcls = withForeignPtr (unTCList tcls) c_tclistsort lsearch :: (Storable a) => List a -> a -> IO Int lsearch tcls key = withForeignPtr (unTCList tcls) $ \p -> withPtrLen key $ \(kbuf, ksiz) -> fmap fromIntegral $ c_tclistlsearch p (castPtr kbuf) (fromIntegral ksiz) bsearch :: (Storable a) => List a -> a -> IO Int bsearch tcls key = withForeignPtr (unTCList tcls) $ \p -> withPtrLen key $ \(kbuf, ksiz) -> fmap fromIntegral $ c_tclistbsearch p (castPtr kbuf) (fromIntegral ksiz) clear :: List a -> IO () clear tcls = withForeignPtr (unTCList tcls) c_tclistclear dump :: List a -> IO B.ByteString dump tcls = withForeignPtr (unTCList tcls) $ \p -> alloca $ \sizbuf -> do c_str <- c_tclistdump p sizbuf size <- fromIntegral `fmap` peek sizbuf unsafePackCStringFinalizer (castPtr c_str) size (free c_str) load :: B.ByteString -> IO (List a) load bytes = unsafeUseAsCStringLen bytes $ \(buf, siz) -> do tclis <- c_tclistload (castPtr buf) (fromIntegral siz) List `fmap` newForeignPtr tclistFinalizer tclis