{-# LINE 1 "Network/Socket/ByteString/Lazy.hsc" #-}{-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface #-}{-# LINE 2 "Network/Socket/ByteString/Lazy.hsc" #-}-- |-- Module : Network.Socket.ByteString.Lazy-- Copyright : (c) Bryan O'Sullivan 2009-- License : BSD-style---- Maintainer : bos@serpentine.com-- Stability : experimental-- Portability : POSIX, GHC---- This module provides access to the BSD /socket/ interface. This-- module is generally more efficient than the 'String' based network-- functions in 'Network.Socket'. For detailed documentation, consult-- your favorite POSIX socket reference. All functions communicate-- failures by converting the error number to 'System.IO.IOError'.---- This module is made to be imported with 'Network.Socket' like so:---- > import Network.Socket hiding (send, sendTo, recv, recvFrom)-- > import Network.Socket.ByteString.Lazy-- > import Prelude hiding (getContents)--moduleNetwork.Socket.ByteString.Lazy({-# LINE 27 "Network/Socket/ByteString/Lazy.hsc" #-}-- * Send data to a socketsend,sendAll,{-# LINE 31 "Network/Socket/ByteString/Lazy.hsc" #-}-- * Receive data from a socketgetContents,recv)whereimportControl.Monad(liftM)importData.ByteString.Lazy.Internal(ByteString(..),defaultChunkSize)importData.Int(Int64)importNetwork.Socket(Socket(..),ShutdownCmd(..),shutdown)importPreludehiding(getContents)importSystem.IO.Unsafe(unsafeInterleaveIO)importqualifiedData.ByteStringasSimportqualifiedNetwork.Socket.ByteStringasN{-# LINE 48 "Network/Socket/ByteString/Lazy.hsc" #-}importControl.Monad(unless)importData.ByteString.Unsafe(unsafeUseAsCStringLen)importForeign.Marshal.Array(allocaArray)importForeign.Ptr(plusPtr)importForeign.Storable(Storable(..))importNetwork.Socket.ByteString.IOVec(IOVec(IOVec))importNetwork.Socket.ByteString.Internal(c_writev)importNetwork.Socket.Internal(throwSocketErrorIfMinus1RetryMayBlock)importqualifiedData.ByteString.LazyasL{-# LINE 60 "Network/Socket/ByteString/Lazy.hsc" #-}importGHC.Conc(threadWaitWrite){-# LINE 62 "Network/Socket/ByteString/Lazy.hsc" #-}{-# LINE 63 "Network/Socket/ByteString/Lazy.hsc" #-}{-# LINE 65 "Network/Socket/ByteString/Lazy.hsc" #-}-- ------------------------------------------------------------------------------- Sending-- | Send data to the socket. The socket must be in a connected state.-- Returns the number of bytes sent. Applications are responsible for-- ensuring that all data has been sent.---- Because a lazily generated 'ByteString' may be arbitrarily long,-- this function caps the amount it will attempt to send at 4MB. This-- number is large (so it should not penalize performance on fast-- networks), but not outrageously so (to avoid demanding lazily-- computed data unnecessarily early). Before being sent, the lazy-- 'ByteString' will be converted to a list of strict 'ByteString's-- with 'L.toChunks'; at most 1024 chunks will be sent. /Unix only/.send::Socket-- ^ Connected socket->ByteString-- ^ Data to send->IOInt64-- ^ Number of bytes sentsend(MkSocketfd____)s=doletcs=takemaxNumChunks(L.toChunkss)len=lengthcsliftMfromIntegral.allocaArraylen$\ptr->withPokescsptr$\niovs->{-# LINE 88 "Network/Socket/ByteString/Lazy.hsc" #-}throwSocketErrorIfMinus1RetryMayBlock"writev"(threadWaitWrite(fromIntegralfd))${-# LINE 91 "Network/Socket/ByteString/Lazy.hsc" #-}c_writev(fromIntegralfd)ptrniovswherewithPokessspf=loopssp00whereloop(c:cs)qk!niovs|k<maxNumBytes=unsafeUseAsCStringLenc$\(ptr,len)->dopokeq$IOVecptr(fromIntegrallen)loopcs(q`plusPtr`sizeOf(undefined::IOVec))(k+fromIntegrallen)(niovs+1)|otherwise=fniovsloop___niovs=fniovsmaxNumBytes=4194304::Int-- maximum number of bytes to transmit in one system callmaxNumChunks=1024::Int-- maximum number of chunks to transmit in one system call-- | Send data to the socket. The socket must be in a connected-- state. This function continues to send data until either all data-- has been sent or an error occurs. If there is an error, an-- exception is raised, and there is no way to determine how much data-- was sent. /Unix only/.sendAll::Socket-- ^ Connected socket->ByteString-- ^ Data to send->IO()sendAllsockbs=dosent<-sendsockbsletbs'=L.dropsentbsunless(L.nullbs')$sendAllsockbs'{-# LINE 118 "Network/Socket/ByteString/Lazy.hsc" #-}-- ------------------------------------------------------------------------------- Receiving-- | Receive data from the socket. The socket must be in a connected-- state. Data is received on demand, in chunks; each chunk will be-- sized to reflect the amount of data received by individual 'recv'-- calls.---- All remaining data from the socket is consumed. When there is no-- more data to be received, the receiving side of the socket is shut-- down. If there is an error and an exception is thrown, the socket-- is not shut down.getContents::Socket-- ^ Connected socket->IOByteString-- ^ Data receivedgetContentssock=loopwhereloop=unsafeInterleaveIO$dos<-N.recvsockdefaultChunkSizeifS.nullsthenshutdownsockShutdownReceive>>returnEmptyelseChunks`liftM`loop-- | Receive data from the socket. The socket must be in a connected-- state. This function may return fewer bytes than specified. If-- the received data is longer than the specified length, it may be-- discarded depending on the type of socket. This function may block-- until a message arrives.---- If there is no more data to be received, returns an empty 'ByteString'.recv::Socket-- ^ Connected socket->Int64-- ^ Maximum number of bytes to receive->IOByteString-- ^ Data receivedrecvsocknbytes=chunk`liftM`N.recvsock(fromIntegralnbytes)wherechunkk|S.nullk=Empty|otherwise=ChunkkEmpty