packages feed

Data-Rope 0.1 → 0.2

raw patch · 4 files changed

+113/−9 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Rope: elemIndex' :: Word8 -> Rope -> Maybe Int
+ Data.Rope: hGetContents :: Handle -> IO Rope
+ Data.Rope: hGetLine :: Handle -> IO Rope
+ Data.Rope.Internals: c2w :: Char -> Word8
+ Data.Rope.Internals: w2c :: Word8 -> Char

Files

Data-Rope.cabal view
@@ -1,5 +1,5 @@ Name:		Data-Rope-Version: 	0.1+Version: 	0.2 Synopsis:	Ropes, an alternative to (Byte)Strings. Description: 	Ropes : an alternative to Strings, 		a time and space-efficient representation of character
Data/Rope.lhs view
@@ -46,10 +46,13 @@   -- * Indexing 'Rope's   index,   elemIndex,+  elemIndex',   elemIndices,   -- * Input and Output   readFile,   hGet,+  hGetLine,+  hGetContents,   hPut,   hPutStrLn,   hPutStr,@@ -72,7 +75,7 @@ import qualified Data.ByteString.Internal as B import Data.String import Data.Word-+import Control.Exception (finally) #if __GLASGOW_HASKELL__ >=608 import GHC.IO (IO(IO),unsafePerformIO,unsafeInterleaveIO) import GHC.Base (realWorld#)@@ -83,11 +86,13 @@ import System.IO.Unsafe #endif import Data.Maybe-import GHC.Conc+import GHC.Conc (par)  import System.Posix (openFd,closeFd,defaultFileFlags,getFileStatus,                      fileSize,OpenMode(..))-import System.IO hiding (hPutStrLn,hPutStr,putStrLn,putStr,readFile)+import System.IO (hGetBuf,hPutBuf,hSeek,hTell,hFileSize,+                  hPutChar, stdout, hClose)+ import qualified Prelude(length,map,splitAt) import Prelude hiding (length,null,head,tail,last,init,map,reverse,                        foldl,foldr,@@ -298,7 +303,7 @@ -} -- | O(1) Tests whether a 'Rope' is empty. null::Rope->Bool-null x=length x>0+null x=length x==0  -- | O(1) Length of a 'Rope'. length::Rope->Int@@ -626,12 +631,13 @@       index_ (Concat{r,l}) i_         |i_>=length l = index_ r (i_-length l)         |otherwise = index_ l i_+                     {-       index_ (File{handle,position}) i_=         unsafePerformIO $ alloca $ \cc->do           hSeek handle AbsoluteSeek $ fromIntegral $ position+i_           hGetBuf handle cc 1           peek cc-+-}  -- | O(n) returns the index of the first element equal to the query element. This implementation -- uses memchr at leaves, and explores the rope in parallel (with 'GHC.Conc.par').@@ -664,6 +670,36 @@         x<-peek ptr         if x==w then return $ Just i else loop (ptr`plusPtr`1) (i+1) l +-- | O(n) Same as 'elemIndex', but explores the 'Rope' sequentially. Useful for+-- 'Rope's loaded lazily with 'readFile'.++elemIndex'::Word8->Rope->Maybe Int+elemIndex' w rope=+  elemIndex_ 0 rope+  where+    elemIndex_ i (String{contents,offset,length_})=+      inlinePerformIO $ withForeignPtr contents $ \con->do+        ptr<-memchr (con`plusPtr`offset) w (fromIntegral length_)+        return $ if ptr==nullPtr then Nothing else Just $ i+offset+(ptr`minusPtr`con)+        +    elemIndex_ i (Concat{l,r})=+      case elemIndex_ i l of+        Nothing->elemIndex_ (i+length l) r+        a->a+       +    elemIndex_ i (File{handle,position,length_})=+      unsafePerformIO $ allocaBytes length_ $ \c->do+        hSeek handle AbsoluteSeek $ fromIntegral position+        l<-hGetBuf handle c length_+        x<-loop c 0 l+        return $ x>>=(return.(+i))+      +    loop ptr i l+      | i>=l = return Nothing+      | otherwise = do+        x<-peek ptr+        if x==w then return $ Just i else loop (ptr`plusPtr`1) (i+1) l+ -- | O(n) returns the list of all positions where the queried elements occurs in the 'Rope'. -- This implementation uses memchr. @@ -921,8 +957,7 @@ putStrLn::Rope->IO() putStrLn=hPutStrLn stdout   --+-- | fromPtr encapsule un pointeur, un offset et une longueur dans un @Rope@.. fromPtr::ForeignPtr Word8->Int->Int->IO Rope fromPtr fp offset s   | s<=leafSize = withForeignPtr fp $ \p->do@@ -983,6 +1018,7 @@   fromPtr fp 0 (fromIntegral s)  + -- | Strict hGet. The whole rope is constructed. hGet::Handle->Int->IO Rope hGet handle length_=do@@ -1012,5 +1048,55 @@           bb<-buildRope handle (position+fromIntegral a) b           return $ Concat { length_=len,l=aa,r=bb,sizeC=size aa+size bb }   +-- | Returns the next line in the input 'Handle'. If you need to iterate 'hGetLine',+-- it may be more efficient to first @mmap@ the file using 'readFile', or even load+-- it with then iterate+-- @'breakByte' 0x0a@ : 'hGetLine' allocates a buffer to read the file+-- and may waste most of this space if the lines are shorter than the standard buffer+-- size of this module.+hGetLine::Handle->IO Rope+hGetLine h=+  hGetLine' empty+  +  where+    hGetLine' x=do+      contents<-mallocForeignPtrBytes leafSize+      withForeignPtr contents $ \con->do+        l<-hGetBuf h con leafSize+        let readBytes=min l leafSize+        if readBytes<=0 then return x else do+          ptr<-memchr con 0x0a (fromIntegral readBytes)+          if ptr==nullPtr then do+            i0<-mallocForeignPtr+            withForeignPtr i0 $ \i->poke i readBytes+            let y=String { contents,i0,offset=0,length_=readBytes }+            hGetLine' (x`append`y)+          +            else do+          +            i0<-mallocForeignPtr+            let lineLen=ptr`minusPtr`con+                y=String { contents,i0,offset=0,length_=lineLen }+            withForeignPtr i0 $ \i->poke i lineLen+            hSeek h RelativeSeek (fromIntegral $ lineLen-readBytes+1)+            return $ x`append`y+          +-- | Reads the contents of a file handle strictly, then closes it.++hGetContents::Handle->IO Rope+hGetContents h=finally (hGetContents' empty) (hClose h)++  where+    hGetContents' r=do+      contents<-mallocForeignPtrBytes leafSize+      withForeignPtr contents $ \l->do+        x<-hGetBuf h l leafSize+        i0<-mallocForeignPtr+        withForeignPtr i0 $ \i->poke i x+        let y=String { contents,i0,offset=0,length_=x }++        if x==0 then return r else+          if x<leafSize then return $ r`append`y else+            hGetContents' $ r`append`y \end{code} 
+ Data/Rope/Char8.lhs view
@@ -0,0 +1,11 @@+\begin{code}+module Data.Rope.Char8 where++import qualified Data.Rope as R+import Data.Rope.Internals++singleton::Word8->Rope+singleton x=(R.singleton).w2c+++\end{code}
Data/Rope/Internals.hsc view
@@ -7,7 +7,7 @@ import Foreign.Storable import Foreign.C.Types import Data.Word-+import GHC.Base  foreign import ccall unsafe "sys/mman.h mmap" c_mmap::   Ptr a->CSize->CInt->CInt->CInt->CInt->IO (Ptr Word8)@@ -32,3 +32,10 @@  c_MAP_FILE::CInt c_MAP_FILE= #const MAP_FILE+++w2c::Word8->Char+w2c=unsafeChr.fromIntegral++c2w::Char->Word8+c2w=fromIntegral.ord