/usr/share/doc/libghc-blaze-builder-doc/html/src/Blaze-ByteString-Builder.html is in libghc-blaze-builder-doc 0.4.0.1-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | <?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://code.haskell.org/~malcolm/hscolour/ -->
<title>Blaze/ByteString/Builder.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE CPP, BangPatterns #-}</span>
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE GeneralizedNewtypeDeriving #-}</span>
<a name="line-3"></a>
<a name="line-4"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-5"></a><span class='hs-comment'>-- |</span>
<a name="line-6"></a><span class='hs-comment'>-- Module: Blaze.ByteString.Builder</span>
<a name="line-7"></a><span class='hs-comment'>-- Copyright: (c) 2013 Leon P Smith</span>
<a name="line-8"></a><span class='hs-comment'>-- License: BSD3</span>
<a name="line-9"></a><span class='hs-comment'>-- Maintainer: Leon P Smith <leon@melding-monads.com></span>
<a name="line-10"></a><span class='hs-comment'>-- Stability: experimental</span>
<a name="line-11"></a><span class='hs-comment'>--</span>
<a name="line-12"></a><span class='hs-comment'>-- "Blaze.ByteString.Builder" is the main module, which you should import as a user</span>
<a name="line-13"></a><span class='hs-comment'>-- of the @blaze-builder@ library.</span>
<a name="line-14"></a><span class='hs-comment'>--</span>
<a name="line-15"></a><span class='hs-comment'>-- > import Blaze.ByteString.Builder</span>
<a name="line-16"></a><span class='hs-comment'>--</span>
<a name="line-17"></a><span class='hs-comment'>-- It provides you with a type 'Builder' that allows to efficiently construct</span>
<a name="line-18"></a><span class='hs-comment'>-- lazy bytestrings with a large average chunk size.</span>
<a name="line-19"></a><span class='hs-comment'>--</span>
<a name="line-20"></a><span class='hs-comment'>-- Intuitively, a 'Builder' denotes the construction of a part of a lazy</span>
<a name="line-21"></a><span class='hs-comment'>-- bytestring. Builders can either be created using one of the primitive</span>
<a name="line-22"></a><span class='hs-comment'>-- combinators in "Blaze.ByteString.Builder.Write" or by using one of the predefined</span>
<a name="line-23"></a><span class='hs-comment'>-- combinators for standard Haskell values (see the exposed modules of this</span>
<a name="line-24"></a><span class='hs-comment'>-- package). Concatenation of builders is done using 'mappend' from the</span>
<a name="line-25"></a><span class='hs-comment'>-- 'Monoid' typeclass.</span>
<a name="line-26"></a><span class='hs-comment'>--</span>
<a name="line-27"></a><span class='hs-comment'>-- Here is a small example that serializes a list of strings using the UTF-8</span>
<a name="line-28"></a><span class='hs-comment'>-- encoding.</span>
<a name="line-29"></a><span class='hs-comment'>--</span>
<a name="line-30"></a><span class='hs-comment'>-- @ import "Blaze.ByteString.Builder.Char.Utf8"@</span>
<a name="line-31"></a><span class='hs-comment'>--</span>
<a name="line-32"></a><span class='hs-comment'>-- > strings :: [String]</span>
<a name="line-33"></a><span class='hs-comment'>-- > strings = replicate 10000 "Hello there!"</span>
<a name="line-34"></a><span class='hs-comment'>--</span>
<a name="line-35"></a><span class='hs-comment'>-- The function @'fromString'@ creates a 'Builder' denoting the UTF-8 encoded</span>
<a name="line-36"></a><span class='hs-comment'>-- argument. Hence, UTF-8 encoding and concatenating all @strings@ can be done</span>
<a name="line-37"></a><span class='hs-comment'>-- follows.</span>
<a name="line-38"></a><span class='hs-comment'>--</span>
<a name="line-39"></a><span class='hs-comment'>-- > concatenation :: Builder</span>
<a name="line-40"></a><span class='hs-comment'>-- > concatenation = mconcat $ map fromString strings</span>
<a name="line-41"></a><span class='hs-comment'>--</span>
<a name="line-42"></a><span class='hs-comment'>-- The function 'toLazyByteString' can be used to execute a 'Builder' and</span>
<a name="line-43"></a><span class='hs-comment'>-- obtain the resulting lazy bytestring.</span>
<a name="line-44"></a><span class='hs-comment'>--</span>
<a name="line-45"></a><span class='hs-comment'>-- > result :: L.ByteString</span>
<a name="line-46"></a><span class='hs-comment'>-- > result = toLazyByteString concatenation</span>
<a name="line-47"></a><span class='hs-comment'>--</span>
<a name="line-48"></a><span class='hs-comment'>-- The @result@ is a lazy bytestring containing 10000 repetitions of the string</span>
<a name="line-49"></a><span class='hs-comment'>-- @\"Hello there!\"@ encoded using UTF-8. The corresponding 120000 bytes are</span>
<a name="line-50"></a><span class='hs-comment'>-- distributed among three chunks of 32kb and a last chunk of 6kb.</span>
<a name="line-51"></a><span class='hs-comment'>--</span>
<a name="line-52"></a><span class='hs-comment'>-- /A note on history./ This serialization library was inspired by the</span>
<a name="line-53"></a><span class='hs-comment'>-- @Data.Binary.Builder@ module provided by the @binary@ package. It was</span>
<a name="line-54"></a><span class='hs-comment'>-- originally developed with the specific needs of the @blaze-html@ package in</span>
<a name="line-55"></a><span class='hs-comment'>-- mind. Since then it has been restructured to serve as a drop-in replacement</span>
<a name="line-56"></a><span class='hs-comment'>-- for @Data.Binary.Builder@, which it improves upon both in speed as well as</span>
<a name="line-57"></a><span class='hs-comment'>-- expressivity.</span>
<a name="line-58"></a><span class='hs-comment'>--</span>
<a name="line-59"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-60"></a>
<a name="line-61"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span>
<a name="line-62"></a> <span class='hs-layout'>(</span>
<a name="line-63"></a> <span class='hs-comment'>-- * The 'Builder' type</span>
<a name="line-64"></a> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span>
<a name="line-65"></a>
<a name="line-66"></a> <span class='hs-comment'>-- * Creating builders</span>
<a name="line-67"></a> <span class='hs-layout'>,</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span>
<a name="line-68"></a> <span class='hs-layout'>,</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span>
<a name="line-69"></a> <span class='hs-layout'>,</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-70"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>flush</span>
<a name="line-71"></a>
<a name="line-72"></a> <span class='hs-comment'>-- * Executing builders</span>
<a name="line-73"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>toLazyByteString</span>
<a name="line-74"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>toLazyByteStringWith</span>
<a name="line-75"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>toByteString</span>
<a name="line-76"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>toByteStringIO</span>
<a name="line-77"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>toByteStringIOWith</span>
<a name="line-78"></a>
<a name="line-79"></a> <span class='hs-comment'>-- * 'Write's</span>
<a name="line-80"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Write</span>
<a name="line-81"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>fromWrite</span>
<a name="line-82"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>fromWriteSingleton</span>
<a name="line-83"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>fromWriteList</span>
<a name="line-84"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>writeToByteString</span>
<a name="line-85"></a>
<a name="line-86"></a> <span class='hs-comment'>-- ** Writing 'Storable's</span>
<a name="line-87"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>writeStorable</span>
<a name="line-88"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>fromStorable</span>
<a name="line-89"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>fromStorables</span>
<a name="line-90"></a>
<a name="line-91"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-92"></a>
<a name="line-93"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-layout'>(</span><span class='hs-varid'>unless</span><span class='hs-layout'>)</span>
<a name="line-94"></a>
<a name="line-95"></a><span class='hs-cpp'>#if __GLASGOW_HASKELL__ >= 702</span>
<a name="line-96"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span>
<a name="line-97"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>ForeignPtr</span><span class='hs-varop'>.</span><span class='hs-conid'>Unsafe</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>Unsafe</span>
<a name="line-98"></a><span class='hs-cpp'>#else</span>
<a name="line-99"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>Unsafe</span>
<a name="line-100"></a><span class='hs-cpp'>#endif</span>
<a name="line-101"></a>
<a name="line-102"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span><span class='hs-varop'>.</span><span class='hs-conid'>Write</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>W</span>
<a name="line-103"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-104"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span>
<a name="line-105"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span>
<a name="line-106"></a>
<a name="line-107"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span> <span class='hs-layout'>(</span> <span class='hs-conid'>Builder</span> <span class='hs-layout'>)</span>
<a name="line-108"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>B</span>
<a name="line-109"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span><span class='hs-varop'>.</span><span class='hs-conid'>Extra</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>B</span>
<a name="line-110"></a>
<a name="line-111"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>S</span>
<a name="line-112"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>S</span>
<a name="line-113"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span>
<a name="line-114"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span>
<a name="line-115"></a>
<a name="line-116"></a><span class='hs-cpp'>#if __GLASGOW_HASKELL__ >= 702</span>
<a name="line-117"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Unsafe</span> <span class='hs-layout'>(</span><span class='hs-varid'>unsafeDupablePerformIO</span><span class='hs-layout'>)</span>
<a name="line-118"></a><span class='hs-cpp'>#else</span>
<a name="line-119"></a><a name="unsafeDupablePerformIO"></a><span class='hs-definition'>unsafeDupablePerformIO</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>a</span>
<a name="line-120"></a><span class='hs-definition'>unsafeDupablePerformIO</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unsafePerformIO</span>
<a name="line-121"></a><span class='hs-cpp'>#endif</span>
<a name="line-122"></a>
<a name="line-123"></a>
<a name="line-124"></a>
<a name="line-125"></a><a name="packChunks"></a><span class='hs-comment'>-- | Pack the chunks of a lazy bytestring into a single strict bytestring.</span>
<a name="line-126"></a><span class='hs-definition'>packChunks</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-127"></a><span class='hs-definition'>packChunks</span> <span class='hs-varid'>lbs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-128"></a> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeCreate</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varop'>$</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>length</span> <span class='hs-varid'>lbs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>copyChunks</span> <span class='hs-varid'>lbs</span><span class='hs-layout'>)</span>
<a name="line-129"></a> <span class='hs-keyword'>where</span>
<a name="line-130"></a> <span class='hs-varid'>copyChunks</span> <span class='hs-varop'>!</span><span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>Empty</span> <span class='hs-varop'>!</span><span class='hs-sel'>_pf</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-131"></a> <span class='hs-varid'>copyChunks</span> <span class='hs-varop'>!</span><span class='hs-layout'>(</span><span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>fpbuf</span> <span class='hs-varid'>o</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>lbs'</span><span class='hs-layout'>)</span> <span class='hs-varop'>!</span><span class='hs-varid'>pf</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-132"></a> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>fpbuf</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>pbuf</span> <span class='hs-keyglyph'>-></span>
<a name="line-133"></a> <span class='hs-varid'>copyBytes</span> <span class='hs-varid'>pf</span> <span class='hs-layout'>(</span><span class='hs-varid'>pbuf</span> <span class='hs-varop'>`plusPtr`</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span> <span class='hs-varid'>l</span>
<a name="line-134"></a> <span class='hs-varid'>copyChunks</span> <span class='hs-varid'>lbs'</span> <span class='hs-layout'>(</span><span class='hs-varid'>pf</span> <span class='hs-varop'>`plusPtr`</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span>
<a name="line-135"></a>
<a name="line-136"></a><a name="toByteString"></a><span class='hs-comment'>-- | Run the builder to construct a strict bytestring containing the sequence</span>
<a name="line-137"></a><span class='hs-comment'>-- of bytes denoted by the builder. This is done by first serializing to a lazy bytestring and then packing its</span>
<a name="line-138"></a><span class='hs-comment'>-- chunks to a appropriately sized strict bytestring.</span>
<a name="line-139"></a><span class='hs-comment'>--</span>
<a name="line-140"></a><span class='hs-comment'>-- > toByteString = packChunks . toLazyByteString</span>
<a name="line-141"></a><span class='hs-comment'>--</span>
<a name="line-142"></a><span class='hs-comment'>-- Note that @'toByteString'@ is a 'Monoid' homomorphism.</span>
<a name="line-143"></a><span class='hs-comment'>--</span>
<a name="line-144"></a><span class='hs-comment'>-- > toByteString mempty == mempty</span>
<a name="line-145"></a><span class='hs-comment'>-- > toByteString (x `mappend` y) == toByteString x `mappend` toByteString y</span>
<a name="line-146"></a><span class='hs-comment'>--</span>
<a name="line-147"></a><span class='hs-comment'>-- However, in the second equation, the left-hand-side is generally faster to</span>
<a name="line-148"></a><span class='hs-comment'>-- execute.</span>
<a name="line-149"></a><span class='hs-comment'>--</span>
<a name="line-150"></a><span class='hs-definition'>toByteString</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Builder</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-151"></a><span class='hs-definition'>toByteString</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>packChunks</span> <span class='hs-varop'>.</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>toLazyByteString</span>
<a name="line-152"></a>
<a name="line-153"></a><a name="defaultBufferSize"></a><span class='hs-comment'>-- | Default size (~32kb) for the buffer that becomes a chunk of the output</span>
<a name="line-154"></a><span class='hs-comment'>-- stream once it is filled.</span>
<a name="line-155"></a><span class='hs-comment'>--</span>
<a name="line-156"></a><span class='hs-definition'>defaultBufferSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-157"></a><span class='hs-definition'>defaultBufferSize</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>32</span> <span class='hs-varop'>*</span> <span class='hs-num'>1024</span> <span class='hs-comment'>-</span> <span class='hs-varid'>overhead</span> <span class='hs-comment'>-- Copied from Data.ByteString.Lazy.</span>
<a name="line-158"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>overhead</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>2</span> <span class='hs-varop'>*</span> <span class='hs-varid'>sizeOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>undefined</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span><span class='hs-layout'>)</span>
<a name="line-159"></a>
<a name="line-160"></a>
<a name="line-161"></a><a name="toByteStringIO"></a><span class='hs-comment'>-- | @toByteStringIOWith bufSize io b@ runs the builder @b@ with a buffer of</span>
<a name="line-162"></a><span class='hs-comment'>-- at least the size @bufSize@ and executes the 'IO' action @io@ whenever the</span>
<a name="line-163"></a><span class='hs-comment'>-- buffer is full.</span>
<a name="line-164"></a><span class='hs-comment'>--</span>
<a name="line-165"></a><span class='hs-comment'>-- Compared to 'toLazyByteStringWith' this function requires less allocation,</span>
<a name="line-166"></a><span class='hs-comment'>-- as the output buffer is only allocated once at the start of the</span>
<a name="line-167"></a><span class='hs-comment'>-- serialization and whenever something bigger than the current buffer size has</span>
<a name="line-168"></a><span class='hs-comment'>-- to be copied into the buffer, which should happen very seldomly for the</span>
<a name="line-169"></a><span class='hs-comment'>-- default buffer size of 32kb. Hence, the pressure on the garbage collector is</span>
<a name="line-170"></a><span class='hs-comment'>-- reduced, which can be an advantage when building long sequences of bytes.</span>
<a name="line-171"></a><span class='hs-comment'>--</span>
<a name="line-172"></a><span class='hs-definition'>toByteStringIO</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Builder</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-173"></a><span class='hs-definition'>toByteStringIO</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toByteStringIOWith</span> <span class='hs-varid'>defaultBufferSize</span>
<a name="line-174"></a>
<a name="line-175"></a><a name="toByteStringIOWith"></a><span class='hs-definition'>toByteStringIOWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ Buffer size (upper bounds</span>
<a name="line-176"></a> <span class='hs-comment'>-- the number of bytes forced</span>
<a name="line-177"></a> <span class='hs-comment'>-- per call to the 'IO' action).</span>
<a name="line-178"></a> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- ^ 'IO' action to execute per</span>
<a name="line-179"></a> <span class='hs-comment'>-- full buffer, which is</span>
<a name="line-180"></a> <span class='hs-comment'>-- referenced by a strict</span>
<a name="line-181"></a> <span class='hs-comment'>-- 'S.ByteString'.</span>
<a name="line-182"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Builder</span> <span class='hs-comment'>-- ^ 'Builder' to run.</span>
<a name="line-183"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span> <span class='hs-comment'>-- ^ Resulting 'IO' action.</span>
<a name="line-184"></a><a name="!"></a><span class='hs-definition'>toByteStringIOWith</span> <span class='hs-varop'>!</span><span class='hs-varid'>bufSize</span> <span class='hs-varid'>io</span> <span class='hs-varid'>builder</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-185"></a> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-varid'>bufSize</span> <span class='hs-varop'>>>=</span> <span class='hs-varid'>getBuffer</span> <span class='hs-layout'>(</span><span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>runBuilder</span> <span class='hs-varid'>builder</span><span class='hs-layout'>)</span> <span class='hs-varid'>bufSize</span>
<a name="line-186"></a> <span class='hs-keyword'>where</span>
<a name="line-187"></a> <span class='hs-varid'>getBuffer</span> <span class='hs-varid'>writer</span> <span class='hs-varop'>!</span><span class='hs-varid'>size</span> <span class='hs-varid'>fp</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-188"></a> <span class='hs-keyword'>let</span> <span class='hs-varop'>!</span><span class='hs-varid'>ptr</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Unsafe</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeForeignPtrToPtr</span> <span class='hs-varid'>fp</span>
<a name="line-189"></a> <span class='hs-layout'>(</span><span class='hs-varid'>bytes</span><span class='hs-layout'>,</span> <span class='hs-varid'>next</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>writer</span> <span class='hs-varid'>ptr</span> <span class='hs-varid'>size</span>
<a name="line-190"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>next</span> <span class='hs-keyword'>of</span>
<a name="line-191"></a> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>Done</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>io</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>fp</span> <span class='hs-num'>0</span> <span class='hs-varid'>bytes</span>
<a name="line-192"></a> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>More</span> <span class='hs-varid'>req</span> <span class='hs-varid'>writer'</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>do</span>
<a name="line-193"></a> <span class='hs-varid'>io</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>fp</span> <span class='hs-num'>0</span> <span class='hs-varid'>bytes</span>
<a name="line-194"></a> <span class='hs-keyword'>let</span> <span class='hs-varop'>!</span><span class='hs-varid'>size'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>max</span> <span class='hs-varid'>bufSize</span> <span class='hs-varid'>req</span>
<a name="line-195"></a> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-varid'>size'</span> <span class='hs-varop'>>>=</span> <span class='hs-varid'>getBuffer</span> <span class='hs-varid'>writer'</span> <span class='hs-varid'>size'</span>
<a name="line-196"></a> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-varid'>bs'</span> <span class='hs-varid'>writer'</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>do</span>
<a name="line-197"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>bytes</span> <span class='hs-varop'>></span> <span class='hs-num'>0</span>
<a name="line-198"></a> <span class='hs-keyword'>then</span> <span class='hs-keyword'>do</span>
<a name="line-199"></a> <span class='hs-varid'>io</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>fp</span> <span class='hs-num'>0</span> <span class='hs-varid'>bytes</span>
<a name="line-200"></a> <span class='hs-varid'>unless</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>null</span> <span class='hs-varid'>bs'</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>io</span> <span class='hs-varid'>bs'</span><span class='hs-layout'>)</span>
<a name="line-201"></a> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-varid'>bufSize</span> <span class='hs-varop'>>>=</span> <span class='hs-varid'>getBuffer</span> <span class='hs-varid'>writer'</span> <span class='hs-varid'>bufSize</span>
<a name="line-202"></a> <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span>
<a name="line-203"></a> <span class='hs-varid'>unless</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>null</span> <span class='hs-varid'>bs'</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>io</span> <span class='hs-varid'>bs'</span><span class='hs-layout'>)</span>
<a name="line-204"></a> <span class='hs-varid'>getBuffer</span> <span class='hs-varid'>writer'</span> <span class='hs-varid'>size</span> <span class='hs-varid'>fp</span>
<a name="line-205"></a>
<a name="line-206"></a>
<a name="line-207"></a><a name="toLazyByteStringWith"></a><span class='hs-comment'>-- | Run a 'Builder' with the given buffer sizes.</span>
<a name="line-208"></a><span class='hs-comment'>--</span>
<a name="line-209"></a><span class='hs-comment'>-- Use this function for integrating the 'Builder' type with other libraries</span>
<a name="line-210"></a><span class='hs-comment'>-- that generate lazy bytestrings.</span>
<a name="line-211"></a><span class='hs-comment'>--</span>
<a name="line-212"></a><span class='hs-comment'>-- Note that the builders should guarantee that on average the desired chunk</span>
<a name="line-213"></a><span class='hs-comment'>-- size is attained. Builders may decide to start a new buffer and not</span>
<a name="line-214"></a><span class='hs-comment'>-- completely fill the existing buffer, if this is faster. However, they should</span>
<a name="line-215"></a><span class='hs-comment'>-- not spill too much of the buffer, if they cannot compensate for it.</span>
<a name="line-216"></a><span class='hs-comment'>--</span>
<a name="line-217"></a><span class='hs-comment'>-- FIXME: Note that the following paragraphs are not entirely correct as of</span>
<a name="line-218"></a><span class='hs-comment'>-- blaze-builder-0.4:</span>
<a name="line-219"></a><span class='hs-comment'>--</span>
<a name="line-220"></a><span class='hs-comment'>-- A call @toLazyByteStringWith bufSize minBufSize firstBufSize@ will generate</span>
<a name="line-221"></a><span class='hs-comment'>-- a lazy bytestring according to the following strategy. First, we allocate</span>
<a name="line-222"></a><span class='hs-comment'>-- a buffer of size @firstBufSize@ and start filling it. If it overflows, we</span>
<a name="line-223"></a><span class='hs-comment'>-- allocate a buffer of size @minBufSize@ and copy the first buffer to it in</span>
<a name="line-224"></a><span class='hs-comment'>-- order to avoid generating a too small chunk. Finally, every next buffer will</span>
<a name="line-225"></a><span class='hs-comment'>-- be of size @bufSize@. This, slow startup strategy is required to achieve</span>
<a name="line-226"></a><span class='hs-comment'>-- good speed for short (<200 bytes) resulting bytestrings, as for them the</span>
<a name="line-227"></a><span class='hs-comment'>-- allocation cost is of a large buffer cannot be compensated. Moreover, this</span>
<a name="line-228"></a><span class='hs-comment'>-- strategy also allows us to avoid spilling too much memory for short</span>
<a name="line-229"></a><span class='hs-comment'>-- resulting bytestrings.</span>
<a name="line-230"></a><span class='hs-comment'>--</span>
<a name="line-231"></a><span class='hs-comment'>-- Note that setting @firstBufSize >= minBufSize@ implies that the first buffer</span>
<a name="line-232"></a><span class='hs-comment'>-- is no longer copied but allocated and filled directly. Hence, setting</span>
<a name="line-233"></a><span class='hs-comment'>-- @firstBufSize = bufSize@ means that all chunks will use an underlying buffer</span>
<a name="line-234"></a><span class='hs-comment'>-- of size @bufSize@. This is recommended, if you know that you always output</span>
<a name="line-235"></a><span class='hs-comment'>-- more than @minBufSize@ bytes.</span>
<a name="line-236"></a><span class='hs-definition'>toLazyByteStringWith</span>
<a name="line-237"></a> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ Buffer size (upper-bounds the resulting chunk size).</span>
<a name="line-238"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ This parameter is ignored as of blaze-builder-0.4</span>
<a name="line-239"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- ^ Size of the first buffer to be used and copied for</span>
<a name="line-240"></a> <span class='hs-comment'>-- larger resulting sequences</span>
<a name="line-241"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Builder</span> <span class='hs-comment'>-- ^ Builder to run.</span>
<a name="line-242"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-comment'>-- ^ Lazy bytestring to output after the builder is</span>
<a name="line-243"></a> <span class='hs-comment'>-- finished.</span>
<a name="line-244"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-comment'>-- ^ Resulting lazy bytestring</span>
<a name="line-245"></a><span class='hs-definition'>toLazyByteStringWith</span> <span class='hs-varid'>bufSize</span> <span class='hs-sel'>_minBufSize</span> <span class='hs-varid'>firstBufSize</span> <span class='hs-varid'>builder</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>=</span>
<a name="line-246"></a> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>toLazyByteStringWith</span> <span class='hs-layout'>(</span><span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-varid'>safeStrategy</span> <span class='hs-varid'>firstBufSize</span> <span class='hs-varid'>bufSize</span><span class='hs-layout'>)</span> <span class='hs-varid'>k</span> <span class='hs-varid'>builder</span>
<a name="line-247"></a>
<a name="line-248"></a><a name="writeToByteString"></a><span class='hs-comment'>-- | Run a 'Write' to produce a strict 'S.ByteString'.</span>
<a name="line-249"></a><span class='hs-comment'>-- This is equivalent to @('toByteString' . 'fromWrite')@, but is more</span>
<a name="line-250"></a><span class='hs-comment'>-- efficient because it uses just one appropriately-sized buffer.</span>
<a name="line-251"></a><span class='hs-definition'>writeToByteString</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Write</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-252"></a><span class='hs-definition'>writeToByteString</span> <span class='hs-varop'>!</span><span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unsafeDupablePerformIO</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-253"></a> <span class='hs-varid'>fptr</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>getBound</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span>
<a name="line-254"></a> <span class='hs-varid'>len</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>withForeignPtr</span> <span class='hs-varid'>fptr</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>ptr</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>do</span>
<a name="line-255"></a> <span class='hs-varid'>end</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>runWrite</span> <span class='hs-varid'>w</span> <span class='hs-varid'>ptr</span>
<a name="line-256"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>end</span> <span class='hs-varop'>`minusPtr`</span> <span class='hs-varid'>ptr</span>
<a name="line-257"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>fromForeignPtr</span> <span class='hs-varid'>fptr</span> <span class='hs-num'>0</span> <span class='hs-varid'>len</span>
<a name="line-258"></a><span class='hs-comment'>{-# INLINE writeToByteString #-}</span>
</pre></body>
</html>
|