Z-IO 0.1.1.1 → 0.1.1.2
raw patch · 17 files changed
+896/−216 lines, 17 filesdep −integer-gmpdep −integer-simplePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: integer-gmp, integer-simple
API changes (from Hackage documentation)
+ Z.IO.Network.TCP: initTCPStream :: HasCallStack => UVManager -> Resource UVStream
+ Z.IO.Network.TCP: setTCPKeepAlive :: HasCallStack => UVStream -> CUInt -> IO ()
+ Z.IO.Network.TCP: setTCPNoDelay :: HasCallStack => UVStream -> Bool -> IO ()
+ Z.IO.UV.FFI: hs_uv_udp_send_connected :: Ptr UVHandle -> Ptr Word8 -> Int -> IO UVSlotUnSafe
+ Z.IO.UV.FFI: uv_udp_disconnect :: Ptr UVHandle -> Ptr SocketAddr -> IO CInt
- Z.Compression.Zlib: compress :: CompressConfig -> Bytes -> Bytes
+ Z.Compression.Zlib: compress :: HasCallStack => CompressConfig -> Bytes -> Bytes
- Z.Compression.Zlib: decompress :: DecompressConfig -> Bytes -> Bytes
+ Z.Compression.Zlib: decompress :: HasCallStack => DecompressConfig -> Bytes -> Bytes
- Z.IO.UV.FFI: hs_uv_tcp_connect :: Ptr UVHandle -> Ptr SocketAddr -> IO UVSlotUnSafe
+ Z.IO.UV.FFI: hs_uv_tcp_connect :: Ptr UVHandle -> MBA# SocketAddr -> IO UVSlotUnSafe
- Z.IO.UV.FFI: hs_uv_udp_send :: Ptr UVHandle -> Ptr SocketAddr -> Ptr Word8 -> Int -> IO UVSlotUnSafe
+ Z.IO.UV.FFI: hs_uv_udp_send :: Ptr UVHandle -> MBA# SocketAddr -> Ptr Word8 -> Int -> IO UVSlotUnSafe
- Z.IO.UV.FFI: uv_tcp_bind :: Ptr UVHandle -> Ptr SocketAddr -> CUInt -> IO CInt
+ Z.IO.UV.FFI: uv_tcp_bind :: Ptr UVHandle -> MBA# SocketAddr -> CUInt -> IO CInt
- Z.IO.UV.FFI: uv_tcp_getpeername :: Ptr UVHandle -> Ptr SocketAddr -> CInt -> IO CInt
+ Z.IO.UV.FFI: uv_tcp_getpeername :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
- Z.IO.UV.FFI: uv_tcp_getsockname :: Ptr UVHandle -> Ptr SocketAddr -> CInt -> IO CInt
+ Z.IO.UV.FFI: uv_tcp_getsockname :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
- Z.IO.UV.FFI: uv_udp_bind :: Ptr UVHandle -> Ptr SocketAddr -> UVUDPFlag -> IO CInt
+ Z.IO.UV.FFI: uv_udp_bind :: Ptr UVHandle -> MBA# SocketAddr -> UVUDPFlag -> IO CInt
- Z.IO.UV.FFI: uv_udp_connect :: Ptr UVHandle -> Ptr SocketAddr -> IO CInt
+ Z.IO.UV.FFI: uv_udp_connect :: Ptr UVHandle -> MBA# SocketAddr -> IO CInt
- Z.IO.UV.FFI: uv_udp_getpeername :: Ptr UVHandle -> Ptr SocketAddr -> MBA# CInt -> IO CInt
+ Z.IO.UV.FFI: uv_udp_getpeername :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
- Z.IO.UV.FFI: uv_udp_getsockname :: Ptr UVHandle -> Ptr SocketAddr -> MBA# CInt -> IO CInt
+ Z.IO.UV.FFI: uv_udp_getsockname :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
Files
- ChangeLog.md +5/−0
- README.md +3/−1
- Z-IO.cabal +12/−35
- Z/Compression/Zlib.hsc +2/−2
- Z/IO/Network/IPC.hs +44/−40
- Z/IO/Network/SocketAddr.hsc +10/−3
- Z/IO/Network/TCP.hs +57/−50
- Z/IO/Network/UDP.hs +27/−23
- Z/IO/UV/FFI.hsc +13/−8
- Z/IO/UV/Manager.hs +1/−0
- cbits/hs_uv_udp.c +5/−0
- include/hs_uv.h +1/−0
- test/Z/Compression/ZlibSpec.hs +77/−0
- test/Z/IO/Network/TCPSpec.hs +52/−0
- test/Z/IO/Network/UDPSpec.hs +53/−0
- test/Z/IO/UDPSpec.hs +0/−54
- third_party/zlib/zconf.h +534/−0
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for Z-IO +## 0.1.1.2 -- 2020-09-25++* Fix macOS build problem caused by missing zconf.h.+* Add more tests(TCP, IPC).+ ## 0.1.1.0 -- 2020-09-19 * Add stream utilities to `Z.IO.Buffered`.
README.md view
@@ -4,7 +4,9 @@ ## Z-IO -[](https://travis-ci.org/haskell-z/z-io)+[](https://github.com/haskell-Z/z-io/actions)++[](https://github.com/haskell-Z/z-io/actions) This package provides basic IO operations:
Z-IO.cabal view
@@ -1,5 +1,5 @@ name: Z-IO-version: 0.1.1.1+version: 0.1.1.2 synopsis: Simple and high performance IO toolkit for Haskell description: Simple and high performance IO toolkit for Haskell, including file system, network, ipc and more!@@ -19,13 +19,6 @@ README.md LICENSE - include/hs_uv.h- cbits/hs_uv_base.c- cbits/hs_uv_stream.c- cbits/hs_uv_udp.c- cbits/hs_uv_file.c- cbits/hs_uv_dns.c- -- zlib C sources third_party/zlib/crc32.h third_party/zlib/inffast.h @@ -103,13 +96,6 @@ default: False manual: True -flag integer-simple- description:- Use the [simple integer library](http://hackage.haskell.org/package/integer-simple)- instead of [integer-gmp](http://hackage.haskell.org/package/integer-gmp)- default: False- manual: False- library exposed-modules: Z.IO.FileSystem Z.IO.FileSystem.Threaded@@ -141,27 +127,23 @@ , time >= 1.8 && < 2.0 , stm == 2.5.* - if flag(integer-simple)- cpp-options: -DINTEGER_SIMPLE- build-depends: integer-simple >= 0.1 && < 0.5- else- cpp-options: -DINTEGER_GMP- build-depends: integer-gmp >= 0.2 && < 1.1- include-dirs: include third_party/zlib includes: hs_uv.h+ zlib.h+ zconf.h install-includes: hs_uv.h zlib.h+ zconf.h cc-options: -march=native c-sources: cbits/hs_uv_base.c+ cbits/hs_uv_dns.c+ cbits/hs_uv_file.c cbits/hs_uv_stream.c cbits/hs_uv_udp.c- cbits/hs_uv_file.c- cbits/hs_uv_dns.c cbits/hs_zlib.c third_party/zlib/adler32.c@@ -237,7 +219,7 @@ if flag(no-pkg-config) extra-libraries: uv else- pkgconfig-depends: libuv >= 1.14+ pkgconfig-depends: libuv >= 1.32 default-language: Haskell2010 build-tools: hsc2hs, hspec-discover@@ -261,19 +243,14 @@ , zlib , bytestring - other-modules: Z.IO.FileSystemSpec+ other-modules: Z.Compression.ZlibSpec Z.IO.FileSystem.ThreadedSpec+ Z.IO.FileSystemSpec+ Z.IO.Network.UDPSpec+ Z.IO.Network.TCPSpec+ -- Z.IO.Network.IPCSpec Z.IO.LowResTimerSpec Z.IO.ResourceSpec- Z.IO.UDPSpec ghc-options: -threaded default-language: Haskell2010-- if flag(integer-simple)- cpp-options: -DINTEGER_SIMPLE- build-depends: integer-simple >= 0.1 && < 0.5- else- cpp-options: -DINTEGER_GMP- build-depends: integer-gmp >= 0.2 && < 1.1-
Z/Compression/Zlib.hsc view
@@ -167,7 +167,7 @@ zflush zs bufRef -- | Compress some bytes.-compress :: CompressConfig -> V.Bytes -> V.Bytes+compress :: HasCallStack => CompressConfig -> V.Bytes -> V.Bytes compress conf input = unsafePerformIO $ do ref <- newIORef [] (write, flush) <- compressSink conf (\ x -> modifyIORef' ref (x:), return ())@@ -266,7 +266,7 @@ -- | Decompress some bytes.-decompress :: DecompressConfig -> V.Bytes -> V.Bytes+decompress :: HasCallStack => DecompressConfig -> V.Bytes -> V.Bytes decompress conf input = V.concat . unsafePerformIO $ do collectSource =<< decompressSource conf =<< sourceFromList [input]
Z/IO/Network/IPC.hs view
@@ -68,12 +68,13 @@ uvm <- liftIO getUVManager client <- initIPCStream uvm let hdl = uvsHandle client- liftIO . withCBytes tname $ \ tname_p -> do+ liftIO $ do forM_ cname $ \ cname' -> withCBytes cname' $ \ cname_p -> -- bind is safe without withUVManager throwUVIfMinus_ (uv_pipe_bind hdl cname_p)- void . withUVRequest uvm $ \ _ -> hs_uv_pipe_connect hdl tname_p+ withCBytes tname $ \ tname_p -> do+ void . withUVRequest uvm $ \ _ -> hs_uv_pipe_connect hdl tname_p return client --------------------------------------------------------------------------------@@ -105,11 +106,14 @@ startIPCServer IPCServerConfig{..} = do let backLog = max ipcListenBacklog 128 serverUVManager <- getUVManager- withResource (initIPCStream serverUVManager) $ \ (UVStream serverHandle serverSlot _ _) ->+ withResource (initIPCStream serverUVManager) $ \ (UVStream serverHandle serverSlot _ _) -> do+ withCBytes ipcListenName $ \ name_p -> do+ throwUVIfMinus_ (uv_pipe_bind serverHandle name_p) bracket (throwOOMIfNull $ hs_uv_accept_check_alloc serverHandle) hs_uv_accept_check_close $ \ check -> do+ -- The buffer passing of accept is a litte complicated here, to get maximum performance, -- we do batch accepting. i.e. recv multiple client inside libuv's event loop: --@@ -127,51 +131,51 @@ -- we allocate a new uv_check_t for given uv_stream_t, with predefined checking callback -- see hs_accept_check_cb in hs_uv_stream.c throwUVIfMinus_ $ hs_uv_accept_check_init check- withCBytes ipcListenName $ \ name_p -> do- m <- getBlockMVar serverUVManager serverSlot- acceptBuf <- newPinnedPrimArray backLog- let acceptBufPtr = coerce (mutablePrimArrayContents acceptBuf :: Ptr UVFD)+ m <- getBlockMVar serverUVManager serverSlot -- Step 2. -- we allocate a buffer to hold accepted FDs, pass it just like a normal reading buffer.- withUVManager' serverUVManager $ do- -- We use buffersize as accepted fd counter, so we write 0 here- pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)- throwUVIfMinus_ (uv_pipe_bind serverHandle name_p)- throwUVIfMinus_ (hs_uv_listen serverHandle (max 4 (fromIntegral backLog)))+-- then we can start listening.+ acceptBuf <- newPinnedPrimArray backLog+ let acceptBufPtr = coerce (mutablePrimArrayContents acceptBuf :: Ptr UVFD) - forever $ do- -- wait until accept some FDs- !acceptCountDown <- takeMVar m+ withUVManager' serverUVManager $ do+ -- We use buffersize as accepted fd counter, so we write 0 here+ pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)+ throwUVIfMinus_ (hs_uv_listen serverHandle (max 4 (fromIntegral backLog)))++ forever $ do+ -- wait until accept some FDs+ !acceptCountDown <- takeMVar m -- Step 3.--- Copy buffer, fetch accepted FDs and fork worker threads.+-- After uv loop finishes, if we got some FDs, copy the FD buffer, fetch accepted FDs and fork worker threads. - -- we lock uv manager here in case of next uv_run overwrite current accept buffer- acceptBufCopy <- withUVManager' serverUVManager $ do- _ <- tryTakeMVar m- pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)+ -- we lock uv manager here in case of next uv_run overwrite current accept buffer+ acceptBufCopy <- withUVManager' serverUVManager $ do+ _ <- tryTakeMVar m+ pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1) - -- if acceptCountDown count to -1, we should resume on haskell side- when (acceptCountDown == -1) (hs_uv_listen_resume serverHandle)+ -- if acceptCountDown count to -1, we should resume on haskell side+ when (acceptCountDown == -1) (hs_uv_listen_resume serverHandle) - -- copy accepted FDs- let acceptCount = backLog - 1 - acceptCountDown- acceptBuf' <- newPrimArray acceptCount- copyMutablePrimArray acceptBuf' 0 acceptBuf (acceptCountDown+1) acceptCount- unsafeFreezePrimArray acceptBuf'+ -- copy accepted FDs+ let acceptCount = backLog - 1 - acceptCountDown+ acceptBuf' <- newPrimArray acceptCount+ copyMutablePrimArray acceptBuf' 0 acceptBuf (acceptCountDown+1) acceptCount+ unsafeFreezePrimArray acceptBuf' - -- fork worker thread- forM_ [0..sizeofPrimArray acceptBufCopy-1] $ \ i -> do- let fd = indexPrimArray acceptBufCopy i- if fd < 0- -- minus fd indicate a server error and we should close server- then throwUVIfMinus_ (return fd)- -- It's important to use the worker thread's mananger instead of server's one!- else void . forkBa $ do- uvm <- getUVManager- withResource (initUVStream (\ loop hdl -> do- throwUVIfMinus_ (uv_pipe_init loop hdl 0)- throwUVIfMinus_ (hs_uv_pipe_open hdl fd)) uvm) $ \ uvs -> do- ipcServerWorker uvs+ -- fork worker thread+ forM_ [0..sizeofPrimArray acceptBufCopy-1] $ \ i -> do+ let fd = indexPrimArray acceptBufCopy i+ if fd < 0+ -- minus fd indicate a server error and we should close server+ then throwUVIfMinus_ (return fd)+ -- It's important to use the worker thread's mananger instead of server's one!+ else void . forkBa $ do+ uvm <- getUVManager+ withResource (initUVStream (\ loop hdl -> do+ throwUVIfMinus_ (uv_pipe_init loop hdl 0)+ throwUVIfMinus_ (hs_uv_pipe_open hdl fd)) uvm) $ \ uvs -> do+ ipcServerWorker uvs --------------------------------------------------------------------------------
Z/IO/Network/SocketAddr.hsc view
@@ -47,8 +47,8 @@ , inet6Loopback , inet6AddrToTuple , tupleToInet6Addr- , FlowInfo(..)- , ScopeID(..)+ , FlowInfo+ , ScopeID -- * port numbber , PortNumber(..) , portAny@@ -82,7 +82,6 @@ import Data.Bits import qualified Data.List as List-import Data.Ratio import Data.Typeable import Foreign import Foreign.C@@ -330,6 +329,13 @@ instance UnalignedAccess Inet6Addr where unalignedSize = UnalignedSize (#size struct in6_addr) + indexBA p off = + let a = indexBA p (off + s6_addr_offset + 0)+ b = indexBA p (off + s6_addr_offset + 4)+ c = indexBA p (off + s6_addr_offset + 8)+ d = indexBA p (off + s6_addr_offset + 12)+ in Inet6Addr (getBE a) (getBE b) (getBE c) (getBE d)+ peekMBA p off = do a <- peekMBA p (off + s6_addr_offset + 0) b <- peekMBA p (off + s6_addr_offset + 4)@@ -520,6 +526,7 @@ instance UnalignedAccess PortNumber where unalignedSize = UnalignedSize 2+ indexBA p off = PortNumber . ntohs $ indexBA p off pokeMBA p off (PortNumber po) = pokeMBA p off (htons po) peekMBA p off = PortNumber . ntohs <$> peekMBA p off
Z/IO/Network/TCP.hs view
@@ -29,6 +29,10 @@ , defaultTCPServerConfig , startTCPServer , getTCPPeerName+ -- * Internal helper+ , setTCPNoDelay+ , setTCPKeepAlive+ , initTCPStream ) where import Control.Concurrent.MVar@@ -70,16 +74,17 @@ uvm <- liftIO getUVManager client <- initTCPStream uvm let hdl = uvsHandle client- liftIO . withSocketAddr tcpRemoteAddr $ \ targetPtr -> do+ liftIO $ do forM_ tcpClientAddr $ \ tcpClientAddr' ->- withSocketAddr tcpClientAddr' $ \ localPtr ->+ withSocketAddrUnsafe tcpClientAddr' $ \ localPtr -> -- bind is safe without withUVManager throwUVIfMinus_ (uv_tcp_bind hdl localPtr 0) -- nodelay is safe without withUVManager when tcpClientNoDelay . throwUVIfMinus_ $ uv_tcp_nodelay hdl 1 when (tcpClientKeepAlive > 0) . throwUVIfMinus_ $ uv_tcp_keepalive hdl 1 tcpClientKeepAlive- void . withUVRequest uvm $ \ _ -> hs_uv_tcp_connect hdl targetPtr+ withSocketAddrUnsafe tcpRemoteAddr $ \ targetPtr -> do+ void . withUVRequest uvm $ \ _ -> hs_uv_tcp_connect hdl targetPtr return client --------------------------------------------------------------------------------@@ -115,7 +120,10 @@ startTCPServer TCPServerConfig{..} = do let backLog = max tcpListenBacklog 128 serverUVManager <- getUVManager- withResource (initTCPStream serverUVManager) $ \ (UVStream serverHandle serverSlot _ _) ->+ withResource (initTCPStream serverUVManager) $ \ (UVStream serverHandle serverSlot _ _) -> do+ -- bind is safe without withUVManager+ withSocketAddrUnsafe tcpListenAddr $ \ addrPtr -> do+ throwUVIfMinus_ (uv_tcp_bind serverHandle addrPtr 0) bracket (throwOOMIfNull $ hs_uv_accept_check_alloc serverHandle) hs_uv_accept_check_close $@@ -137,56 +145,55 @@ -- we allocate a new uv_check_t for given uv_stream_t, with predefined checking callback -- see hs_accept_check_cb in hs_uv_stream.c throwUVIfMinus_ $ hs_uv_accept_check_init check- withSocketAddr tcpListenAddr $ \ addrPtr -> do- m <- getBlockMVar serverUVManager serverSlot- acceptBuf <- newPinnedPrimArray backLog- let acceptBufPtr = coerce (mutablePrimArrayContents acceptBuf :: Ptr UVFD)+ m <- getBlockMVar serverUVManager serverSlot -- Step 2. -- we allocate a buffer to hold accepted FDs, pass it just like a normal reading buffer.- withUVManager' serverUVManager $ do- -- We use buffersize as accepted fd count(count backwards)- pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)- throwUVIfMinus_ (uv_tcp_bind serverHandle addrPtr 0)- throwUVIfMinus_ (hs_uv_listen serverHandle (max 4 (fromIntegral backLog)))+-- then we can start listening.+ acceptBuf <- newPinnedPrimArray backLog+ let acceptBufPtr = coerce (mutablePrimArrayContents acceptBuf :: Ptr UVFD)+ withUVManager' serverUVManager $ do+ -- We use buffersize as accepted fd count(count backwards)+ pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)+ throwUVIfMinus_ (hs_uv_listen serverHandle (max 4 (fromIntegral backLog))) - forever $ do- -- wait until accept some FDs- !acceptCountDown <- takeMVar m+ forever $ do+ -- wait until accept some FDs+ !acceptCountDown <- takeMVar m -- Step 3.--- Copy buffer, fetch accepted FDs and fork worker threads.+-- After uv loop finishes, if we got some FDs, copy the FD buffer, fetch accepted FDs and fork worker threads. - -- we lock uv manager here in case of next uv_run overwrite current accept buffer- acceptBufCopy <- withUVManager' serverUVManager $ do- _ <- tryTakeMVar m- pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1)+ -- we lock uv manager here in case of next uv_run overwrite current accept buffer+ acceptBufCopy <- withUVManager' serverUVManager $ do+ _ <- tryTakeMVar m+ pokeBufferTable serverUVManager serverSlot acceptBufPtr (backLog-1) - -- if acceptCountDown count to -1, we should resume on haskell side- when (acceptCountDown == -1) (hs_uv_listen_resume serverHandle)+ -- if acceptCountDown count to -1, we should resume on haskell side+ when (acceptCountDown == -1) (hs_uv_listen_resume serverHandle) - -- copy accepted FDs- let acceptCount = backLog - 1 - acceptCountDown- acceptBuf' <- newPrimArray acceptCount- copyMutablePrimArray acceptBuf' 0 acceptBuf (acceptCountDown+1) acceptCount- unsafeFreezePrimArray acceptBuf'+ -- copy accepted FDs+ let acceptCount = backLog - 1 - acceptCountDown+ acceptBuf' <- newPrimArray acceptCount+ copyMutablePrimArray acceptBuf' 0 acceptBuf (acceptCountDown+1) acceptCount+ unsafeFreezePrimArray acceptBuf' - -- fork worker thread- forM_ [0..sizeofPrimArray acceptBufCopy-1] $ \ i -> do- let fd = indexPrimArray acceptBufCopy i- if fd < 0- -- minus fd indicate a server error and we should close server- then throwUVIfMinus_ (return fd)- -- It's important to use the worker thread's mananger instead of server's one!- else void . forkBa $ do- uvm <- getUVManager- withResource (initUVStream (\ loop hdl -> do- throwUVIfMinus_ (uv_tcp_init loop hdl)- throwUVIfMinus_ (hs_uv_tcp_open hdl fd)) uvm) $ \ uvs -> do- when tcpServerWorkerNoDelay . throwUVIfMinus_ $- -- safe without withUVManager- uv_tcp_nodelay (uvsHandle uvs) 1- when (tcpServerWorkerKeepAlive > 0) . throwUVIfMinus_ $- uv_tcp_keepalive (uvsHandle uvs) 1 tcpServerWorkerKeepAlive- tcpServerWorker uvs+ -- fork worker thread+ forM_ [0..sizeofPrimArray acceptBufCopy-1] $ \ i -> do+ let fd = indexPrimArray acceptBufCopy i+ if fd < 0+ -- minus fd indicate a server error and we should close server+ then throwUVIfMinus_ (return fd)+ -- It's important to use the worker thread's mananger instead of server's one!+ else void . forkBa $ do+ uvm <- getUVManager+ withResource (initUVStream (\ loop hdl -> do+ throwUVIfMinus_ (uv_tcp_init loop hdl)+ throwUVIfMinus_ (hs_uv_tcp_open hdl fd)) uvm) $ \ uvs -> do+ when tcpServerWorkerNoDelay . throwUVIfMinus_ $+ -- safe without withUVManager+ uv_tcp_nodelay (uvsHandle uvs) 1+ when (tcpServerWorkerKeepAlive > 0) . throwUVIfMinus_ $+ uv_tcp_keepalive (uvsHandle uvs) 1 tcpServerWorkerKeepAlive+ tcpServerWorker uvs -------------------------------------------------------------------------------- @@ -211,13 +218,13 @@ -- | Get the current address to which the handle is bound. getTCPSockName :: HasCallStack => UVStream -> IO SocketAddr getTCPSockName uvs = do- withSocketAddrStorage $ \ paddr ->+ withSocketAddrStorageUnsafe $ \ paddr -> void $ withPrimUnsafe (fromIntegral sizeOfSocketAddrStorage :: CInt) $ \ plen ->- throwUVIfMinus_ (uv_udp_getsockname (uvsHandle uvs) paddr plen)+ throwUVIfMinus_ (uv_tcp_getsockname (uvsHandle uvs) paddr plen) -- | Get the address of the peer connected to the handle. getTCPPeerName :: HasCallStack => UVStream -> IO SocketAddr getTCPPeerName uvs = do- withSocketAddrStorage $ \ paddr ->+ withSocketAddrStorageUnsafe $ \ paddr -> void $ withPrimUnsafe (fromIntegral sizeOfSocketAddrStorage :: CInt) $ \ plen ->- throwUVIfMinus_ (uv_udp_getpeername (uvsHandle uvs) paddr plen)+ throwUVIfMinus_ (uv_tcp_getpeername (uvsHandle uvs) paddr plen)
Z/IO/Network/UDP.hs view
@@ -130,13 +130,15 @@ -- init uv struct (do throwUVIfMinus_ (uv_udp_init loop hdl)- -- bind the socket if address is available- forM_ maddr $ \ (addr, flag) ->- withSocketAddr addr $ \ p ->- throwUVIfMinus_ (uv_udp_bind hdl p flag) ) `onException` hs_uv_handle_free hdl return (hdl, slot) + -- bind the socket if address is available+ -- This is safe without lock UV manager+ forM_ maddr $ \ (addr, flag) ->+ withSocketAddrUnsafe addr $ \ p ->+ throwUVIfMinus_ (uv_udp_bind hdl p flag)+ sbuf <- A.newPinnedPrimArray (max 0 sbsiz) closed <- newIORef False return (UDP hdl slot uvm sbuf closed))@@ -154,7 +156,7 @@ getSockName :: HasCallStack => UDP -> IO SocketAddr getSockName udp@(UDP hdl _ _ _ _) = do checkUDPClosed udp- withSocketAddrStorage $ \ paddr ->+ withSocketAddrStorageUnsafe $ \ paddr -> void $ withPrimUnsafe (fromIntegral sizeOfSocketAddrStorage :: CInt) $ \ plen -> throwUVIfMinus_ (uv_udp_getsockname hdl paddr plen) @@ -166,7 +168,7 @@ connectUDP :: HasCallStack => UDP -> SocketAddr -> IO ConnectedUDP connectUDP udp@(UDP hdl _ _ _ _) addr = do checkUDPClosed udp- withSocketAddr addr $ \ paddr ->+ withSocketAddrUnsafe addr $ \ paddr -> throwUVIfMinus_ (uv_udp_connect hdl paddr) return (ConnectedUDP udp) @@ -174,14 +176,14 @@ disconnectUDP :: HasCallStack => ConnectedUDP -> IO UDP disconnectUDP (ConnectedUDP udp@(UDP hdl _ _ _ _)) = do checkUDPClosed udp- throwUVIfMinus_ (uv_udp_connect hdl nullPtr)+ throwUVIfMinus_ (uv_udp_disconnect hdl nullPtr) return udp -- | Get the remote IP and port on 'ConnectedUDP'. getPeerName :: HasCallStack => ConnectedUDP -> IO SocketAddr getPeerName (ConnectedUDP udp@(UDP hdl _ _ _ _)) = do checkUDPClosed udp- withSocketAddrStorage $ \ paddr ->+ withSocketAddrStorageUnsafe $ \ paddr -> void $ withPrimUnsafe (fromIntegral sizeOfSocketAddrStorage :: CInt) $ \ plen -> throwUVIfMinus_ (uv_udp_getpeername hdl paddr plen) @@ -198,8 +200,9 @@ copyPrimArray sbuf 0 ba s la withMutablePrimArrayContents sbuf $ \ pbuf -> do m <- withUVManager' uvm $ do- reqSlot <- getUVSlot uvm (hs_uv_udp_send hdl nullPtr pbuf la)+ reqSlot <- getUVSlot uvm (hs_uv_udp_send_connected hdl pbuf la) reqMVar <- getBlockMVar uvm reqSlot+ -- since we locked uv manager here, it won't affect next event _ <- tryTakeMVar reqMVar return reqMVar -- we can't cancel uv_udp_send_t in current libuv@@ -221,20 +224,21 @@ lb <- getSizeofMutablePrimArray sbuf when (la > lb) (throwUVIfMinus_ (return UV_EMSGSIZE)) copyPrimArray sbuf 0 ba s la- withSocketAddr addr $ \ paddr ->- withMutablePrimArrayContents sbuf $ \ pbuf -> do- m <- withUVManager' uvm $ do- reqSlot <- getUVSlot uvm (hs_uv_udp_send hdl paddr pbuf la)- reqMVar <- getBlockMVar uvm reqSlot- _ <- tryTakeMVar reqMVar- return reqMVar- -- we can't cancel uv_udp_send_t in current libuv- -- and disaster will happen if buffer got collected.- -- so we have to turn to uninterruptibleMask_'s help.- -- i.e. sendUDP is an uninterruptible operation.- -- OS will guarantee writing a socket will not- -- hang forever anyway.- throwUVIfMinus_ (uninterruptibleMask_ $ takeMVar m)+ withMutablePrimArrayContents sbuf $ \ pbuf -> do+ m <- withUVManager' uvm $ do+ reqSlot <- withSocketAddrUnsafe addr $ \ paddr ->+ getUVSlot uvm (hs_uv_udp_send hdl paddr pbuf la)+ reqMVar <- getBlockMVar uvm reqSlot+ -- since we locked uv manager here, it won't affect next event+ _ <- tryTakeMVar reqMVar+ return reqMVar+ -- we can't cancel uv_udp_send_t in current libuv+ -- and disaster will happen if buffer got collected.+ -- so we have to turn to uninterruptibleMask_'s help.+ -- i.e. sendUDP is an uninterruptible operation.+ -- OS will guarantee writing a socket will not+ -- hang forever anyway.+ throwUVIfMinus_ (uninterruptibleMask_ $ takeMVar m) -- | Set IP multicast loop flag. Makes multicast packets loop back to local sockets. setMulticastLoop :: HasCallStack => UDP -> Bool -> IO ()
Z/IO/UV/FFI.hsc view
@@ -149,14 +149,14 @@ foreign import ccall unsafe uv_tcp_init_ex :: Ptr UVLoop -> Ptr UVHandle -> CUInt -> IO CInt foreign import ccall unsafe uv_tcp_nodelay :: Ptr UVHandle -> CInt -> IO CInt foreign import ccall unsafe uv_tcp_keepalive :: Ptr UVHandle -> CInt -> CUInt -> IO CInt-foreign import ccall unsafe uv_tcp_getsockname :: Ptr UVHandle -> Ptr SocketAddr -> CInt -> IO CInt-foreign import ccall unsafe uv_tcp_getpeername :: Ptr UVHandle -> Ptr SocketAddr -> CInt -> IO CInt+foreign import ccall unsafe uv_tcp_getsockname :: Ptr UVHandle -> MBA## SocketAddr -> MBA## CInt -> IO CInt+foreign import ccall unsafe uv_tcp_getpeername :: Ptr UVHandle -> MBA## SocketAddr -> MBA## CInt -> IO CInt uV_TCP_IPV6ONLY :: CUInt uV_TCP_IPV6ONLY = #{const UV_TCP_IPV6ONLY} -foreign import ccall unsafe uv_tcp_bind :: Ptr UVHandle -> Ptr SocketAddr -> CUInt -> IO CInt-foreign import ccall unsafe hs_uv_tcp_connect :: Ptr UVHandle -> Ptr SocketAddr -> IO UVSlotUnSafe+foreign import ccall unsafe uv_tcp_bind :: Ptr UVHandle -> MBA## SocketAddr -> CUInt -> IO CInt+foreign import ccall unsafe hs_uv_tcp_connect :: Ptr UVHandle -> MBA## SocketAddr -> IO UVSlotUnSafe foreign import ccall unsafe hs_set_socket_reuse :: Ptr UVHandle -> IO CInt foreign import ccall unsafe hs_uv_pipe_open :: Ptr UVHandle -> UVFD -> IO CInt@@ -169,7 +169,7 @@ foreign import ccall unsafe uv_udp_init :: Ptr UVLoop -> Ptr UVHandle -> IO CInt foreign import ccall unsafe uv_udp_init_ex :: Ptr UVLoop -> Ptr UVHandle -> CUInt -> IO CInt foreign import ccall unsafe uv_udp_open :: Ptr UVHandle -> UVFD -> IO CInt-foreign import ccall unsafe uv_udp_bind :: Ptr UVHandle -> Ptr SocketAddr -> UVUDPFlag -> IO CInt+foreign import ccall unsafe uv_udp_bind :: Ptr UVHandle -> MBA## SocketAddr -> UVUDPFlag -> IO CInt newtype UVMembership = UVMembership CInt deriving (Show, Eq, Ord) @@ -191,6 +191,9 @@ pattern UV_UDP_PARTIAL = #{const UV_UDP_PARTIAL} foreign import ccall unsafe uv_udp_connect+ :: Ptr UVHandle -> MBA## SocketAddr -> IO CInt+-- | Just pass null pointer as SocketAddr to disconnect+foreign import ccall unsafe "uv_udp_connect" uv_udp_disconnect :: Ptr UVHandle -> Ptr SocketAddr -> IO CInt foreign import ccall unsafe uv_udp_set_membership ::@@ -207,11 +210,13 @@ foreign import ccall unsafe hs_uv_udp_recv_start :: Ptr UVHandle -> IO CInt foreign import ccall unsafe uv_udp_recv_stop :: Ptr UVHandle -> IO CInt foreign import ccall unsafe hs_uv_udp_send - :: Ptr UVHandle -> Ptr SocketAddr -> Ptr Word8 -> Int -> IO UVSlotUnSafe+ :: Ptr UVHandle -> MBA## SocketAddr -> Ptr Word8 -> Int -> IO UVSlotUnSafe+foreign import ccall unsafe hs_uv_udp_send_connected+ :: Ptr UVHandle -> Ptr Word8 -> Int -> IO UVSlotUnSafe foreign import ccall unsafe uv_udp_getsockname - :: Ptr UVHandle -> Ptr SocketAddr -> MBA## CInt -> IO CInt+ :: Ptr UVHandle -> MBA## SocketAddr -> MBA## CInt -> IO CInt foreign import ccall unsafe uv_udp_getpeername- :: Ptr UVHandle -> Ptr SocketAddr -> MBA## CInt -> IO CInt+ :: Ptr UVHandle -> MBA## SocketAddr -> MBA## CInt -> IO CInt --------------------------------------------------------------------------------
Z/IO/UV/Manager.hs view
@@ -330,6 +330,7 @@ (slot, m) <- withUVManager uvm $ \ loop -> mask_ $ do slot <- getUVSlot uvm (f loop) m <- getBlockMVar uvm slot+ -- since we locked uv manager here, it won't affect next event _ <- tryTakeMVar m return (slot, m) g =<< (takeMVar m `onException` cancelUVReq uvm slot no_extra_cleanup)
cbits/hs_uv_udp.c view
@@ -126,3 +126,8 @@ } else return slot; }++HsInt hs_uv_udp_send_connected(uv_udp_t* handle, char* buf, HsInt buf_siz){+ return hs_uv_udp_send(handle, NULL, buf, buf_siz);+}+
include/hs_uv.h view
@@ -294,6 +294,7 @@ // udp int hs_uv_udp_recv_start(uv_udp_t* handle);+HsInt hs_uv_udp_send_connected(uv_udp_t* handle, char* buf, HsInt buf_siz); HsInt hs_uv_upd_send(uv_udp_t* handle, const struct sockaddr* addr, char* buf, HsInt buf_siz); ////////////////////////////////////////////////////////////////////////////////
+ test/Z/Compression/ZlibSpec.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE OverloadedStrings #-}++module Z.Compression.ZlibSpec where++import Control.Monad+import Data.IORef+import Data.ByteString as B+import Data.ByteString.Lazy as BL+import Z.Data.Vector as V+import Z.Compression.Zlib+import qualified Codec.Compression.Zlib as TheZlib+import Z.IO.Buffered+import Test.QuickCheck+import Test.QuickCheck.Function+import Test.QuickCheck.Property+import Test.Hspec+import Test.Hspec.QuickCheck+import Test.HUnit+++spec :: Spec+spec = describe "zlib" $ do++ describe "decompress . compress === id" . modifyMaxSize (*50) $ do+ prop "decompress . compress === id" $ \ xs -> do+ decompress defaultDecompressConfig+ (compress defaultCompressConfig (V.pack xs)) === V.pack xs++ prop "decompress . compress === id(with dict)" $ \ xs -> do+ let dict = "aabbccdd"+ decompress defaultDecompressConfig{decompressDictionary = dict}+ (compress defaultCompressConfig{compressDictionary = dict} (V.pack xs))+ === V.pack xs++ prop "compress === TheZlib.compress" $ \ xs -> do+ V.unpack (compress defaultCompressConfig (V.pack xs)) ===+ BL.unpack (TheZlib.compressWith TheZlib.defaultCompressParams (BL.pack xs))++ prop "compress === TheZlib.compress(with dict)" $ \ xs -> do+ V.unpack (compress defaultCompressConfig{compressDictionary = "aabbccdd"} (V.pack xs)) ===+ BL.unpack (TheZlib.compressWith+ TheZlib.defaultCompressParams{TheZlib.compressDictionary = Just "aabbccdd" }+ (BL.pack xs))++ prop "decompressSink . compressSource === id" $ \ xss -> do+ ref <- newIORef []+ (write, flush) <- compressSink defaultCompressConfig+ (\ x -> modifyIORef' ref (x:), return ())++ let vs = Prelude.map V.pack xss++ forM_ vs write+ flush++ source <- sourceFromList . Prelude.reverse =<< readIORef ref+ vs' <- collectSource =<< decompressSource defaultDecompressConfig source++ V.concat vs @=? V.concat vs'++ prop "decompressSink . compressSource === id(with dict)" $ \ xss -> do+ let dict = "aabbccdd"+ ref <- newIORef []+ (write, flush) <- compressSink defaultCompressConfig{compressDictionary = dict}++ (\ x -> modifyIORef' ref (x:), return ())++ let vs = Prelude.map V.pack xss++ forM_ vs write+ flush++ source <- sourceFromList . Prelude.reverse =<< readIORef ref+ vs' <- collectSource =<< decompressSource+ defaultDecompressConfig{decompressDictionary = dict} source++ V.concat vs @=? V.concat vs'+
+ test/Z/IO/Network/TCPSpec.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE OverloadedStrings #-}++module Z.IO.Network.TCPSpec where++import Control.Concurrent+import Control.Monad+import Data.Bits+import Z.Data.Vector as V+import Z.Data.Vector.Base as V+import Data.List as List+import Foreign.Marshal.Array+import Foreign.Ptr+import Z.IO.Exception+import Z.IO.Resource+import Z.IO.Buffered+import Z.IO.Network+import Test.Hspec+import Test.HUnit++spec :: Spec+spec = describe "TCP operations" $ do+ it "roundtrip test" $ do+ let testMsg = V.cycleN 256 "abc"+ longMsg = V.cycleN 2048 "abcdefg"+ addr = SocketAddrInet 12345 inetLoopback++ serverThread <- forkIO $ startTCPServer defaultTCPServerConfig{+ tcpListenAddr = addr+ , tcpServerWorker = \ tcp -> do+ i <- newBufferedInput defaultChunkSize tcp+ o <- newBufferedOutput defaultChunkSize tcp+ forever $ readBuffer i >>= writeBuffer o >> flushBuffer o+ }++ threadDelay 100000++ replicateM_ 1000 . forkIO $+ withResource (initTCPClient defaultTCPClientConfig{tcpRemoteAddr = addr}) $ \ tcp -> do+ i <- newBufferedInput defaultChunkSize tcp+ o <- newBufferedOutput defaultChunkSize tcp++ replicateM_ 1000 . forkIO $ do+ writeBuffer o testMsg >> flushBuffer o+ testMsg' <- readAll' i+ testMsg' @=? testMsg++ replicateM_ 1000 . forkIO $ do+ writeBuffer o longMsg >> flushBuffer o+ longMsg' <- readAll' i+ longMsg' @=? longMsg++ killThread serverThread
+ test/Z/IO/Network/UDPSpec.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE OverloadedStrings #-}++module Z.IO.Network.UDPSpec where++import Control.Concurrent+import Control.Monad+import Data.Bits+import Z.Data.Vector as V+import Z.Data.Vector.Base as V+import Data.List as List+import Foreign.Marshal.Array+import Foreign.Ptr+import Z.IO.Exception+import Z.IO.Resource+import Z.IO.Network+import Test.Hspec+import Test.HUnit++spec :: Spec+spec = describe "UDP operations" $ do+ it "roundtrip test" $ do+ let testMsg = V.replicate 256 48+ longMsg = V.replicate 2048 48+ addr = SocketAddrInet 12345 inetLoopback+ withResource (initUDP defaultUDPConfig{udpSendMsgSize = 2048}) $ \ c ->+ withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr,UV_UDP_DEFAULT)}) $ \ s -> do+ forkIO $ sendUDP c addr testMsg+ [(_, partial, rcvMsg)]<- recvUDP defaultUDPRecvConfig s+ partial @=? False+ rcvMsg @=? testMsg++ threadDelay 100000++ forkIO $ sendUDP c addr longMsg+ [(_, partial, rcvMsg)]<- recvUDP defaultUDPRecvConfig s+ partial @=? True++ it "UDP sending addr test" $ do+ let testMsg = V.replicate 256 48+ addr = SocketAddrInet 12346 inetLoopback+ addr' = SocketAddrInet 12347 inetLoopback+ withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr,UV_UDP_DEFAULT)}) $ \ c ->+ withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr',UV_UDP_DEFAULT)}) $ \ s -> do+ forkIO $ sendUDP c addr' testMsg+ [(rcvAddr, _, _)]<- recvUDP defaultUDPRecvConfig s+ Just addr @=? rcvAddr++ it "overlong message exception" $ do+ let testMsg = V.replicate 4096 48+ addr = SocketAddrInet 12348 inetLoopback+ withResource (initUDP defaultUDPConfig) $ \ c ->+ withResource (initUDP defaultUDPConfig) $ \ s -> do+ sendUDP c addr testMsg `shouldThrow` anyException
− test/Z/IO/UDPSpec.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Z.IO.UDPSpec where--import Control.Concurrent-import Control.Monad-import Data.Bits-import Z.Data.Vector as V-import Z.Data.Vector.Base as V-import Data.List as List-import Foreign.Marshal.Array-import Foreign.Ptr-import Z.IO.Exception-import Z.IO.Resource-import Z.IO.Network.SocketAddr-import Z.IO.Network.UDP-import Test.Hspec-import Test.HUnit--spec :: Spec-spec = describe "UDP operations" $ do- it "roundtrip test" $ do- let testMsg = V.replicate 256 48- longMsg = V.replicate 2048 48- addr = SocketAddrInet 12345 inetLoopback- withResource (initUDP defaultUDPConfig{udpSendMsgSize = 2048}) $ \ c ->- withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr,UV_UDP_DEFAULT)}) $ \ s -> do- forkIO $ sendUDP c addr testMsg- [(_, partial, rcvMsg)]<- recvUDP defaultUDPRecvConfig s- partial @=? False- rcvMsg @=? testMsg-- threadDelay 100000-- forkIO $ sendUDP c addr longMsg- [(_, partial, rcvMsg)]<- recvUDP defaultUDPRecvConfig s- partial @=? True-- it "UDP sending addr test" $ do- let testMsg = V.replicate 256 48- addr = SocketAddrInet 12346 inetLoopback- addr' = SocketAddrInet 12347 inetLoopback- withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr,UV_UDP_DEFAULT)}) $ \ c ->- withResource (initUDP defaultUDPConfig{udpLocalAddr = Just (addr',UV_UDP_DEFAULT)}) $ \ s -> do- forkIO $ sendUDP c addr' testMsg- [(rcvAddr, _, _)]<- recvUDP defaultUDPRecvConfig s- Just addr @=? rcvAddr-- it "overlong message exception" $ do- let testMsg = V.replicate 4096 48- addr = SocketAddrInet 12348 inetLoopback- withResource (initUDP defaultUDPConfig) $ \ c ->- withResource (initUDP defaultUDPConfig) $ \ s -> do- sendUDP c addr testMsg `shouldThrow` anyException
+ third_party/zlib/zconf.h view
@@ -0,0 +1,534 @@+/* zconf.h -- configuration of the zlib compression library+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* @(#) $Id$ */++#ifndef ZCONF_H+#define ZCONF_H++/*+ * If you *really* need a unique prefix for all types and library functions,+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.+ * Even better than compiling with -DZ_PREFIX would be to use configure to set+ * this permanently in zconf.h using "./configure --zprefix".+ */+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */+# define Z_PREFIX_SET++/* all linked symbols and init macros */+# define _dist_code z__dist_code+# define _length_code z__length_code+# define _tr_align z__tr_align+# define _tr_flush_bits z__tr_flush_bits+# define _tr_flush_block z__tr_flush_block+# define _tr_init z__tr_init+# define _tr_stored_block z__tr_stored_block+# define _tr_tally z__tr_tally+# define adler32 z_adler32+# define adler32_combine z_adler32_combine+# define adler32_combine64 z_adler32_combine64+# define adler32_z z_adler32_z+# ifndef Z_SOLO+# define compress z_compress+# define compress2 z_compress2+# define compressBound z_compressBound+# endif+# define crc32 z_crc32+# define crc32_combine z_crc32_combine+# define crc32_combine64 z_crc32_combine64+# define crc32_z z_crc32_z+# define deflate z_deflate+# define deflateBound z_deflateBound+# define deflateCopy z_deflateCopy+# define deflateEnd z_deflateEnd+# define deflateGetDictionary z_deflateGetDictionary+# define deflateInit z_deflateInit+# define deflateInit2 z_deflateInit2+# define deflateInit2_ z_deflateInit2_+# define deflateInit_ z_deflateInit_+# define deflateParams z_deflateParams+# define deflatePending z_deflatePending+# define deflatePrime z_deflatePrime+# define deflateReset z_deflateReset+# define deflateResetKeep z_deflateResetKeep+# define deflateSetDictionary z_deflateSetDictionary+# define deflateSetHeader z_deflateSetHeader+# define deflateTune z_deflateTune+# define deflate_copyright z_deflate_copyright+# define get_crc_table z_get_crc_table+# ifndef Z_SOLO+# define gz_error z_gz_error+# define gz_intmax z_gz_intmax+# define gz_strwinerror z_gz_strwinerror+# define gzbuffer z_gzbuffer+# define gzclearerr z_gzclearerr+# define gzclose z_gzclose+# define gzclose_r z_gzclose_r+# define gzclose_w z_gzclose_w+# define gzdirect z_gzdirect+# define gzdopen z_gzdopen+# define gzeof z_gzeof+# define gzerror z_gzerror+# define gzflush z_gzflush+# define gzfread z_gzfread+# define gzfwrite z_gzfwrite+# define gzgetc z_gzgetc+# define gzgetc_ z_gzgetc_+# define gzgets z_gzgets+# define gzoffset z_gzoffset+# define gzoffset64 z_gzoffset64+# define gzopen z_gzopen+# define gzopen64 z_gzopen64+# ifdef _WIN32+# define gzopen_w z_gzopen_w+# endif+# define gzprintf z_gzprintf+# define gzputc z_gzputc+# define gzputs z_gzputs+# define gzread z_gzread+# define gzrewind z_gzrewind+# define gzseek z_gzseek+# define gzseek64 z_gzseek64+# define gzsetparams z_gzsetparams+# define gztell z_gztell+# define gztell64 z_gztell64+# define gzungetc z_gzungetc+# define gzvprintf z_gzvprintf+# define gzwrite z_gzwrite+# endif+# define inflate z_inflate+# define inflateBack z_inflateBack+# define inflateBackEnd z_inflateBackEnd+# define inflateBackInit z_inflateBackInit+# define inflateBackInit_ z_inflateBackInit_+# define inflateCodesUsed z_inflateCodesUsed+# define inflateCopy z_inflateCopy+# define inflateEnd z_inflateEnd+# define inflateGetDictionary z_inflateGetDictionary+# define inflateGetHeader z_inflateGetHeader+# define inflateInit z_inflateInit+# define inflateInit2 z_inflateInit2+# define inflateInit2_ z_inflateInit2_+# define inflateInit_ z_inflateInit_+# define inflateMark z_inflateMark+# define inflatePrime z_inflatePrime+# define inflateReset z_inflateReset+# define inflateReset2 z_inflateReset2+# define inflateResetKeep z_inflateResetKeep+# define inflateSetDictionary z_inflateSetDictionary+# define inflateSync z_inflateSync+# define inflateSyncPoint z_inflateSyncPoint+# define inflateUndermine z_inflateUndermine+# define inflateValidate z_inflateValidate+# define inflate_copyright z_inflate_copyright+# define inflate_fast z_inflate_fast+# define inflate_table z_inflate_table+# ifndef Z_SOLO+# define uncompress z_uncompress+# define uncompress2 z_uncompress2+# endif+# define zError z_zError+# ifndef Z_SOLO+# define zcalloc z_zcalloc+# define zcfree z_zcfree+# endif+# define zlibCompileFlags z_zlibCompileFlags+# define zlibVersion z_zlibVersion++/* all zlib typedefs in zlib.h and zconf.h */+# define Byte z_Byte+# define Bytef z_Bytef+# define alloc_func z_alloc_func+# define charf z_charf+# define free_func z_free_func+# ifndef Z_SOLO+# define gzFile z_gzFile+# endif+# define gz_header z_gz_header+# define gz_headerp z_gz_headerp+# define in_func z_in_func+# define intf z_intf+# define out_func z_out_func+# define uInt z_uInt+# define uIntf z_uIntf+# define uLong z_uLong+# define uLongf z_uLongf+# define voidp z_voidp+# define voidpc z_voidpc+# define voidpf z_voidpf++/* all zlib structs in zlib.h and zconf.h */+# define gz_header_s z_gz_header_s+# define internal_state z_internal_state++#endif++#if defined(__MSDOS__) && !defined(MSDOS)+# define MSDOS+#endif+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)+# define OS2+#endif+#if defined(_WINDOWS) && !defined(WINDOWS)+# define WINDOWS+#endif+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)+# ifndef WIN32+# define WIN32+# endif+#endif+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)+# ifndef SYS16BIT+# define SYS16BIT+# endif+# endif+#endif++/*+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more+ * than 64k bytes at a time (needed on systems with 16-bit int).+ */+#ifdef SYS16BIT+# define MAXSEG_64K+#endif+#ifdef MSDOS+# define UNALIGNED_OK+#endif++#ifdef __STDC_VERSION__+# ifndef STDC+# define STDC+# endif+# if __STDC_VERSION__ >= 199901L+# ifndef STDC99+# define STDC99+# endif+# endif+#endif+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))+# define STDC+#endif+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))+# define STDC+#endif+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))+# define STDC+#endif+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))+# define STDC+#endif++#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */+# define STDC+#endif++#ifndef STDC+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */+# define const /* note: need a more gentle solution here */+# endif+#endif++#if defined(ZLIB_CONST) && !defined(z_const)+# define z_const const+#else+# define z_const+#endif++#ifdef Z_SOLO+ typedef unsigned long z_size_t;+#else+# define z_longlong long long+# if defined(NO_SIZE_T)+ typedef unsigned NO_SIZE_T z_size_t;+# elif defined(STDC)+# include <stddef.h>+ typedef size_t z_size_t;+# else+ typedef unsigned long z_size_t;+# endif+# undef z_longlong+#endif++/* Maximum value for memLevel in deflateInit2 */+#ifndef MAX_MEM_LEVEL+# ifdef MAXSEG_64K+# define MAX_MEM_LEVEL 8+# else+# define MAX_MEM_LEVEL 9+# endif+#endif++/* Maximum value for windowBits in deflateInit2 and inflateInit2.+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files+ * created by gzip. (Files created by minigzip can still be extracted by+ * gzip.)+ */+#ifndef MAX_WBITS+# define MAX_WBITS 15 /* 32K LZ77 window */+#endif++/* The memory requirements for deflate are (in bytes):+ (1 << (windowBits+2)) + (1 << (memLevel+9))+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)+ plus a few kilobytes for small objects. For example, if you want to reduce+ the default memory requirements from 256K to 128K, compile with+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"+ Of course this will generally degrade compression (there's no free lunch).++ The memory requirements for inflate are (in bytes) 1 << windowBits+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes+ for small objects.+*/++ /* Type declarations */++#ifndef OF /* function prototypes */+# ifdef STDC+# define OF(args) args+# else+# define OF(args) ()+# endif+#endif++#ifndef Z_ARG /* function prototypes for stdarg */+# if defined(STDC) || defined(Z_HAVE_STDARG_H)+# define Z_ARG(args) args+# else+# define Z_ARG(args) ()+# endif+#endif++/* The following definitions for FAR are needed only for MSDOS mixed+ * model programming (small or medium model with some far allocations).+ * This was tested only with MSC; for other MSDOS compilers you may have+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,+ * just define FAR to be empty.+ */+#ifdef SYS16BIT+# if defined(M_I86SM) || defined(M_I86MM)+ /* MSC small or medium model */+# define SMALL_MEDIUM+# ifdef _MSC_VER+# define FAR _far+# else+# define FAR far+# endif+# endif+# if (defined(__SMALL__) || defined(__MEDIUM__))+ /* Turbo C small or medium model */+# define SMALL_MEDIUM+# ifdef __BORLANDC__+# define FAR _far+# else+# define FAR far+# endif+# endif+#endif++#if defined(WINDOWS) || defined(WIN32)+ /* If building or using zlib as a DLL, define ZLIB_DLL.+ * This is not mandatory, but it offers a little performance increase.+ */+# ifdef ZLIB_DLL+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))+# ifdef ZLIB_INTERNAL+# define ZEXTERN extern __declspec(dllexport)+# else+# define ZEXTERN extern __declspec(dllimport)+# endif+# endif+# endif /* ZLIB_DLL */+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,+ * define ZLIB_WINAPI.+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.+ */+# ifdef ZLIB_WINAPI+# ifdef FAR+# undef FAR+# endif+# include <windows.h>+ /* No need for _export, use ZLIB.DEF instead. */+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */+# define ZEXPORT WINAPI+# ifdef WIN32+# define ZEXPORTVA WINAPIV+# else+# define ZEXPORTVA FAR CDECL+# endif+# endif+#endif++#if defined (__BEOS__)+# ifdef ZLIB_DLL+# ifdef ZLIB_INTERNAL+# define ZEXPORT __declspec(dllexport)+# define ZEXPORTVA __declspec(dllexport)+# else+# define ZEXPORT __declspec(dllimport)+# define ZEXPORTVA __declspec(dllimport)+# endif+# endif+#endif++#ifndef ZEXTERN+# define ZEXTERN extern+#endif+#ifndef ZEXPORT+# define ZEXPORT+#endif+#ifndef ZEXPORTVA+# define ZEXPORTVA+#endif++#ifndef FAR+# define FAR+#endif++#if !defined(__MACTYPES__)+typedef unsigned char Byte; /* 8 bits */+#endif+typedef unsigned int uInt; /* 16 bits or more */+typedef unsigned long uLong; /* 32 bits or more */++#ifdef SMALL_MEDIUM+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */+# define Bytef Byte FAR+#else+ typedef Byte FAR Bytef;+#endif+typedef char FAR charf;+typedef int FAR intf;+typedef uInt FAR uIntf;+typedef uLong FAR uLongf;++#ifdef STDC+ typedef void const *voidpc;+ typedef void FAR *voidpf;+ typedef void *voidp;+#else+ typedef Byte const *voidpc;+ typedef Byte FAR *voidpf;+ typedef Byte *voidp;+#endif++#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)+# include <limits.h>+# if (UINT_MAX == 0xffffffffUL)+# define Z_U4 unsigned+# elif (ULONG_MAX == 0xffffffffUL)+# define Z_U4 unsigned long+# elif (USHRT_MAX == 0xffffffffUL)+# define Z_U4 unsigned short+# endif+#endif++#ifdef Z_U4+ typedef Z_U4 z_crc_t;+#else+ typedef unsigned long z_crc_t;+#endif++#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */+# define Z_HAVE_UNISTD_H+#endif++#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */+# define Z_HAVE_STDARG_H+#endif++#ifdef STDC+# ifndef Z_SOLO+# include <sys/types.h> /* for off_t */+# endif+#endif++#if defined(STDC) || defined(Z_HAVE_STDARG_H)+# ifndef Z_SOLO+# include <stdarg.h> /* for va_list */+# endif+#endif++#ifdef _WIN32+# ifndef Z_SOLO+# include <stddef.h> /* for wchar_t */+# endif+#endif++/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even+ * though the former does not conform to the LFS document), but considering+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as+ * equivalently requesting no 64-bit operations+ */+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1+# undef _LARGEFILE64_SOURCE+#endif++#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)+# define Z_HAVE_UNISTD_H+#endif+#ifndef Z_SOLO+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */+# ifdef VMS+# include <unixio.h> /* for off_t */+# endif+# ifndef z_off_t+# define z_off_t off_t+# endif+# endif+#endif++#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0+# define Z_LFS64+#endif++#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)+# define Z_LARGE64+#endif++#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)+# define Z_WANT64+#endif++#if !defined(SEEK_SET) && !defined(Z_SOLO)+# define SEEK_SET 0 /* Seek from beginning of file. */+# define SEEK_CUR 1 /* Seek from current position. */+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */+#endif++#ifndef z_off_t+# define z_off_t long+#endif++#if !defined(_WIN32) && defined(Z_LARGE64)+# define z_off64_t off64_t+#else+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)+# define z_off64_t __int64+# else+# define z_off64_t z_off_t+# endif+#endif++/* MVS linker does not support external names larger than 8 bytes */+#if defined(__MVS__)+ #pragma map(deflateInit_,"DEIN")+ #pragma map(deflateInit2_,"DEIN2")+ #pragma map(deflateEnd,"DEEND")+ #pragma map(deflateBound,"DEBND")+ #pragma map(inflateInit_,"ININ")+ #pragma map(inflateInit2_,"ININ2")+ #pragma map(inflateEnd,"INEND")+ #pragma map(inflateSync,"INSY")+ #pragma map(inflateSetDictionary,"INSEDI")+ #pragma map(compressBound,"CMBND")+ #pragma map(inflate_table,"INTABL")+ #pragma map(inflate_fast,"INFA")+ #pragma map(inflate_copyright,"INCOPY")+#endif++#endif /* ZCONF_H */