<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --> <title>GHC/IO/Buffer.hs</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head> <body> <pre><a name="line-1"></a><span class='hs-comment'>{-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields #-}</span> <a name="line-2"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-3"></a><span class='hs-comment'>-- |</span> <a name="line-4"></a><span class='hs-comment'>-- Module : GHC.IO.Buffer</span> <a name="line-5"></a><span class='hs-comment'>-- Copyright : (c) The University of Glasgow 2008</span> <a name="line-6"></a><span class='hs-comment'>-- License : see libraries/base/LICENSE</span> <a name="line-7"></a><span class='hs-comment'>-- </span> <a name="line-8"></a><span class='hs-comment'>-- Maintainer : cvs-ghc@haskell.org</span> <a name="line-9"></a><span class='hs-comment'>-- Stability : internal</span> <a name="line-10"></a><span class='hs-comment'>-- Portability : non-portable (GHC Extensions)</span> <a name="line-11"></a><span class='hs-comment'>--</span> <a name="line-12"></a><span class='hs-comment'>-- Buffers used in the IO system</span> <a name="line-13"></a><span class='hs-comment'>--</span> <a name="line-14"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-15"></a> <a name="line-16"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Buffer</span> <span class='hs-layout'>(</span> <a name="line-17"></a> <span class='hs-comment'>-- * Buffers of any element</span> <a name="line-18"></a> <span class='hs-conid'>Buffer</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>BufferState</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>CharBuffer</span><span class='hs-layout'>,</span> <span class='hs-conid'>CharBufElem</span><span class='hs-layout'>,</span> <a name="line-19"></a> <a name="line-20"></a> <span class='hs-comment'>-- ** Creation</span> <a name="line-21"></a> <span class='hs-varid'>newByteBuffer</span><span class='hs-layout'>,</span> <a name="line-22"></a> <span class='hs-varid'>newCharBuffer</span><span class='hs-layout'>,</span> <a name="line-23"></a> <span class='hs-varid'>newBuffer</span><span class='hs-layout'>,</span> <a name="line-24"></a> <span class='hs-varid'>emptyBuffer</span><span class='hs-layout'>,</span> <a name="line-25"></a> <a name="line-26"></a> <span class='hs-comment'>-- ** Insertion/removal</span> <a name="line-27"></a> <span class='hs-varid'>bufferRemove</span><span class='hs-layout'>,</span> <a name="line-28"></a> <span class='hs-varid'>bufferAdd</span><span class='hs-layout'>,</span> <a name="line-29"></a> <span class='hs-varid'>slideContents</span><span class='hs-layout'>,</span> <a name="line-30"></a> <span class='hs-varid'>bufferAdjustL</span><span class='hs-layout'>,</span> <a name="line-31"></a> <a name="line-32"></a> <span class='hs-comment'>-- ** Inspecting</span> <a name="line-33"></a> <span class='hs-varid'>isEmptyBuffer</span><span class='hs-layout'>,</span> <a name="line-34"></a> <span class='hs-varid'>isFullBuffer</span><span class='hs-layout'>,</span> <a name="line-35"></a> <span class='hs-varid'>isFullCharBuffer</span><span class='hs-layout'>,</span> <a name="line-36"></a> <span class='hs-varid'>isWriteBuffer</span><span class='hs-layout'>,</span> <a name="line-37"></a> <span class='hs-varid'>bufferElems</span><span class='hs-layout'>,</span> <a name="line-38"></a> <span class='hs-varid'>bufferAvailable</span><span class='hs-layout'>,</span> <a name="line-39"></a> <span class='hs-varid'>summaryBuffer</span><span class='hs-layout'>,</span> <a name="line-40"></a> <a name="line-41"></a> <span class='hs-comment'>-- ** Operating on the raw buffer as a Ptr</span> <a name="line-42"></a> <span class='hs-varid'>withBuffer</span><span class='hs-layout'>,</span> <a name="line-43"></a> <span class='hs-varid'>withRawBuffer</span><span class='hs-layout'>,</span> <a name="line-44"></a> <a name="line-45"></a> <span class='hs-comment'>-- ** Assertions</span> <a name="line-46"></a> <span class='hs-varid'>checkBuffer</span><span class='hs-layout'>,</span> <a name="line-47"></a> <a name="line-48"></a> <span class='hs-comment'>-- * Raw buffers</span> <a name="line-49"></a> <span class='hs-conid'>RawBuffer</span><span class='hs-layout'>,</span> <a name="line-50"></a> <span class='hs-varid'>readWord8Buf</span><span class='hs-layout'>,</span> <a name="line-51"></a> <span class='hs-varid'>writeWord8Buf</span><span class='hs-layout'>,</span> <a name="line-52"></a> <span class='hs-conid'>RawCharBuffer</span><span class='hs-layout'>,</span> <a name="line-53"></a> <span class='hs-varid'>peekCharBuf</span><span class='hs-layout'>,</span> <a name="line-54"></a> <span class='hs-varid'>readCharBuf</span><span class='hs-layout'>,</span> <a name="line-55"></a> <span class='hs-varid'>writeCharBuf</span><span class='hs-layout'>,</span> <a name="line-56"></a> <span class='hs-varid'>readCharBufPtr</span><span class='hs-layout'>,</span> <a name="line-57"></a> <span class='hs-varid'>writeCharBufPtr</span><span class='hs-layout'>,</span> <a name="line-58"></a> <span class='hs-varid'>charSize</span><span class='hs-layout'>,</span> <a name="line-59"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <a name="line-60"></a> <a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Base</span> <a name="line-62"></a><span class='hs-comment'>-- import GHC.IO</span> <a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Num</span> <a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Ptr</span> <a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span> <a name="line-66"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Show</span> <a name="line-67"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Real</span> <a name="line-68"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span> <a name="line-69"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>ForeignPtr</span> <a name="line-70"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>Storable</span> <a name="line-71"></a> <a name="line-72"></a><span class='hs-comment'>-- Char buffers use either UTF-16 or UTF-32, with the endianness matching</span> <a name="line-73"></a><span class='hs-comment'>-- the endianness of the host.</span> <a name="line-74"></a><span class='hs-comment'>--</span> <a name="line-75"></a><span class='hs-comment'>-- Invariants:</span> <a name="line-76"></a><span class='hs-comment'>-- * a Char buffer consists of *valid* UTF-16 or UTF-32</span> <a name="line-77"></a><span class='hs-comment'>-- * only whole characters: no partial surrogate pairs</span> <a name="line-78"></a> <a name="line-79"></a><span class='hs-cpp'>#define CHARBUF_UTF32</span> <a name="line-80"></a> <a name="line-81"></a><span class='hs-comment'>-- #define CHARBUF_UTF16</span> <a name="line-82"></a><span class='hs-comment'>--</span> <a name="line-83"></a><span class='hs-comment'>-- NB. it won't work to just change this to CHARBUF_UTF16. Some of</span> <a name="line-84"></a><span class='hs-comment'>-- the code to make this work is there, and it has been tested with</span> <a name="line-85"></a><span class='hs-comment'>-- the Iconv codec, but there are some pieces that are known to be</span> <a name="line-86"></a><span class='hs-comment'>-- broken. In particular, the built-in codecs</span> <a name="line-87"></a><span class='hs-comment'>-- e.g. GHC.IO.Encoding.UTF{8,16,32} need to use isFullCharBuffer or</span> <a name="line-88"></a><span class='hs-comment'>-- similar in place of the ow >= os comparisions.</span> <a name="line-89"></a> <a name="line-90"></a><span class='hs-comment'>-- ---------------------------------------------------------------------------</span> <a name="line-91"></a><span class='hs-comment'>-- Raw blocks of data</span> <a name="line-92"></a> <a name="line-93"></a><a name="RawBuffer"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ForeignPtr</span> <span class='hs-varid'>e</span> <a name="line-94"></a> <a name="line-95"></a><a name="readWord8Buf"></a><span class='hs-definition'>readWord8Buf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-conid'>Word8</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Word8</span> <a name="line-96"></a><span class='hs-definition'>readWord8Buf</span> <span class='hs-varid'>arr</span> <span class='hs-varid'>ix</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>arr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>peekByteOff</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <a name="line-97"></a> <a name="line-98"></a><a name="writeWord8Buf"></a><span class='hs-definition'>writeWord8Buf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-conid'>Word8</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Word8</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span> <a name="line-99"></a><span class='hs-definition'>writeWord8Buf</span> <span class='hs-varid'>arr</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>arr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>pokeByteOff</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>w</span> <a name="line-100"></a> <a name="line-101"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-102"></a><a name="CharBufElem"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CharBufElem</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Word16</span> <a name="line-103"></a><span class='hs-cpp'>#else</span> <a name="line-104"></a><a name="CharBufElem"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CharBufElem</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Char</span> <a name="line-105"></a><span class='hs-cpp'>#endif</span> <a name="line-106"></a> <a name="line-107"></a><a name="RawCharBuffer"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>RawCharBuffer</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-conid'>CharBufElem</span> <a name="line-108"></a> <a name="line-109"></a><a name="peekCharBuf"></a><span class='hs-definition'>peekCharBuf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawCharBuffer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Char</span> <a name="line-110"></a><span class='hs-definition'>peekCharBuf</span> <span class='hs-varid'>arr</span> <span class='hs-varid'>ix</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>arr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>do</span> <a name="line-111"></a> <span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>readCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <a name="line-112"></a> <span class='hs-varid'>return</span> <span class='hs-varid'>c</span> <a name="line-113"></a> <a name="line-114"></a><a name="readCharBuf"></a><span class='hs-comment'>{-# INLINE readCharBuf #-}</span> <a name="line-115"></a><span class='hs-definition'>readCharBuf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawCharBuffer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Char</span><span class='hs-layout'>,</span> <span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <a name="line-116"></a><span class='hs-definition'>readCharBuf</span> <span class='hs-varid'>arr</span> <span class='hs-varid'>ix</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>arr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>readCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <a name="line-117"></a> <a name="line-118"></a><a name="writeCharBuf"></a><span class='hs-comment'>{-# INLINE writeCharBuf #-}</span> <a name="line-119"></a><span class='hs-definition'>writeCharBuf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawCharBuffer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Char</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Int</span> <a name="line-120"></a><span class='hs-definition'>writeCharBuf</span> <span class='hs-varid'>arr</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>arr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>writeCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>c</span> <a name="line-121"></a> <a name="line-122"></a><a name="readCharBufPtr"></a><span class='hs-comment'>{-# INLINE readCharBufPtr #-}</span> <a name="line-123"></a><span class='hs-definition'>readCharBufPtr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ptr</span> <span class='hs-conid'>CharBufElem</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Char</span><span class='hs-layout'>,</span> <span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <a name="line-124"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-125"></a><span class='hs-definition'>readCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-126"></a> <span class='hs-varid'>c1</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>peekElemOff</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <a name="line-127"></a> <span class='hs-keyword'>if</span> <span class='hs-layout'>(</span><span class='hs-varid'>c1</span> <span class='hs-varop'><</span> <span class='hs-num'>0xd800</span> <span class='hs-varop'>||</span> <span class='hs-varid'>c1</span> <span class='hs-varop'>></span> <span class='hs-num'>0xdbff</span><span class='hs-layout'>)</span> <a name="line-128"></a> <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>chr</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>c1</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-129"></a> <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>c2</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>peekElemOff</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-130"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>unsafeChr</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>c1</span> <span class='hs-comment'>-</span> <span class='hs-num'>0xd800</span><span class='hs-layout'>)</span><span class='hs-varop'>*</span><span class='hs-num'>0x400</span> <span class='hs-varop'>+</span> <a name="line-131"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>c2</span> <span class='hs-comment'>-</span> <span class='hs-num'>0xdc00</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-num'>0x10000</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>2</span><span class='hs-layout'>)</span> <a name="line-132"></a><span class='hs-cpp'>#else</span> <a name="line-133"></a><span class='hs-definition'>readCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>peekElemOff</span> <span class='hs-layout'>(</span><span class='hs-varid'>castPtr</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>ix</span><span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-layout'>,</span> <span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-134"></a><span class='hs-cpp'>#endif</span> <a name="line-135"></a> <a name="line-136"></a><a name="writeCharBufPtr"></a><span class='hs-comment'>{-# INLINE writeCharBufPtr #-}</span> <a name="line-137"></a><span class='hs-definition'>writeCharBufPtr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ptr</span> <span class='hs-conid'>CharBufElem</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Char</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Int</span> <a name="line-138"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-139"></a><span class='hs-definition'>writeCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>ch</span> <a name="line-140"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>c</span> <span class='hs-varop'><</span> <span class='hs-num'>0x10000</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>pokeElemOff</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <a name="line-141"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-142"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>c'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>c</span> <span class='hs-comment'>-</span> <span class='hs-num'>0x10000</span> <a name="line-143"></a> <span class='hs-varid'>pokeElemOff</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-layout'>(</span><span class='hs-varid'>c'</span> <span class='hs-varop'>`div`</span> <span class='hs-num'>0x400</span> <span class='hs-varop'>+</span> <span class='hs-num'>0xd800</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-144"></a> <span class='hs-varid'>pokeElemOff</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-layout'>(</span><span class='hs-varid'>c'</span> <span class='hs-varop'>`mod`</span> <span class='hs-num'>0x400</span> <span class='hs-varop'>+</span> <span class='hs-num'>0xdc00</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-145"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>2</span><span class='hs-layout'>)</span> <a name="line-146"></a> <span class='hs-keyword'>where</span> <a name="line-147"></a> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ord</span> <span class='hs-varid'>ch</span> <a name="line-148"></a><span class='hs-cpp'>#else</span> <a name="line-149"></a><span class='hs-definition'>writeCharBufPtr</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>ch</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>pokeElemOff</span> <span class='hs-layout'>(</span><span class='hs-varid'>castPtr</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>ix</span> <span class='hs-varid'>ch</span><span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>ix</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-150"></a><span class='hs-cpp'>#endif</span> <a name="line-151"></a> <a name="line-152"></a><a name="charSize"></a><span class='hs-definition'>charSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <a name="line-153"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-154"></a><span class='hs-definition'>charSize</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>2</span> <a name="line-155"></a><span class='hs-cpp'>#else</span> <a name="line-156"></a><span class='hs-definition'>charSize</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>4</span> <a name="line-157"></a><span class='hs-cpp'>#endif</span> <a name="line-158"></a> <a name="line-159"></a><span class='hs-comment'>-- ---------------------------------------------------------------------------</span> <a name="line-160"></a><span class='hs-comment'>-- Buffers</span> <a name="line-161"></a> <a name="line-162"></a><a name="Buffer"></a><span class='hs-comment'>-- | A mutable array of bytes that can be passed to foreign functions.</span> <a name="line-163"></a><a name="Buffer"></a><span class='hs-comment'>--</span> <a name="line-164"></a><a name="Buffer"></a><span class='hs-comment'>-- The buffer is represented by a record, where the record contains</span> <a name="line-165"></a><a name="Buffer"></a><span class='hs-comment'>-- the raw buffer and the start/end points of the filled portion. The</span> <a name="line-166"></a><a name="Buffer"></a><span class='hs-comment'>-- buffer contents itself is mutable, but the rest of the record is</span> <a name="line-167"></a><a name="Buffer"></a><span class='hs-comment'>-- immutable. This is a slightly odd mix, but it turns out to be</span> <a name="line-168"></a><a name="Buffer"></a><span class='hs-comment'>-- quite practical: by making all the buffer metadata immutable, we</span> <a name="line-169"></a><a name="Buffer"></a><span class='hs-comment'>-- can have operations on buffer metadata outside of the IO monad.</span> <a name="line-170"></a><a name="Buffer"></a><span class='hs-comment'>--</span> <a name="line-171"></a><a name="Buffer"></a><span class='hs-comment'>-- The "live" elements of the buffer are those between the 'bufL' and</span> <a name="line-172"></a><a name="Buffer"></a><span class='hs-comment'>-- 'bufR' offsets. In an empty buffer, 'bufL' is equal to 'bufR', but</span> <a name="line-173"></a><a name="Buffer"></a><span class='hs-comment'>-- they might not be zero: for exmaple, the buffer might correspond to</span> <a name="line-174"></a><a name="Buffer"></a><span class='hs-comment'>-- a memory-mapped file and in which case 'bufL' will point to the</span> <a name="line-175"></a><a name="Buffer"></a><span class='hs-comment'>-- next location to be written, which is not necessarily the beginning</span> <a name="line-176"></a><a name="Buffer"></a><span class='hs-comment'>-- of the file.</span> <a name="line-177"></a><a name="Buffer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <a name="line-178"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Buffer</span> <span class='hs-layout'>{</span> <a name="line-179"></a> <span class='hs-varid'>bufRaw</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-layout'>(</span><span class='hs-conid'>RawBuffer</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-180"></a> <span class='hs-varid'>bufState</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BufferState</span><span class='hs-layout'>,</span> <a name="line-181"></a> <span class='hs-varid'>bufSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- in elements, not bytes</span> <a name="line-182"></a> <span class='hs-varid'>bufL</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- offset of first item in the buffer</span> <a name="line-183"></a> <span class='hs-varid'>bufR</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Int</span> <span class='hs-comment'>-- offset of last item + 1</span> <a name="line-184"></a> <span class='hs-layout'>}</span> <a name="line-185"></a> <a name="line-186"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-187"></a><a name="CharBuffer"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CharBuffer</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Buffer</span> <span class='hs-conid'>Word16</span> <a name="line-188"></a><span class='hs-cpp'>#else</span> <a name="line-189"></a><a name="CharBuffer"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CharBuffer</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Buffer</span> <span class='hs-conid'>Char</span> <a name="line-190"></a><span class='hs-cpp'>#endif</span> <a name="line-191"></a> <a name="line-192"></a><a name="BufferState"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>BufferState</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ReadBuffer</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>WriteBuffer</span> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>)</span> <a name="line-193"></a> <a name="line-194"></a><a name="withBuffer"></a><span class='hs-definition'>withBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Ptr</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <a name="line-195"></a><span class='hs-definition'>withBuffer</span> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufRaw</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>raw</span> <span class='hs-layout'>}</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-layout'>(</span><span class='hs-varid'>castForeignPtr</span> <span class='hs-varid'>raw</span><span class='hs-layout'>)</span> <span class='hs-varid'>f</span> <a name="line-196"></a> <a name="line-197"></a><a name="withRawBuffer"></a><span class='hs-definition'>withRawBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Ptr</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <a name="line-198"></a><span class='hs-definition'>withRawBuffer</span> <span class='hs-varid'>raw</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-layout'>(</span><span class='hs-varid'>castForeignPtr</span> <span class='hs-varid'>raw</span><span class='hs-layout'>)</span> <span class='hs-varid'>f</span> <a name="line-199"></a> <a name="line-200"></a><a name="isEmptyBuffer"></a><span class='hs-definition'>isEmptyBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-201"></a><span class='hs-definition'>isEmptyBuffer</span> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>r</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>l</span> <span class='hs-varop'>==</span> <span class='hs-varid'>r</span> <a name="line-202"></a> <a name="line-203"></a><a name="isFullBuffer"></a><span class='hs-definition'>isFullBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-204"></a><span class='hs-definition'>isFullBuffer</span> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufSize</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>s</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>==</span> <span class='hs-varid'>w</span> <a name="line-205"></a> <a name="line-206"></a><a name="isFullCharBuffer"></a><span class='hs-comment'>-- if a Char buffer does not have room for a surrogate pair, it is "full"</span> <a name="line-207"></a><span class='hs-definition'>isFullCharBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-208"></a><span class='hs-cpp'>#ifdef CHARBUF_UTF16</span> <a name="line-209"></a><span class='hs-definition'>isFullCharBuffer</span> <span class='hs-varid'>buf</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bufferAvailable</span> <span class='hs-varid'>buf</span> <span class='hs-varop'><</span> <span class='hs-num'>2</span> <a name="line-210"></a><span class='hs-cpp'>#else</span> <a name="line-211"></a><span class='hs-definition'>isFullCharBuffer</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isFullBuffer</span> <a name="line-212"></a><span class='hs-cpp'>#endif</span> <a name="line-213"></a> <a name="line-214"></a><a name="isWriteBuffer"></a><span class='hs-definition'>isWriteBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-215"></a><span class='hs-definition'>isWriteBuffer</span> <span class='hs-varid'>buf</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>bufState</span> <span class='hs-varid'>buf</span> <span class='hs-keyword'>of</span> <a name="line-216"></a> <span class='hs-conid'>WriteBuffer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>True</span> <a name="line-217"></a> <span class='hs-conid'>ReadBuffer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>False</span> <a name="line-218"></a> <a name="line-219"></a><a name="bufferElems"></a><span class='hs-definition'>bufferElems</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <a name="line-220"></a><span class='hs-definition'>bufferElems</span> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>r</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>w</span> <span class='hs-comment'>-</span> <span class='hs-varid'>r</span> <a name="line-221"></a> <a name="line-222"></a><a name="bufferAvailable"></a><span class='hs-definition'>bufferAvailable</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <a name="line-223"></a><span class='hs-definition'>bufferAvailable</span> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufSize</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>s</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-comment'>-</span> <span class='hs-varid'>w</span> <a name="line-224"></a> <a name="line-225"></a><a name="bufferRemove"></a><span class='hs-definition'>bufferRemove</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <a name="line-226"></a><span class='hs-definition'>bufferRemove</span> <span class='hs-varid'>i</span> <span class='hs-varid'>buf</span><span class='hs-keyglyph'>@</span><span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>r</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bufferAdjustL</span> <span class='hs-layout'>(</span><span class='hs-varid'>r</span><span class='hs-varop'>+</span><span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-varid'>buf</span> <a name="line-227"></a> <a name="line-228"></a><a name="bufferAdjustL"></a><span class='hs-definition'>bufferAdjustL</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <a name="line-229"></a><span class='hs-definition'>bufferAdjustL</span> <span class='hs-varid'>l</span> <span class='hs-varid'>buf</span><span class='hs-keyglyph'>@</span><span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span> <span class='hs-layout'>}</span> <a name="line-230"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>l</span> <span class='hs-varop'>==</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>buf</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-num'>0</span> <span class='hs-layout'>}</span> <a name="line-231"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>buf</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span> <span class='hs-layout'>}</span> <a name="line-232"></a> <a name="line-233"></a><a name="bufferAdd"></a><span class='hs-definition'>bufferAdd</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <a name="line-234"></a><span class='hs-definition'>bufferAdd</span> <span class='hs-varid'>i</span> <span class='hs-varid'>buf</span><span class='hs-keyglyph'>@</span><span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>buf</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span><span class='hs-varop'>+</span><span class='hs-varid'>i</span> <span class='hs-layout'>}</span> <a name="line-235"></a> <a name="line-236"></a><a name="emptyBuffer"></a><span class='hs-definition'>emptyBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RawBuffer</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BufferState</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span> <a name="line-237"></a><span class='hs-definition'>emptyBuffer</span> <span class='hs-varid'>raw</span> <span class='hs-varid'>sz</span> <span class='hs-varid'>state</span> <span class='hs-keyglyph'>=</span> <a name="line-238"></a> <span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufRaw</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>raw</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufState</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>state</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufSize</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>sz</span> <span class='hs-layout'>}</span> <a name="line-239"></a> <a name="line-240"></a><a name="newByteBuffer"></a><span class='hs-definition'>newByteBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BufferState</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Buffer</span> <span class='hs-conid'>Word8</span><span class='hs-layout'>)</span> <a name="line-241"></a><span class='hs-definition'>newByteBuffer</span> <span class='hs-varid'>c</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newBuffer</span> <span class='hs-varid'>c</span> <span class='hs-varid'>c</span> <span class='hs-varid'>st</span> <a name="line-242"></a> <a name="line-243"></a><a name="newCharBuffer"></a><span class='hs-definition'>newCharBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BufferState</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>CharBuffer</span> <a name="line-244"></a><span class='hs-definition'>newCharBuffer</span> <span class='hs-varid'>c</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newBuffer</span> <span class='hs-layout'>(</span><span class='hs-varid'>c</span> <span class='hs-varop'>*</span> <span class='hs-varid'>charSize</span><span class='hs-layout'>)</span> <span class='hs-varid'>c</span> <span class='hs-varid'>st</span> <a name="line-245"></a> <a name="line-246"></a><a name="newBuffer"></a><span class='hs-definition'>newBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BufferState</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Buffer</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <a name="line-247"></a><span class='hs-definition'>newBuffer</span> <span class='hs-varid'>bytes</span> <span class='hs-varid'>sz</span> <span class='hs-varid'>state</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-248"></a> <span class='hs-varid'>fp</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>mallocForeignPtrBytes</span> <span class='hs-varid'>bytes</span> <a name="line-249"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>emptyBuffer</span> <span class='hs-varid'>fp</span> <span class='hs-varid'>sz</span> <span class='hs-varid'>state</span><span class='hs-layout'>)</span> <a name="line-250"></a> <a name="line-251"></a><a name="slideContents"></a><span class='hs-comment'>-- | slides the contents of the buffer to the beginning</span> <a name="line-252"></a><span class='hs-definition'>slideContents</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-conid'>Word8</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Buffer</span> <span class='hs-conid'>Word8</span><span class='hs-layout'>)</span> <a name="line-253"></a><span class='hs-definition'>slideContents</span> <span class='hs-varid'>buf</span><span class='hs-keyglyph'>@</span><span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>r</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufRaw</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>raw</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-254"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>elems</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>r</span> <span class='hs-comment'>-</span> <span class='hs-varid'>l</span> <a name="line-255"></a> <span class='hs-varid'>withRawBuffer</span> <span class='hs-varid'>raw</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>p</span> <span class='hs-keyglyph'>-></span> <a name="line-256"></a> <span class='hs-keyword'>do</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>memcpy</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`plusPtr`</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>elems</span><span class='hs-layout'>)</span> <a name="line-257"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span> <a name="line-258"></a> <span class='hs-varid'>return</span> <span class='hs-varid'>buf</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>elems</span> <span class='hs-layout'>}</span> <a name="line-259"></a> <a name="line-260"></a><span class='hs-keyword'>foreign</span> <span class='hs-keyword'>import</span> <span class='hs-keyword'>ccall</span> <span class='hs-keyword'>unsafe</span> <span class='hs-str'>"memcpy"</span> <a name="line-261"></a> <span class='hs-varid'>memcpy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ptr</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Ptr</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CSize</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ptr</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <a name="line-262"></a> <a name="line-263"></a><a name="summaryBuffer"></a><span class='hs-definition'>summaryBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>String</span> <a name="line-264"></a><span class='hs-definition'>summaryBuffer</span> <span class='hs-varid'>buf</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"buf"</span> <span class='hs-varop'>++</span> <span class='hs-varid'>show</span> <span class='hs-layout'>(</span><span class='hs-varid'>bufSize</span> <span class='hs-varid'>buf</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-str'>"("</span> <span class='hs-varop'>++</span> <span class='hs-varid'>show</span> <span class='hs-layout'>(</span><span class='hs-varid'>bufL</span> <span class='hs-varid'>buf</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-str'>"-"</span> <span class='hs-varop'>++</span> <span class='hs-varid'>show</span> <span class='hs-layout'>(</span><span class='hs-varid'>bufR</span> <span class='hs-varid'>buf</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-str'>")"</span> <a name="line-265"></a> <a name="line-266"></a><span class='hs-comment'>-- INVARIANTS on Buffers:</span> <a name="line-267"></a><span class='hs-comment'>-- * r <= w</span> <a name="line-268"></a><span class='hs-comment'>-- * if r == w, and the buffer is for reading, then r == 0 && w == 0</span> <a name="line-269"></a><span class='hs-comment'>-- * a write buffer is never full. If an operation</span> <a name="line-270"></a><span class='hs-comment'>-- fills up the buffer, it will always flush it before </span> <a name="line-271"></a><span class='hs-comment'>-- returning.</span> <a name="line-272"></a><span class='hs-comment'>-- * a read buffer may be full as a result of hLookAhead. In normal</span> <a name="line-273"></a><span class='hs-comment'>-- operation, a read buffer always has at least one character of space.</span> <a name="line-274"></a> <a name="line-275"></a><a name="checkBuffer"></a><span class='hs-definition'>checkBuffer</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span> <a name="line-276"></a><span class='hs-definition'>checkBuffer</span> <span class='hs-varid'>buf</span><span class='hs-keyglyph'>@</span><span class='hs-conid'>Buffer</span><span class='hs-layout'>{</span> <span class='hs-varid'>bufState</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>state</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufL</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>r</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufR</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>w</span><span class='hs-layout'>,</span> <span class='hs-varid'>bufSize</span><span class='hs-keyglyph'>=</span><span class='hs-varid'>size</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-277"></a> <span class='hs-varid'>check</span> <span class='hs-varid'>buf</span> <span class='hs-layout'>(</span> <a name="line-278"></a> <span class='hs-varid'>size</span> <span class='hs-varop'>></span> <span class='hs-num'>0</span> <a name="line-279"></a> <span class='hs-varop'>&&</span> <span class='hs-varid'>r</span> <span class='hs-varop'><=</span> <span class='hs-varid'>w</span> <a name="line-280"></a> <span class='hs-varop'>&&</span> <span class='hs-varid'>w</span> <span class='hs-varop'><=</span> <span class='hs-varid'>size</span> <a name="line-281"></a> <span class='hs-varop'>&&</span> <span class='hs-layout'>(</span> <span class='hs-varid'>r</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>w</span> <span class='hs-varop'>||</span> <span class='hs-varid'>state</span> <span class='hs-varop'>==</span> <span class='hs-conid'>WriteBuffer</span> <span class='hs-varop'>||</span> <span class='hs-layout'>(</span><span class='hs-varid'>r</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>w</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-layout'>)</span> <a name="line-282"></a> <span class='hs-varop'>&&</span> <span class='hs-layout'>(</span> <span class='hs-varid'>state</span> <span class='hs-varop'>/=</span> <span class='hs-conid'>WriteBuffer</span> <span class='hs-varop'>||</span> <span class='hs-varid'>w</span> <span class='hs-varop'><</span> <span class='hs-varid'>size</span> <span class='hs-layout'>)</span> <span class='hs-comment'>-- write buffer is never full</span> <a name="line-283"></a> <span class='hs-layout'>)</span> <a name="line-284"></a> <a name="line-285"></a><a name="check"></a><span class='hs-definition'>check</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Buffer</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span> <a name="line-286"></a><span class='hs-definition'>check</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span> <a name="line-287"></a><span class='hs-definition'>check</span> <span class='hs-varid'>buf</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-layout'>(</span><span class='hs-str'>"buffer invariant violation: "</span> <span class='hs-varop'>++</span> <span class='hs-varid'>summaryBuffer</span> <span class='hs-varid'>buf</span><span class='hs-layout'>)</span> </pre></body> </html>