netlines (empty) → 0.1.0
raw patch · 4 files changed
+172/−0 lines, 4 filesdep +basedep +bytestringdep +contstuffsetup-changed
Dependencies added: base, bytestring, contstuff, enumerator
Files
- LICENSE +32/−0
- Network/NetLines.hs +100/−0
- Setup.lhs +12/−0
- netlines.cabal +28/−0
+ LICENSE view
@@ -0,0 +1,32 @@+netlines license+Copyright (c) 2010, Ertugrul Soeylemez++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in+ the documentation and/or other materials provided with the+ distribution.++ * Neither the name of the author nor the names of any contributors+ may be used to endorse or promote products derived from this+ software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Network/NetLines.hs view
@@ -0,0 +1,100 @@+-- |+-- Module: Network.NetLines+-- Copyright: (c) 2010 Ertugrul Soeylemez+-- License: BSD3+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>+-- Stability: experimental+--+-- Enumerator tools for working with text-based network protocols.++{-# LANGUAGE ScopedTypeVariables #-}++module Network.NetLines+ ( -- * Conversion to lines+ netLine,+ netLines,++ -- * Enumerators+ enumHandleTimeout+ )+ where++import qualified Data.ByteString as B+import Control.ContStuff+import Data.ByteString (ByteString)+import Data.Enumerator as E+import Data.Enumerator.Binary as EB+import Data.Word+import System.IO+import System.IO.Error as IOErr+++-- | Enumerate from a handle with the given buffer size (first argument)+-- and timeout in milliseconds (second argument). If the timeout is+-- exceeded an exception is thrown via 'throwError'.++enumHandleTimeout :: forall b m. MonadIO m =>+ Int -> Int -> Handle -> Enumerator ByteString m b+enumHandleTimeout bufSize timeout h = loop+ where+ loop :: Enumerator ByteString m b+ loop (Continue k) = do+ mHaveInput <- liftIO $ IOErr.try (hWaitForInput h timeout)+ case mHaveInput of+ Left err+ | isEOFError err -> continue k+ | otherwise -> throwError err+ Right False -> throwError $ userError "Handle timed out"+ Right True -> do+ mStr <- liftIO $ IOErr.try (B.hGetNonBlocking h bufSize)+ str <- either throwError return mStr+ if B.null str+ then continue k+ else k (Chunks [str]) >>== loop+ loop step = returnI step+++-- | Savely read a line with the given maximum length. If a longer line+-- is enumerated, the excess data is dropped in constant space. Returns+-- 'Nothing' on EOF.+--+-- Please note that this function is very error-tolerant in the way it+-- handles line endings. Both CR and LF are proper line terminators.+-- This function ignores empty lines.++netLine :: forall m r. Monad m => Int -> MaybeT r (Iteratee ByteString m) ByteString+netLine n =+ lift (EB.dropWhile isEol) >> netLine' n++ where+ isEol :: Word8 -> Bool+ isEol 10 = True+ isEol 13 = True+ isEol _ = False++ isNotEol :: Word8 -> Bool+ isNotEol = not . isEol++ netLine' :: Int -> MaybeT r (Iteratee ByteString m) ByteString+ netLine' 0 = B.empty <$ lift (EB.dropWhile isNotEol)+ netLine' n = do+ c <- liftF EB.head+ if isNotEol c+ then B.cons c <$> netLine' (n-1)+ else return B.empty+++-- | Convert a stream of bytes to a stream of lines with the given+-- maximum length. Longer lines are silently truncated in constant+-- space.++netLines :: forall b m. Monad m => Int -> Enumeratee ByteString ByteString m b+netLines maxLen = loop+ where+ loop :: Enumeratee ByteString ByteString m b+ loop (Continue k) = do+ mLine <- evalMaybeT $ netLine maxLen+ case mLine of+ Just line -> k (Chunks [line]) >>== loop+ Nothing -> k EOF >>== loop+ loop step = return step
+ Setup.lhs view
@@ -0,0 +1,12 @@+netlines setup script+Copyright (C) 2010, Ertugrul Soeylemez++Please see the LICENSE file for terms and conditions of use,+modification and distribution of this package, including this file.++> module Main where+>+> import Distribution.Simple+>+> main :: IO ()+> main = defaultMain
+ netlines.cabal view
@@ -0,0 +1,28 @@+Name: netlines+Version: 0.1.0+Category: Network+Synopsis: Enumerator tools for text-based network protocols+Maintainer: Ertugrul Söylemez <es@ertes.de>+Author: Ertugrul Söylemez <es@ertes.de>+Copyright: (c) 2010 Ertugrul Söylemez+License: BSD3+License-file: LICENSE+Build-type: Simple+Stability: experimental+Cabal-version: >= 1.6+Description:++ Enumerator tools for text-based network protocols. This includes,+ among other things, an enumeratee to split an incoming ByteString+ stream to a length-limited line stream in a safe manner+ (i.e. constant space).++Library+ Build-depends:+ base >= 4 && <= 5,+ bytestring >= 0.9.1.7,+ contstuff >= 1.2.4,+ enumerator >= 0.4.7+ GHC-Options: -W+ Exposed-modules:+ Network.NetLines