download-curl 0.0 → 0.1
raw patch · 3 files changed
+121/−9 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Network.Curl.Download.Lazy: openLazyURI :: String -> IO (Either String ByteString)
Files
- Network/Curl/Download.hs +8/−6
- Network/Curl/Download/Lazy.hs +109/−0
- download-curl.cabal +4/−3
Network/Curl/Download.hs view
@@ -123,15 +123,15 @@ let start = 1024 buf <- mallocBytes start- ref <- newIORef (buf, 0)+ ref <- newIORef (P buf 0) setopt h (CurlFailOnError True) setDefaultSSLOpts h url setopt h (CurlURL url) setopt h (CurlWriteFunction (gather ref)) mapM_ (setopt h) flags- rc <- perform h- (buf', sz) <- readIORef ref+ rc <- perform h+ P buf' sz <- readIORef ref if rc /= CurlOK then do@@ -141,12 +141,14 @@ fp <- newForeignPtr finalizerFree buf' return (Right $! S.fromForeignPtr fp 0 (fromIntegral sz)) -gather :: IORef (Ptr Word8, Int) -> WriteFunction+data P = P !(Ptr Word8) !Int++gather :: IORef P -> WriteFunction gather r = writer $ \(src, m) -> do- (dest, n) <- readIORef r+ P dest n <- readIORef r dest' <- reallocBytes dest (n + m) S.memcpy (dest' `plusPtr` n) src (fromIntegral m)- writeIORef r (dest', n + m)+ writeIORef r (P dest' (n + m)) -- memcpy chunks of data into our bytestring. writer :: ((Ptr Word8, Int) -> IO ()) -> WriteFunction
+ Network/Curl/Download/Lazy.hs view
@@ -0,0 +1,109 @@++--------------------------------------------------------------------+-- |+-- Module : Network.Curl.Download.Lazy+-- Copyright : (c) Don Stewart+-- License : BSD3+--+-- Maintainer: Don Stewart <dons@galois.com>+-- Stability : provisional+-- Portability: posix+--+-- A binding to curl, an efficient, high level library for+-- retrieving files using Uniform Resource Locators (URLs).+--+-- Content may be retrieved as a lazy "ByteString".+--+-- Error handling is encapsulated in the "Either" type.+--+--------------------------------------------------------------------++module Network.Curl.Download.Lazy (++ -- * The basic lazy interface to network content+ openLazyURI++ ) where++import Network.Curl+import Foreign++import Data.IORef+import Control.Monad+import Control.Monad.Instances+import System.IO++import qualified Data.ByteString.Lazy.Internal as L+import qualified Data.ByteString.Internal as S++------------------------------------------------------------------------++-- | Download content specified by a url using curl, returning the+-- content as a lazy "ByteString".+--+-- If an error occurs, "Left" is returned, with a+-- protocol-specific error string.+--+-- Examples:+--+-- > openURI "http://haskell.org"+--+openLazyURI :: String -> IO (Either String L.ByteString)+openLazyURI s = case parseURL s of+ Nothing -> return $ Left $ "Malformed url: "++ s+ Just url -> do+ e <- getFile url []+ return $ case e of+ Left err -> Left $ "Failed to connect: " ++ err+ Right src -> Right src++------------------------------------------------------------------------+-- Internal:+--++newtype URL = URL String++parseURL :: String -> Maybe URL+parseURL s = Just (URL s) -- no parsing++getFile :: URL -> [CurlOption] -> IO (Either String L.ByteString)+getFile (URL url) flags = do+ h <- initialize+ ref <- newIORef L.Empty++ setopt h (CurlFailOnError True)+ setDefaultSSLOpts h url+ setopt h (CurlURL url)+ setopt h (CurlWriteFunction (gather ref))+ mapM_ (setopt h) flags+ rc <- perform h+ chunks <- readIORef ref++ return $ if rc /= CurlOK+ then Left (show rc)+ else Right $! rev'spine chunks++-- fp <- newForeignPtr finalizerFree buf'+-- return (Right $! S.fromForeignPtr fp 0 (fromIntegral sz))++gather :: IORef L.ByteString -> WriteFunction+gather r = writer $ \chunk -> do+ chunks <- readIORef r+ let chunks' = L.Chunk chunk chunks+ writeIORef r $! chunks'++-- memcpy chunks of data into our bytestring.+writer :: (S.ByteString -> IO ()) -> WriteFunction+writer f src sz nelems _ = do+ let n' = sz * nelems+ f =<< (S.create (fromIntegral n') $+ \dest -> S.memcpy dest (castPtr src) (fromIntegral n'))+ return n'+++-- reverse just the spine of a lazy bytestring+rev'spine :: L.ByteString -> L.ByteString+rev'spine l = rev l L.Empty+ where+ rev L.Empty a = a+ rev (L.Chunk x xs) a = rev xs (L.Chunk x a)
download-curl.cabal view
@@ -1,11 +1,11 @@ name: download-curl-version: 0.0+version: 0.1 homepage: http://code.haskell.org/~dons/code/download-curl synopsis: High-level file download based on URLs description: High-level file download based on URLs .- Download web content as strict bytestring, strings, HTML tags, XML, RSS- or Atom feeds or JSON, using the curl network library.+ Download web content as strict or lazy bytestringrs, strings, HTML+ tags, XML, RSS or Atom feeds or JSON, using the curl network library. . Importing the library: . @@ -49,6 +49,7 @@ library exposed-modules: Network.Curl.Download+ Network.Curl.Download.Lazy ghc-options: -Wall if flag(small_base)