X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FIO%2FBuffer.hs;h=70967772a4dc96f0f324bd4a34aea15a5eabcdbe;hb=7d39e10019df33f1a19d65b3c58c4d01a7dc8d30;hp=65e718458783c11323c8cbfbf2b939ad2c6448f7;hpb=2c7c50ca5e6f9bf1eebf70ba633c77027952edef;p=ghc-base.git diff --git a/GHC/IO/Buffer.hs b/GHC/IO/Buffer.hs index 65e7184..7096777 100644 --- a/GHC/IO/Buffer.hs +++ b/GHC/IO/Buffer.hs @@ -160,19 +160,21 @@ charSize = 4 -- --------------------------------------------------------------------------- -- Buffers --- The buffer is represented by a mutable variable containing a --- record, where the record contains the raw buffer and the start/end --- points of the filled portion. We use a mutable variable so that --- the common operation of writing (or reading) some data from (to) --- the buffer doesn't need to modify, and hence copy, the handle --- itself, it just updates the buffer. - --- There will be some allocation involved in a simple hPutChar in --- order to create the new Buffer structure (below), but this is --- relatively small, and this only has to be done once per write --- operation. - -- | A mutable array of bytes that can be passed to foreign functions. +-- +-- The buffer is represented by a record, where the record contains +-- the raw buffer and the start/end points of the filled portion. The +-- buffer contents itself is mutable, but the rest of the record is +-- immutable. This is a slightly odd mix, but it turns out to be +-- quite practical: by making all the buffer metadata immutable, we +-- can have operations on buffer metadata outside of the IO monad. +-- +-- The "live" elements of the buffer are those between the 'bufL' and +-- 'bufR' offsets. In an empty buffer, 'bufL' is equal to 'bufR', but +-- they might not be zero: for exmaple, the buffer might correspond to +-- a memory-mapped file and in which case 'bufL' will point to the +-- next location to be written, which is not necessarily the beginning +-- of the file. data Buffer e = Buffer { bufRaw :: !(RawBuffer e), @@ -197,7 +199,7 @@ withRawBuffer :: RawBuffer e -> (Ptr e -> IO a) -> IO a withRawBuffer raw f = withForeignPtr (castForeignPtr raw) f isEmptyBuffer :: Buffer e -> Bool -isEmptyBuffer Buffer{ bufR=w } = w == 0 +isEmptyBuffer Buffer{ bufL=l, bufR=r } = l == r isFullBuffer :: Buffer e -> Bool isFullBuffer Buffer{ bufR=w, bufSize=s } = s == w @@ -264,8 +266,7 @@ summaryBuffer buf = "buf" ++ show (bufSize buf) ++ "(" ++ show (bufL buf) ++ "-" -- INVARIANTS on Buffers: -- * r <= w --- * if r == w, then r == 0 && w == 0 --- * if state == WriteBuffer, then r == 0 +-- * if r == w, and the buffer is for reading, then r == 0 && w == 0 -- * a write buffer is never full. If an operation -- fills up the buffer, it will always flush it before -- returning. @@ -278,8 +279,7 @@ checkBuffer buf@Buffer{ bufState = state, bufL=r, bufR=w, bufSize=size } = do size > 0 && r <= w && w <= size - && ( r /= w || (r == 0 && w == 0) ) - && ( state /= WriteBuffer || r == 0 ) + && ( r /= w || state == WriteBuffer || (r == 0 && w == 0) ) && ( state /= WriteBuffer || w < size ) -- write buffer is never full )