3 <title>Bisect report</title>
4 <link rel="stylesheet" type="text/css" href="style.css">
7 <h3>File: bitstring.ml (<a href="index.html">return to index</a>)</h3>
10 <table class="simple">
11 <tr><th>kind</th><th width="16px"> </th><th>coverage</th></tr>
12 <tr><td>binding</td><td width="16px"> </td><td>226 / 245 (92 %)</td></tr>
13 <tr><td>sequence</td><td width="16px"> </td><td>83 / 95 (87 %)</td></tr>
14 <tr><td>for</td><td width="16px"> </td><td>5 / 5 (100 %)</td></tr>
15 <tr><td>if/then</td><td width="16px"> </td><td>141 / 194 (72 %)</td></tr>
16 <tr><td>try</td><td width="16px"> </td><td>1 / 2 (50 %)</td></tr>
17 <tr><td>while</td><td width="16px"> </td><td>3 / 3 (100 %)</td></tr>
18 <tr><td>match/function</td><td width="16px"> </td><td>64 / 87 (73 %)</td></tr>
19 <tr><td>class expression</td><td width="16px"> </td><td>0 / 0 (- %)</td></tr>
20 <tr><td>class initializer</td><td width="16px"> </td><td>0 / 0 (- %)</td></tr>
21 <tr><td>class method</td><td width="16px"> </td><td>0 / 0 (- %)</td></tr>
22 <tr><td>class value</td><td width="16px"> </td><td>0 / 0 (- %)</td></tr>
23 <tr><td>toplevel expression</td><td width="16px"> </td><td>0 / 0 (- %)</td></tr>
28 <div class="lineNone">000001| (* Bitstring library.</div>
29 <div class="lineNone">000002| * Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones</div>
30 <div class="lineNone">000003| *</div>
31 <div class="lineNone">000004| * This library is free software; you can redistribute it and/or</div>
32 <div class="lineNone">000005| * modify it under the terms of the GNU Lesser General Public</div>
33 <div class="lineNone">000006| * License as published by the Free Software Foundation; either</div>
34 <div class="lineNone">000007| * version 2 of the License, or (at your option) any later version,</div>
35 <div class="lineNone">000008| * with the OCaml linking exception described in COPYING.LIB.</div>
36 <div class="lineNone">000009| *</div>
37 <div class="lineNone">000010| * This library is distributed in the hope that it will be useful,</div>
38 <div class="lineNone">000011| * but WITHOUT ANY WARRANTY; without even the implied warranty of</div>
39 <div class="lineNone">000012| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</div>
40 <div class="lineNone">000013| * Lesser General Public License for more details.</div>
41 <div class="lineNone">000014| *</div>
42 <div class="lineNone">000015| * You should have received a copy of the GNU Lesser General Public</div>
43 <div class="lineNone">000016| * License along with this library; if not, write to the Free Software</div>
44 <div class="lineNone">000017| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</div>
45 <div class="lineNone">000018| *</div>
46 <div class="lineNone">000019| * $Id: bitstring.ml 159 2008-08-27 11:26:45Z richard.wm.jones $</div>
47 <div class="lineNone">000020| *)</div>
48 <div class="lineNone">000021| </div>
49 <div class="lineNone">000022| open Printf</div>
50 <div class="lineNone">000023| </div>
51 <div class="lineNone">000024| include Bitstring_types</div>
52 <div class="lineNone">000025| include Bitstring_config</div>
53 <div class="lineNone">000026| </div>
54 <div class="lineNone">000027| (* Enable runtime debug messages. Must also have been enabled</div>
55 <div class="lineNone">000028| * in pa_bitstring.ml.</div>
56 <div class="lineNone">000029| *)</div>
57 <div class="lineAllVisited">000030| let debug = (*[43]*)ref false</div>
58 <div class="lineNone">000031| </div>
59 <div class="lineNone">000032| (* Exceptions. *)</div>
60 <div class="lineNone">000033| exception Construct_failure of string * string * int * int</div>
61 <div class="lineNone">000034| </div>
62 <div class="lineNone">000035| (* A bitstring is simply the data itself (as a string), and the</div>
63 <div class="lineNone">000036| * bitoffset and the bitlength within the string. Note offset/length</div>
64 <div class="lineNone">000037| * are counted in bits, not bytes.</div>
65 <div class="lineNone">000038| *)</div>
66 <div class="lineNone">000039| type bitstring = string * int * int</div>
67 <div class="lineNone">000040| </div>
68 <div class="lineNone">000041| type t = bitstring</div>
69 <div class="lineNone">000042| </div>
70 <div class="lineNone">000043| (* Functions to create and load bitstrings. *)</div>
71 <div class="lineAllVisited">000044| let empty_bitstring = (*[43]*)"", 0, 0</div>
72 <div class="lineNone">000045| </div>
73 <div class="lineNone">000046| let make_bitstring len c =</div>
74 <div class="lineAllVisited">000047| (*[1325989]*)if len >= 0 then (*[1325989]*)String.make ((len+7) lsr 3) c, 0, len</div>
75 <div class="lineNone">000048| else</div>
76 <div class="lineAllUnvisited">000049| (*[0]*)invalid_arg (</div>
77 <div class="lineNone">000050| sprintf "make_bitstring/create_bitstring: len %d < 0" len</div>
78 <div class="lineNone">000051| )</div>
79 <div class="lineNone">000052| </div>
80 <div class="lineAllVisited">000053| let create_bitstring len = (*[42903]*)make_bitstring len '\000'</div>
81 <div class="lineNone">000054| </div>
82 <div class="lineAllVisited">000055| let zeroes_bitstring = (*[43]*)create_bitstring</div>
83 <div class="lineNone">000056| </div>
84 <div class="lineAllVisited">000057| let ones_bitstring len = (*[1278457]*)make_bitstring len '\xff'</div>
85 <div class="lineNone">000058| </div>
86 <div class="lineAllVisited">000059| let bitstring_of_string str = (*[2]*)str, 0, String.length str lsl 3</div>
87 <div class="lineNone">000060| </div>
88 <div class="lineNone">000061| let bitstring_of_chan chan =</div>
89 <div class="lineAllVisited">000062| (*[36]*)let tmpsize = 16384 in</div>
90 <div class="lineAllVisited">000063| (*[36]*)let buf = Buffer.create tmpsize in</div>
91 <div class="lineAllVisited">000064| (*[36]*)let tmp = String.create tmpsize in</div>
92 <div class="lineAllVisited">000065| (*[36]*)let n = ref 0 in</div>
93 <div class="lineAllVisited">000066| (*[36]*)while (*[72]*)n := input chan tmp 0 tmpsize; !(*[72]*)n > 0 do</div>
94 <div class="lineAllVisited">000067| (*[36]*)Buffer.add_substring buf tmp 0 !n;</div>
95 <div class="lineNone">000068| done;</div>
96 <div class="lineAllVisited">000069| (*[36]*)Buffer.contents buf, 0, Buffer.length buf lsl 3</div>
97 <div class="lineNone">000070| </div>
98 <div class="lineNone">000071| let bitstring_of_chan_max chan max =</div>
99 <div class="lineAllVisited">000072| (*[2]*)let tmpsize = 16384 in</div>
100 <div class="lineAllVisited">000073| (*[2]*)let buf = Buffer.create tmpsize in</div>
101 <div class="lineAllVisited">000074| (*[2]*)let tmp = String.create tmpsize in</div>
102 <div class="lineAllVisited">000075| (*[2]*)let len = ref 0 in</div>
103 <div class="lineAllVisited">000076| (*[2]*)let rec loop () =</div>
104 <div class="lineAllVisited">000077| (*[2]*)if !len < max then (</div>
105 <div class="lineAllVisited">000078| (*[2]*)let r = min tmpsize (max - !len) in</div>
106 <div class="lineAllVisited">000079| (*[2]*)let n = input chan tmp 0 r in</div>
107 <div class="lineAllUnvisited">000080| (*[0]*)if n > 0 then (</div>
108 <div class="lineAllVisited">000081| (*[2]*)Buffer.add_substring buf tmp 0 n;</div>
109 <div class="lineAllVisited">000082| (*[2]*)len (*[2]*):= !len + n;</div>
110 <div class="lineAllVisited">000083| (*[2]*)loop ()</div>
111 <div class="lineNone">000084| )</div>
112 <div class="lineNone">000085| )</div>
113 <div class="lineNone">000086| in</div>
114 <div class="lineAllVisited">000087| (*[2]*)loop (*[2]*)();</div>
115 <div class="lineAllVisited">000088| (*[2]*)Buffer.contents buf, 0, !len lsl 3</div>
116 <div class="lineNone">000089| </div>
117 <div class="lineNone">000090| let bitstring_of_file_descr fd =</div>
118 <div class="lineAllVisited">000091| (*[1]*)let tmpsize = 16384 in</div>
119 <div class="lineAllVisited">000092| (*[1]*)let buf = Buffer.create tmpsize in</div>
120 <div class="lineAllVisited">000093| (*[1]*)let tmp = String.create tmpsize in</div>
121 <div class="lineAllVisited">000094| (*[1]*)let n = ref 0 in</div>
122 <div class="lineAllVisited">000095| (*[1]*)while (*[2]*)n := Unix.read fd tmp 0 tmpsize; !(*[2]*)n > 0 do</div>
123 <div class="lineAllVisited">000096| (*[1]*)Buffer.add_substring buf tmp 0 !n;</div>
124 <div class="lineNone">000097| done;</div>
125 <div class="lineAllVisited">000098| (*[1]*)Buffer.contents buf, 0, Buffer.length buf lsl 3</div>
126 <div class="lineNone">000099| </div>
127 <div class="lineNone">000100| let bitstring_of_file_descr_max fd max =</div>
128 <div class="lineAllVisited">000101| (*[2]*)let tmpsize = 16384 in</div>
129 <div class="lineAllVisited">000102| (*[2]*)let buf = Buffer.create tmpsize in</div>
130 <div class="lineAllVisited">000103| (*[2]*)let tmp = String.create tmpsize in</div>
131 <div class="lineAllVisited">000104| (*[2]*)let len = ref 0 in</div>
132 <div class="lineAllVisited">000105| (*[2]*)let rec loop () =</div>
133 <div class="lineAllVisited">000106| (*[2]*)if !len < max then (</div>
134 <div class="lineAllVisited">000107| (*[2]*)let r = min tmpsize (max - !len) in</div>
135 <div class="lineAllVisited">000108| (*[2]*)let n = Unix.read fd tmp 0 r in</div>
136 <div class="lineAllUnvisited">000109| (*[0]*)if n > 0 then (</div>
137 <div class="lineAllVisited">000110| (*[2]*)Buffer.add_substring buf tmp 0 n;</div>
138 <div class="lineAllVisited">000111| (*[2]*)len (*[2]*):= !len + n;</div>
139 <div class="lineAllVisited">000112| (*[2]*)loop ()</div>
140 <div class="lineNone">000113| )</div>
141 <div class="lineNone">000114| )</div>
142 <div class="lineNone">000115| in</div>
143 <div class="lineAllVisited">000116| (*[2]*)loop (*[2]*)();</div>
144 <div class="lineAllVisited">000117| (*[2]*)Buffer.contents buf, 0, !len lsl 3</div>
145 <div class="lineNone">000118| </div>
146 <div class="lineNone">000119| let bitstring_of_file fname =</div>
147 <div class="lineAllVisited">000120| (*[35]*)let chan = open_in_bin fname in</div>
148 <div class="lineAllVisited">000121| (*[35]*)try</div>
149 <div class="lineAllVisited">000122| (*[35]*)let bs = bitstring_of_chan chan in</div>
150 <div class="lineAllVisited">000123| (*[35]*)close_in (*[35]*)chan;</div>
151 <div class="lineAllVisited">000124| (*[35]*)bs</div>
152 <div class="lineNone">000125| with exn -></div>
153 <div class="lineAllUnvisited">000126| (*[0]*)close_in (*[0]*)chan;</div>
154 <div class="lineAllUnvisited">000127| (*[0]*)raise exn</div>
155 <div class="lineNone">000128| </div>
156 <div class="lineAllVisited">000129| let bitstring_length (_, _, len) = (*[1565492]*)len</div>
157 <div class="lineNone">000130| </div>
158 <div class="lineNone">000131| let subbitstring (data, off, len) off' len' =</div>
159 <div class="lineAllVisited">000132| (*[1]*)let off = off + off' in</div>
160 <div class="lineMixed">000133| (*[1]*)if len < off' + len' then (*[0]*)invalid_arg "subbitstring";</div>
161 <div class="lineAllVisited">000134| ((*[1]*)data, off, len')</div>
162 <div class="lineNone">000135| </div>
163 <div class="lineNone">000136| let dropbits n (data, off, len) =</div>
164 <div class="lineAllVisited">000137| (*[336643]*)let off = off + n in</div>
165 <div class="lineAllVisited">000138| (*[336643]*)let len = len - n in</div>
166 <div class="lineMixed">000139| (*[336643]*)if len < 0 then (*[0]*)invalid_arg "dropbits";</div>
167 <div class="lineAllVisited">000140| ((*[336643]*)data, off, len)</div>
168 <div class="lineNone">000141| </div>
169 <div class="lineNone">000142| let takebits n (data, off, len) =</div>
170 <div class="lineMixed">000143| (*[100]*)if len < n then (*[0]*)invalid_arg "takebits";</div>
171 <div class="lineAllVisited">000144| ((*[100]*)data, off, n)</div>
172 <div class="lineNone">000145| </div>
173 <div class="lineNone">000146| (*----------------------------------------------------------------------*)</div>
174 <div class="lineNone">000147| (* Bitwise functions.</div>
175 <div class="lineNone">000148| *</div>
176 <div class="lineNone">000149| * We try to isolate all bitwise functions within these modules.</div>
177 <div class="lineNone">000150| *)</div>
178 <div class="lineNone">000151| </div>
179 <div class="lineNone">000152| module I = struct</div>
180 <div class="lineNone">000153| (* Bitwise operations on ints. Note that we assume int <= 31 bits. *)</div>
181 <div class="lineNone">000154| external (<<<) : int -> int -> int = "%lslint"</div>
182 <div class="lineNone">000155| external (>>>) : int -> int -> int = "%lsrint"</div>
183 <div class="lineNone">000156| external to_int : int -> int = "%identity"</div>
184 <div class="lineAllVisited">000157| let zero = (*[43]*)0</div>
185 <div class="lineAllVisited">000158| let one = (*[43]*)1</div>
186 <div class="lineAllVisited">000159| let minus_one = (*[43]*)-1</div>
187 <div class="lineAllVisited">000160| let ff = (*[43]*)0xff</div>
188 <div class="lineNone">000161| </div>
189 <div class="lineNone">000162| (* Create a mask 0-31 bits wide. *)</div>
190 <div class="lineNone">000163| let mask bits =</div>
191 <div class="lineAllVisited">000164| (*[2342]*)if bits < 30 then</div>
192 <div class="lineAllVisited">000165| ((*[1952]*)one <<< bits) - 1</div>
193 <div class="lineAllVisited">000166| else (*[390]*)if bits = 30 then</div>
194 <div class="lineAllUnvisited">000167| (*[0]*)max_int</div>
195 <div class="lineAllVisited">000168| else (*[390]*)if bits = 31 then</div>
196 <div class="lineAllVisited">000169| (*[390]*)minus_one</div>
197 <div class="lineNone">000170| else</div>
198 <div class="lineAllUnvisited">000171| (*[0]*)invalid_arg "Bitstring.I.mask"</div>
199 <div class="lineNone">000172| </div>
200 <div class="lineNone">000173| (* Byte swap an int of a given size. *)</div>
201 <div class="lineNone">000174| let byteswap v bits =</div>
202 <div class="lineMixed">000175| (*[780]*)if bits <= 8 then (*[0]*)v</div>
203 <div class="lineAllVisited">000176| else (*[780]*)if bits <= 16 then (</div>
204 <div class="lineAllVisited">000177| (*[260]*)let shift = bits-8 in</div>
205 <div class="lineAllVisited">000178| (*[260]*)let v1 = v >>> shift in</div>
206 <div class="lineAllVisited">000179| (*[260]*)let v2 = ((v land (mask shift)) <<< 8) in</div>
207 <div class="lineAllVisited">000180| v2 (*[260]*)lor v1</div>
208 <div class="lineAllVisited">000181| ) else (*[520]*)if bits <= 24 then (</div>
209 <div class="lineAllVisited">000182| (*[260]*)let shift = bits - 16 in</div>
210 <div class="lineAllVisited">000183| (*[260]*)let v1 = v >>> (8+shift) in</div>
211 <div class="lineAllVisited">000184| (*[260]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
212 <div class="lineAllVisited">000185| (*[260]*)let v3 = (v land (mask shift)) <<< 16 in</div>
213 <div class="lineAllVisited">000186| v3 lor v2 (*[260]*)lor v1</div>
214 <div class="lineNone">000187| ) else (</div>
215 <div class="lineAllVisited">000188| (*[260]*)let shift = bits - 24 in</div>
216 <div class="lineAllVisited">000189| (*[260]*)let v1 = v >>> (16+shift) in</div>
217 <div class="lineAllVisited">000190| (*[260]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
218 <div class="lineAllVisited">000191| (*[260]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
219 <div class="lineAllVisited">000192| (*[260]*)let v4 = (v land (mask shift)) <<< 24 in</div>
220 <div class="lineAllVisited">000193| v4 lor v3 lor v2 (*[260]*)lor v1</div>
221 <div class="lineNone">000194| )</div>
222 <div class="lineNone">000195| </div>
223 <div class="lineNone">000196| (* Check a value is in range 0 .. 2^bits-1. *)</div>
224 <div class="lineNone">000197| let range_unsigned v bits =</div>
225 <div class="lineAllVisited">000198| (*[1172]*)let mask = lnot (mask bits) in</div>
226 <div class="lineAllVisited">000199| (v (*[1172]*)land mask) = zero</div>
227 <div class="lineNone">000200| </div>
228 <div class="lineNone">000201| (* Call function g on the top bits, then f on each full byte</div>
229 <div class="lineNone">000202| * (big endian - so start at top).</div>
230 <div class="lineNone">000203| *)</div>
231 <div class="lineNone">000204| let rec map_bytes_be g f v bits =</div>
232 <div class="lineAllVisited">000205| (*[1436]*)if bits >= 8 then (</div>
233 <div class="lineAllVisited">000206| (*[1044]*)map_bytes_be g f (v >>> 8) (*[1044]*)(bits-8);</div>
234 <div class="lineAllVisited">000207| (*[1044]*)let lsb = v land ff in</div>
235 <div class="lineAllVisited">000208| (*[1044]*)f (to_int lsb)</div>
236 <div class="lineAllVisited">000209| ) else (*[262]*)if bits > 0 then (</div>
237 <div class="lineAllVisited">000210| (*[130]*)let lsb = v land (mask bits) in</div>
238 <div class="lineAllVisited">000211| (*[130]*)g (to_int lsb) bits</div>
239 <div class="lineNone">000212| )</div>
240 <div class="lineNone">000213| </div>
241 <div class="lineNone">000214| (* Call function g on the top bits, then f on each full byte</div>
242 <div class="lineNone">000215| * (little endian - so start at root).</div>
243 <div class="lineNone">000216| *)</div>
244 <div class="lineNone">000217| let rec map_bytes_le g f v bits =</div>
245 <div class="lineAllVisited">000218| (*[2860]*)if bits >= 8 then (</div>
246 <div class="lineAllVisited">000219| (*[2080]*)let lsb = v land ff in</div>
247 <div class="lineAllVisited">000220| (*[2080]*)f (*[2080]*)(to_int lsb);</div>
248 <div class="lineAllVisited">000221| (*[2080]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
249 <div class="lineAllVisited">000222| ) else (*[520]*)if bits > 0 then (</div>
250 <div class="lineAllVisited">000223| (*[260]*)let lsb = v land (mask bits) in</div>
251 <div class="lineAllVisited">000224| (*[260]*)g (to_int lsb) bits</div>
252 <div class="lineNone">000225| )</div>
253 <div class="lineNone">000226| end</div>
254 <div class="lineNone">000227| </div>
255 <div class="lineNone">000228| module I32 = struct</div>
256 <div class="lineNone">000229| (* Bitwise operations on int32s. Note we try to keep it as similar</div>
257 <div class="lineNone">000230| * as possible to the I module above, to make it easier to track</div>
258 <div class="lineNone">000231| * down bugs.</div>
259 <div class="lineNone">000232| *)</div>
260 <div class="lineAllVisited">000233| let (<<<) = (*[43]*)Int32.shift_left</div>
261 <div class="lineAllVisited">000234| let (>>>) = (*[43]*)Int32.shift_right_logical</div>
262 <div class="lineAllVisited">000235| let (land) = (*[43]*)Int32.logand</div>
263 <div class="lineAllVisited">000236| let (lor) = (*[43]*)Int32.logor</div>
264 <div class="lineAllVisited">000237| let lnot = (*[43]*)Int32.lognot</div>
265 <div class="lineAllVisited">000238| let pred = (*[43]*)Int32.pred</div>
266 <div class="lineAllVisited">000239| let max_int = (*[43]*)Int32.max_int</div>
267 <div class="lineAllVisited">000240| let to_int = (*[43]*)Int32.to_int</div>
268 <div class="lineAllVisited">000241| let zero = (*[43]*)Int32.zero</div>
269 <div class="lineAllVisited">000242| let one = (*[43]*)Int32.one</div>
270 <div class="lineAllVisited">000243| let minus_one = (*[43]*)Int32.minus_one</div>
271 <div class="lineAllVisited">000244| let ff = (*[43]*)0xff_l</div>
272 <div class="lineNone">000245| </div>
273 <div class="lineNone">000246| (* Create a mask so many bits wide. *)</div>
274 <div class="lineNone">000247| let mask bits =</div>
275 <div class="lineAllVisited">000248| (*[272]*)if bits < 31 then</div>
276 <div class="lineAllVisited">000249| (*[272]*)pred (one <<< bits)</div>
277 <div class="lineAllUnvisited">000250| else (*[0]*)if bits = 31 then</div>
278 <div class="lineAllUnvisited">000251| (*[0]*)max_int</div>
279 <div class="lineAllUnvisited">000252| else (*[0]*)if bits = 32 then</div>
280 <div class="lineAllUnvisited">000253| (*[0]*)minus_one</div>
281 <div class="lineNone">000254| else</div>
282 <div class="lineAllUnvisited">000255| (*[0]*)invalid_arg "Bitstring.I32.mask"</div>
283 <div class="lineNone">000256| </div>
284 <div class="lineNone">000257| (* Byte swap an int of a given size. *)</div>
285 <div class="lineNone">000258| let byteswap v bits =</div>
286 <div class="lineMixed">000259| (*[272]*)if bits <= 8 then (*[0]*)v</div>
287 <div class="lineAllVisited">000260| else (*[272]*)if bits <= 16 then (</div>
288 <div class="lineAllUnvisited">000261| (*[0]*)let shift = bits-8 in</div>
289 <div class="lineAllUnvisited">000262| (*[0]*)let v1 = v >>> shift in</div>
290 <div class="lineAllUnvisited">000263| (*[0]*)let v2 = (v land (mask shift)) <<< 8 in</div>
291 <div class="lineAllUnvisited">000264| v2 (*[0]*)lor v1</div>
292 <div class="lineAllVisited">000265| ) else (*[272]*)if bits <= 24 then (</div>
293 <div class="lineAllUnvisited">000266| (*[0]*)let shift = bits - 16 in</div>
294 <div class="lineAllUnvisited">000267| (*[0]*)let v1 = v >>> (8+shift) in</div>
295 <div class="lineAllUnvisited">000268| (*[0]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
296 <div class="lineAllUnvisited">000269| (*[0]*)let v3 = (v land (mask shift)) <<< 16 in</div>
297 <div class="lineAllUnvisited">000270| v3 lor v2 (*[0]*)lor v1</div>
298 <div class="lineNone">000271| ) else (</div>
299 <div class="lineAllVisited">000272| (*[272]*)let shift = bits - 24 in</div>
300 <div class="lineAllVisited">000273| (*[272]*)let v1 = v >>> (16+shift) in</div>
301 <div class="lineAllVisited">000274| (*[272]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
302 <div class="lineAllVisited">000275| (*[272]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
303 <div class="lineAllVisited">000276| (*[272]*)let v4 = (v land (mask shift)) <<< 24 in</div>
304 <div class="lineAllVisited">000277| v4 lor v3 lor v2 (*[272]*)lor v1</div>
305 <div class="lineNone">000278| )</div>
306 <div class="lineNone">000279| </div>
307 <div class="lineNone">000280| (* Check a value is in range 0 .. 2^bits-1. *)</div>
308 <div class="lineNone">000281| let range_unsigned v bits =</div>
309 <div class="lineAllUnvisited">000282| (*[0]*)let mask = lnot (mask bits) in</div>
310 <div class="lineAllUnvisited">000283| (v (*[0]*)land mask) = zero</div>
311 <div class="lineNone">000284| </div>
312 <div class="lineNone">000285| (* Call function g on the top bits, then f on each full byte</div>
313 <div class="lineNone">000286| * (big endian - so start at top).</div>
314 <div class="lineNone">000287| *)</div>
315 <div class="lineNone">000288| let rec map_bytes_be g f v bits =</div>
316 <div class="lineAllUnvisited">000289| (*[0]*)if bits >= 8 then (</div>
317 <div class="lineAllUnvisited">000290| (*[0]*)map_bytes_be g f (v >>> 8) (*[0]*)(bits-8);</div>
318 <div class="lineAllUnvisited">000291| (*[0]*)let lsb = v land ff in</div>
319 <div class="lineAllUnvisited">000292| (*[0]*)f (to_int lsb)</div>
320 <div class="lineAllUnvisited">000293| ) else (*[0]*)if bits > 0 then (</div>
321 <div class="lineAllUnvisited">000294| (*[0]*)let lsb = v land (mask bits) in</div>
322 <div class="lineAllUnvisited">000295| (*[0]*)g (to_int lsb) bits</div>
323 <div class="lineNone">000296| )</div>
324 <div class="lineNone">000297| </div>
325 <div class="lineNone">000298| (* Call function g on the top bits, then f on each full byte</div>
326 <div class="lineNone">000299| * (little endian - so start at root).</div>
327 <div class="lineNone">000300| *)</div>
328 <div class="lineNone">000301| let rec map_bytes_le g f v bits =</div>
329 <div class="lineAllUnvisited">000302| (*[0]*)if bits >= 8 then (</div>
330 <div class="lineAllUnvisited">000303| (*[0]*)let lsb = v land ff in</div>
331 <div class="lineAllUnvisited">000304| (*[0]*)f (*[0]*)(to_int lsb);</div>
332 <div class="lineAllUnvisited">000305| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
333 <div class="lineAllUnvisited">000306| ) else (*[0]*)if bits > 0 then (</div>
334 <div class="lineAllUnvisited">000307| (*[0]*)let lsb = v land (mask bits) in</div>
335 <div class="lineAllUnvisited">000308| (*[0]*)g (to_int lsb) bits</div>
336 <div class="lineNone">000309| )</div>
337 <div class="lineNone">000310| end</div>
338 <div class="lineNone">000311| </div>
339 <div class="lineNone">000312| module I64 = struct</div>
340 <div class="lineNone">000313| (* Bitwise operations on int64s. Note we try to keep it as similar</div>
341 <div class="lineNone">000314| * as possible to the I/I32 modules above, to make it easier to track</div>
342 <div class="lineNone">000315| * down bugs.</div>
343 <div class="lineNone">000316| *)</div>
344 <div class="lineAllVisited">000317| let (<<<) = (*[43]*)Int64.shift_left</div>
345 <div class="lineAllVisited">000318| let (>>>) = (*[43]*)Int64.shift_right_logical</div>
346 <div class="lineAllVisited">000319| let (land) = (*[43]*)Int64.logand</div>
347 <div class="lineAllVisited">000320| let (lor) = (*[43]*)Int64.logor</div>
348 <div class="lineAllVisited">000321| let lnot = (*[43]*)Int64.lognot</div>
349 <div class="lineAllVisited">000322| let pred = (*[43]*)Int64.pred</div>
350 <div class="lineAllVisited">000323| let max_int = (*[43]*)Int64.max_int</div>
351 <div class="lineAllVisited">000324| let to_int = (*[43]*)Int64.to_int</div>
352 <div class="lineAllVisited">000325| let zero = (*[43]*)Int64.zero</div>
353 <div class="lineAllVisited">000326| let one = (*[43]*)Int64.one</div>
354 <div class="lineAllVisited">000327| let minus_one = (*[43]*)Int64.minus_one</div>
355 <div class="lineAllVisited">000328| let ff = (*[43]*)0xff_L</div>
356 <div class="lineNone">000329| </div>
357 <div class="lineNone">000330| (* Create a mask so many bits wide. *)</div>
358 <div class="lineNone">000331| let mask bits =</div>
359 <div class="lineAllVisited">000332| (*[670350]*)if bits < 63 then</div>
360 <div class="lineAllVisited">000333| (*[664750]*)pred (one <<< bits)</div>
361 <div class="lineAllVisited">000334| else (*[5600]*)if bits = 63 then</div>
362 <div class="lineAllVisited">000335| (*[4950]*)max_int</div>
363 <div class="lineAllVisited">000336| else (*[650]*)if bits = 64 then</div>
364 <div class="lineAllVisited">000337| (*[650]*)minus_one</div>
365 <div class="lineNone">000338| else</div>
366 <div class="lineAllUnvisited">000339| (*[0]*)invalid_arg "Bitstring.I64.mask"</div>
367 <div class="lineNone">000340| </div>
368 <div class="lineNone">000341| (* Byte swap an int of a given size. *)</div>
369 <div class="lineNone">000342| (* let byteswap v bits = *)</div>
370 <div class="lineNone">000343| </div>
371 <div class="lineNone">000344| (* Check a value is in range 0 .. 2^bits-1. *)</div>
372 <div class="lineNone">000345| let range_unsigned v bits =</div>
373 <div class="lineAllVisited">000346| (*[352630]*)let mask = lnot (mask bits) in</div>
374 <div class="lineAllVisited">000347| (v (*[352630]*)land mask) = zero</div>
375 <div class="lineNone">000348| </div>
376 <div class="lineNone">000349| (* Call function g on the top bits, then f on each full byte</div>
377 <div class="lineNone">000350| * (big endian - so start at top).</div>
378 <div class="lineNone">000351| *)</div>
379 <div class="lineNone">000352| let rec map_bytes_be g f v bits =</div>
380 <div class="lineAllVisited">000353| (*[1462730]*)if bits >= 8 then (</div>
381 <div class="lineAllVisited">000354| (*[1110620]*)map_bytes_be g f (v >>> 8) (*[1110620]*)(bits-8);</div>
382 <div class="lineAllVisited">000355| (*[1110620]*)let lsb = v land ff in</div>
383 <div class="lineAllVisited">000356| (*[1110620]*)f (to_int lsb)</div>
384 <div class="lineAllVisited">000357| ) else (*[34910]*)if bits > 0 then (</div>
385 <div class="lineAllVisited">000358| (*[317200]*)let lsb = v land (mask bits) in</div>
386 <div class="lineAllVisited">000359| (*[317200]*)g (to_int lsb) bits</div>
387 <div class="lineNone">000360| )</div>
388 <div class="lineNone">000361| </div>
389 <div class="lineNone">000362| (* Call function g on the top bits, then f on each full byte</div>
390 <div class="lineNone">000363| * (little endian - so start at root).</div>
391 <div class="lineNone">000364| *)</div>
392 <div class="lineNone">000365| let rec map_bytes_le g f v bits =</div>
393 <div class="lineAllVisited">000366| (*[4160]*)if bits >= 8 then (</div>
394 <div class="lineAllVisited">000367| (*[3640]*)let lsb = v land ff in</div>
395 <div class="lineAllVisited">000368| (*[3640]*)f (*[3640]*)(to_int lsb);</div>
396 <div class="lineAllVisited">000369| (*[3640]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
397 <div class="lineAllVisited">000370| ) else (*[520]*)if bits > 0 then (</div>
398 <div class="lineAllUnvisited">000371| (*[0]*)let lsb = v land (mask bits) in</div>
399 <div class="lineAllUnvisited">000372| (*[0]*)g (to_int lsb) bits</div>
400 <div class="lineNone">000373| )</div>
401 <div class="lineNone">000374| end</div>
402 <div class="lineNone">000375| </div>
403 <div class="lineNone">000376| (*----------------------------------------------------------------------*)</div>
404 <div class="lineNone">000377| (* Extraction functions.</div>
405 <div class="lineNone">000378| *</div>
406 <div class="lineNone">000379| * NB: internal functions, called from the generated macros, and</div>
407 <div class="lineNone">000380| * the parameters should have been checked for sanity already).</div>
408 <div class="lineNone">000381| *)</div>
409 <div class="lineNone">000382| </div>
410 <div class="lineNone">000383| (* Extract and convert to numeric. A single bit is returned as</div>
411 <div class="lineNone">000384| * a boolean. There are no endianness or signedness considerations.</div>
412 <div class="lineNone">000385| *)</div>
413 <div class="lineNone">000386| let extract_bit data off len _ = (* final param is always 1 *)</div>
414 <div class="lineAllVisited">000387| (*[2515282]*)let byteoff = off lsr 3 in</div>
415 <div class="lineAllVisited">000388| (*[2515282]*)let bitmask = 1 lsl (7 - (off land 7)) in</div>
416 <div class="lineAllVisited">000389| (*[2515282]*)let b = Char.code data.[byteoff] land bitmask <> 0 in</div>
417 <div class="lineAllVisited">000390| (*[2515282]*)b (*, off+1, len-1*)</div>
418 <div class="lineNone">000391| </div>
419 <div class="lineNone">000392| (* Returns 8 bit unsigned aligned bytes from the string.</div>
420 <div class="lineNone">000393| * If the string ends then this returns 0's.</div>
421 <div class="lineNone">000394| *)</div>
422 <div class="lineNone">000395| let _get_byte data byteoff strlen =</div>
423 <div class="lineAllVisited">000396| (*[9840892]*)if strlen > byteoff then (*[9274362]*)Char.code data.[byteoff] else (*[566530]*)0</div>
424 <div class="lineNone">000397| let _get_byte32 data byteoff strlen =</div>
425 <div class="lineMixed">000398| (*[264]*)if strlen > byteoff then (*[264]*)Int32.of_int (Char.code data.[byteoff]) else (*[0]*)0l</div>
426 <div class="lineNone">000399| let _get_byte64 data byteoff strlen =</div>
427 <div class="lineAllVisited">000400| (*[1626792]*)if strlen > byteoff then (*[1518549]*)Int64.of_int (Char.code data.[byteoff]) else (*[108243]*)0L</div>
428 <div class="lineNone">000401| </div>
429 <div class="lineNone">000402| (* Extract [2..8] bits. Because the result fits into a single</div>
430 <div class="lineNone">000403| * byte we don't have to worry about endianness, only signedness.</div>
431 <div class="lineNone">000404| *)</div>
432 <div class="lineNone">000405| let extract_char_unsigned data off len flen =</div>
433 <div class="lineAllVisited">000406| (*[5040562]*)let byteoff = off lsr 3 in</div>
434 <div class="lineNone">000407| </div>
435 <div class="lineNone">000408| (* Optimize the common (byte-aligned) case. *)</div>
436 <div class="lineAllVisited">000409| (*[5040562]*)if off land 7 = 0 then (</div>
437 <div class="lineAllVisited">000410| (*[121776]*)let byte = Char.code data.[byteoff] in</div>
438 <div class="lineAllVisited">000411| byte (*[121776]*)lsr (8 - flen) (*, off+flen, len-flen*)</div>
439 <div class="lineNone">000412| ) else (</div>
440 <div class="lineNone">000413| (* Extract the 16 bits at byteoff and byteoff+1 (note that the</div>
441 <div class="lineNone">000414| * second byte might not exist in the original string).</div>
442 <div class="lineNone">000415| *)</div>
443 <div class="lineAllVisited">000416| (*[4918786]*)let strlen = String.length data in</div>
444 <div class="lineNone">000417| </div>
445 <div class="lineAllVisited">000418| (*[4918786]*)let word =</div>
446 <div class="lineNone">000419| (_get_byte data byteoff strlen lsl 8) +</div>
447 <div class="lineNone">000420| _get_byte data (byteoff+1) strlen in</div>
448 <div class="lineNone">000421| </div>
449 <div class="lineNone">000422| (* Mask off the top bits. *)</div>
450 <div class="lineAllVisited">000423| (*[4918786]*)let bitmask = (1 lsl (16 - (off land 7))) - 1 in</div>
451 <div class="lineAllVisited">000424| (*[4918786]*)let word = word land bitmask in</div>
452 <div class="lineNone">000425| (* Shift right to get rid of the bottom bits. *)</div>
453 <div class="lineAllVisited">000426| (*[4918786]*)let shift = 16 - ((off land 7) + flen) in</div>
454 <div class="lineAllVisited">000427| (*[4918786]*)let word = word lsr shift in</div>
455 <div class="lineNone">000428| </div>
456 <div class="lineAllVisited">000429| (*[4918786]*)word (*, off+flen, len-flen*)</div>
457 <div class="lineNone">000430| )</div>
458 <div class="lineNone">000431| </div>
459 <div class="lineNone">000432| (* Extract [9..31] bits. We have to consider endianness and signedness. *)</div>
460 <div class="lineNone">000433| let extract_int_be_unsigned data off len flen =</div>
461 <div class="lineAllVisited">000434| (*[1170]*)let byteoff = off lsr 3 in</div>
462 <div class="lineNone">000435| </div>
463 <div class="lineAllVisited">000436| (*[1170]*)let strlen = String.length data in</div>
464 <div class="lineNone">000437| </div>
465 <div class="lineAllVisited">000438| (*[1170]*)let word =</div>
466 <div class="lineNone">000439| (* Optimize the common (byte-aligned) case. *)</div>
467 <div class="lineNone">000440| if off land 7 = 0 then (</div>
468 <div class="lineAllVisited">000441| (*[152]*)let word =</div>
469 <div class="lineNone">000442| (_get_byte data byteoff strlen lsl 23) +</div>
470 <div class="lineNone">000443| (_get_byte data (byteoff+1) strlen lsl 15) +</div>
471 <div class="lineNone">000444| (_get_byte data (byteoff+2) strlen lsl 7) +</div>
472 <div class="lineNone">000445| (_get_byte data (byteoff+3) strlen lsr 1) in</div>
473 <div class="lineAllVisited">000446| word (*[152]*)lsr (31 - flen)</div>
474 <div class="lineAllVisited">000447| ) else (*[1018]*)if flen <= 24 then (</div>
475 <div class="lineNone">000448| (* Extract the 31 bits at byteoff .. byteoff+3. *)</div>
476 <div class="lineAllVisited">000449| (*[678]*)let word =</div>
477 <div class="lineNone">000450| (_get_byte data byteoff strlen lsl 23) +</div>
478 <div class="lineNone">000451| (_get_byte data (byteoff+1) strlen lsl 15) +</div>
479 <div class="lineNone">000452| (_get_byte data (byteoff+2) strlen lsl 7) +</div>
480 <div class="lineNone">000453| (_get_byte data (byteoff+3) strlen lsr 1) in</div>
481 <div class="lineNone">000454| (* Mask off the top bits. *)</div>
482 <div class="lineAllVisited">000455| (*[678]*)let bitmask = (1 lsl (31 - (off land 7))) - 1 in</div>
483 <div class="lineAllVisited">000456| (*[678]*)let word = word land bitmask in</div>
484 <div class="lineNone">000457| (* Shift right to get rid of the bottom bits. *)</div>
485 <div class="lineAllVisited">000458| (*[678]*)let shift = 31 - ((off land 7) + flen) in</div>
486 <div class="lineAllVisited">000459| word (*[678]*)lsr shift</div>
487 <div class="lineNone">000460| ) else (</div>
488 <div class="lineNone">000461| (* Extract the next 31 bits, slow method. *)</div>
489 <div class="lineAllVisited">000462| (*[340]*)let word =</div>
490 <div class="lineNone">000463| let c0 = extract_char_unsigned data off len 8</div>
491 <div class="lineNone">000464| and off = off + 8 and len = len - 8 in</div>
492 <div class="lineAllVisited">000465| (*[340]*)let c1 = extract_char_unsigned data off len 8</div>
493 <div class="lineNone">000466| and off = off + 8 and len = len - 8 in</div>
494 <div class="lineAllVisited">000467| (*[340]*)let c2 = extract_char_unsigned data off len 8</div>
495 <div class="lineNone">000468| and off = off + 8 and len = len - 8 in</div>
496 <div class="lineAllVisited">000469| (*[340]*)let c3 = extract_char_unsigned data off len 7 in</div>
497 <div class="lineAllVisited">000470| (c0 (*[340]*)lsl 23) + (c1 lsl 15) + (c2 lsl 7) + c3 in</div>
498 <div class="lineAllVisited">000471| word (*[340]*)lsr (31 - flen)</div>
499 <div class="lineNone">000472| ) in</div>
500 <div class="lineAllVisited">000473| (*[1170]*)word (*, off+flen, len-flen*)</div>
501 <div class="lineNone">000474| </div>
502 <div class="lineNone">000475| let extract_int_le_unsigned data off len flen =</div>
503 <div class="lineAllVisited">000476| (*[780]*)let v = extract_int_be_unsigned data off len flen in</div>
504 <div class="lineAllVisited">000477| (*[780]*)let v = I.byteswap v flen in</div>
505 <div class="lineAllVisited">000478| (*[780]*)v</div>
506 <div class="lineNone">000479| </div>
507 <div class="lineNone">000480| let extract_int_ne_unsigned =</div>
508 <div class="lineAllVisited">000481| (*[43]*)if nativeendian = BigEndian</div>
509 <div class="lineAllUnvisited">000482| then (*[0]*)extract_int_be_unsigned</div>
510 <div class="lineAllVisited">000483| else (*[43]*)extract_int_le_unsigned</div>
511 <div class="lineNone">000484| </div>
512 <div class="lineNone">000485| let extract_int_ee_unsigned = function</div>
513 <div class="lineAllUnvisited">000486| | BigEndian -> (*[0]*)extract_int_be_unsigned</div>
514 <div class="lineAllUnvisited">000487| | LittleEndian -> (*[0]*)extract_int_le_unsigned</div>
515 <div class="lineAllUnvisited">000488| | NativeEndian -> (*[0]*)extract_int_ne_unsigned</div>
516 <div class="lineNone">000489| </div>
517 <div class="lineNone">000490| let _make_int32_be c0 c1 c2 c3 =</div>
518 <div class="lineAllVisited">000491| (*[408]*)Int32.logor</div>
519 <div class="lineNone">000492| (Int32.logor</div>
520 <div class="lineNone">000493| (Int32.logor</div>
521 <div class="lineNone">000494| (Int32.shift_left c0 24)</div>
522 <div class="lineNone">000495| (Int32.shift_left c1 16))</div>
523 <div class="lineNone">000496| (Int32.shift_left c2 8))</div>
524 <div class="lineNone">000497| c3</div>
525 <div class="lineNone">000498| </div>
526 <div class="lineNone">000499| let _make_int32_le c0 c1 c2 c3 =</div>
527 <div class="lineAllUnvisited">000500| (*[0]*)Int32.logor</div>
528 <div class="lineNone">000501| (Int32.logor</div>
529 <div class="lineNone">000502| (Int32.logor</div>
530 <div class="lineNone">000503| (Int32.shift_left c3 24)</div>
531 <div class="lineNone">000504| (Int32.shift_left c2 16))</div>
532 <div class="lineNone">000505| (Int32.shift_left c1 8))</div>
533 <div class="lineNone">000506| c0</div>
534 <div class="lineNone">000507| </div>
535 <div class="lineNone">000508| (* Extract exactly 32 bits. We have to consider endianness and signedness. *)</div>
536 <div class="lineNone">000509| let extract_int32_be_unsigned data off len flen =</div>
537 <div class="lineAllVisited">000510| (*[408]*)let byteoff = off lsr 3 in</div>
538 <div class="lineNone">000511| </div>
539 <div class="lineAllVisited">000512| (*[408]*)let strlen = String.length data in</div>
540 <div class="lineNone">000513| </div>
541 <div class="lineAllVisited">000514| (*[408]*)let word =</div>
542 <div class="lineNone">000515| (* Optimize the common (byte-aligned) case. *)</div>
543 <div class="lineNone">000516| if off land 7 = 0 then (</div>
544 <div class="lineAllVisited">000517| (*[66]*)let word =</div>
545 <div class="lineNone">000518| let c0 = _get_byte32 data byteoff strlen in</div>
546 <div class="lineAllVisited">000519| (*[66]*)let c1 = _get_byte32 data (byteoff+1) strlen in</div>
547 <div class="lineAllVisited">000520| (*[66]*)let c2 = _get_byte32 data (byteoff+2) strlen in</div>
548 <div class="lineAllVisited">000521| (*[66]*)let c3 = _get_byte32 data (byteoff+3) strlen in</div>
549 <div class="lineAllVisited">000522| (*[66]*)_make_int32_be c0 c1 c2 c3 in</div>
550 <div class="lineAllVisited">000523| (*[66]*)Int32.shift_right_logical word (32 - flen)</div>
551 <div class="lineNone">000524| ) else (</div>
552 <div class="lineNone">000525| (* Extract the next 32 bits, slow method. *)</div>
553 <div class="lineAllVisited">000526| (*[342]*)let word =</div>
554 <div class="lineNone">000527| let c0 = extract_char_unsigned data off len 8</div>
555 <div class="lineNone">000528| and off = off + 8 and len = len - 8 in</div>
556 <div class="lineAllVisited">000529| (*[342]*)let c1 = extract_char_unsigned data off len 8</div>
557 <div class="lineNone">000530| and off = off + 8 and len = len - 8 in</div>
558 <div class="lineAllVisited">000531| (*[342]*)let c2 = extract_char_unsigned data off len 8</div>
559 <div class="lineNone">000532| and off = off + 8 and len = len - 8 in</div>
560 <div class="lineAllVisited">000533| (*[342]*)let c3 = extract_char_unsigned data off len 8 in</div>
561 <div class="lineAllVisited">000534| (*[342]*)let c0 = Int32.of_int c0 in</div>
562 <div class="lineAllVisited">000535| (*[342]*)let c1 = Int32.of_int c1 in</div>
563 <div class="lineAllVisited">000536| (*[342]*)let c2 = Int32.of_int c2 in</div>
564 <div class="lineAllVisited">000537| (*[342]*)let c3 = Int32.of_int c3 in</div>
565 <div class="lineAllVisited">000538| (*[342]*)_make_int32_be c0 c1 c2 c3 in</div>
566 <div class="lineAllVisited">000539| (*[342]*)Int32.shift_right_logical word (32 - flen)</div>
567 <div class="lineNone">000540| ) in</div>
568 <div class="lineAllVisited">000541| (*[408]*)word (*, off+flen, len-flen*)</div>
569 <div class="lineNone">000542| </div>
570 <div class="lineNone">000543| let extract_int32_le_unsigned data off len flen =</div>
571 <div class="lineAllVisited">000544| (*[272]*)let v = extract_int32_be_unsigned data off len flen in</div>
572 <div class="lineAllVisited">000545| (*[272]*)let v = I32.byteswap v flen in</div>
573 <div class="lineAllVisited">000546| (*[272]*)v</div>
574 <div class="lineNone">000547| </div>
575 <div class="lineNone">000548| let extract_int32_ne_unsigned =</div>
576 <div class="lineAllVisited">000549| (*[43]*)if nativeendian = BigEndian</div>
577 <div class="lineAllUnvisited">000550| then (*[0]*)extract_int32_be_unsigned</div>
578 <div class="lineAllVisited">000551| else (*[43]*)extract_int32_le_unsigned</div>
579 <div class="lineNone">000552| </div>
580 <div class="lineNone">000553| let extract_int32_ee_unsigned = function</div>
581 <div class="lineAllVisited">000554| | BigEndian -> (*[6]*)extract_int32_be_unsigned</div>
582 <div class="lineAllVisited">000555| | LittleEndian -> (*[6]*)extract_int32_le_unsigned</div>
583 <div class="lineAllVisited">000556| | NativeEndian -> (*[6]*)extract_int32_ne_unsigned</div>
584 <div class="lineNone">000557| </div>
585 <div class="lineNone">000558| let _make_int64_be c0 c1 c2 c3 c4 c5 c6 c7 =</div>
586 <div class="lineAllVisited">000559| (*[658243]*)Int64.logor</div>
587 <div class="lineNone">000560| (Int64.logor</div>
588 <div class="lineNone">000561| (Int64.logor</div>
589 <div class="lineNone">000562| (Int64.logor</div>
590 <div class="lineNone">000563| (Int64.logor</div>
591 <div class="lineNone">000564| (Int64.logor</div>
592 <div class="lineNone">000565| (Int64.logor</div>
593 <div class="lineNone">000566| (Int64.shift_left c0 56)</div>
594 <div class="lineNone">000567| (Int64.shift_left c1 48))</div>
595 <div class="lineNone">000568| (Int64.shift_left c2 40))</div>
596 <div class="lineNone">000569| (Int64.shift_left c3 32))</div>
597 <div class="lineNone">000570| (Int64.shift_left c4 24))</div>
598 <div class="lineNone">000571| (Int64.shift_left c5 16))</div>
599 <div class="lineNone">000572| (Int64.shift_left c6 8))</div>
600 <div class="lineNone">000573| c7</div>
601 <div class="lineNone">000574| </div>
602 <div class="lineNone">000575| let _make_int64_le c0 c1 c2 c3 c4 c5 c6 c7 =</div>
603 <div class="lineAllVisited">000576| (*[520]*)_make_int64_be c7 c6 c5 c4 c3 c2 c1 c0</div>
604 <div class="lineNone">000577| </div>
605 <div class="lineNone">000578| (* Extract [1..64] bits. We have to consider endianness and signedness. *)</div>
606 <div class="lineNone">000579| let extract_int64_be_unsigned data off len flen =</div>
607 <div class="lineAllVisited">000580| (*[657723]*)let byteoff = off lsr 3 in</div>
608 <div class="lineNone">000581| </div>
609 <div class="lineAllVisited">000582| (*[657723]*)let strlen = String.length data in</div>
610 <div class="lineNone">000583| </div>
611 <div class="lineAllVisited">000584| (*[657723]*)let word =</div>
612 <div class="lineNone">000585| (* Optimize the common (byte-aligned) case. *)</div>
613 <div class="lineNone">000586| if off land 7 = 0 then (</div>
614 <div class="lineAllVisited">000587| (*[203285]*)let word =</div>
615 <div class="lineNone">000588| let c0 = _get_byte64 data byteoff strlen in</div>
616 <div class="lineAllVisited">000589| (*[203285]*)let c1 = _get_byte64 data (byteoff+1) strlen in</div>
617 <div class="lineAllVisited">000590| (*[203285]*)let c2 = _get_byte64 data (byteoff+2) strlen in</div>
618 <div class="lineAllVisited">000591| (*[203285]*)let c3 = _get_byte64 data (byteoff+3) strlen in</div>
619 <div class="lineAllVisited">000592| (*[203285]*)let c4 = _get_byte64 data (byteoff+4) strlen in</div>
620 <div class="lineAllVisited">000593| (*[203285]*)let c5 = _get_byte64 data (byteoff+5) strlen in</div>
621 <div class="lineAllVisited">000594| (*[203285]*)let c6 = _get_byte64 data (byteoff+6) strlen in</div>
622 <div class="lineAllVisited">000595| (*[203285]*)let c7 = _get_byte64 data (byteoff+7) strlen in</div>
623 <div class="lineAllVisited">000596| (*[203285]*)_make_int64_be c0 c1 c2 c3 c4 c5 c6 c7 in</div>
624 <div class="lineAllVisited">000597| (*[203285]*)Int64.shift_right_logical word (64 - flen)</div>
625 <div class="lineNone">000598| ) else (</div>
626 <div class="lineNone">000599| (* Extract the next 64 bits, slow method. *)</div>
627 <div class="lineAllVisited">000600| (*[454438]*)let word =</div>
628 <div class="lineNone">000601| let c0 = extract_char_unsigned data off len 8</div>
629 <div class="lineNone">000602| and off = off + 8 and len = len - 8 in</div>
630 <div class="lineAllVisited">000603| (*[454438]*)let c1 = extract_char_unsigned data off len 8</div>
631 <div class="lineNone">000604| and off = off + 8 and len = len - 8 in</div>
632 <div class="lineAllVisited">000605| (*[454438]*)let c2 = extract_char_unsigned data off len 8</div>
633 <div class="lineNone">000606| and off = off + 8 and len = len - 8 in</div>
634 <div class="lineAllVisited">000607| (*[454438]*)let c3 = extract_char_unsigned data off len 8</div>
635 <div class="lineNone">000608| and off = off + 8 and len = len - 8 in</div>
636 <div class="lineAllVisited">000609| (*[454438]*)let c4 = extract_char_unsigned data off len 8</div>
637 <div class="lineNone">000610| and off = off + 8 and len = len - 8 in</div>
638 <div class="lineAllVisited">000611| (*[454438]*)let c5 = extract_char_unsigned data off len 8</div>
639 <div class="lineNone">000612| and off = off + 8 and len = len - 8 in</div>
640 <div class="lineAllVisited">000613| (*[454438]*)let c6 = extract_char_unsigned data off len 8</div>
641 <div class="lineNone">000614| and off = off + 8 and len = len - 8 in</div>
642 <div class="lineAllVisited">000615| (*[454438]*)let c7 = extract_char_unsigned data off len 8 in</div>
643 <div class="lineAllVisited">000616| (*[454438]*)let c0 = Int64.of_int c0 in</div>
644 <div class="lineAllVisited">000617| (*[454438]*)let c1 = Int64.of_int c1 in</div>
645 <div class="lineAllVisited">000618| (*[454438]*)let c2 = Int64.of_int c2 in</div>
646 <div class="lineAllVisited">000619| (*[454438]*)let c3 = Int64.of_int c3 in</div>
647 <div class="lineAllVisited">000620| (*[454438]*)let c4 = Int64.of_int c4 in</div>
648 <div class="lineAllVisited">000621| (*[454438]*)let c5 = Int64.of_int c5 in</div>
649 <div class="lineAllVisited">000622| (*[454438]*)let c6 = Int64.of_int c6 in</div>
650 <div class="lineAllVisited">000623| (*[454438]*)let c7 = Int64.of_int c7 in</div>
651 <div class="lineAllVisited">000624| (*[454438]*)_make_int64_be c0 c1 c2 c3 c4 c5 c6 c7 in</div>
652 <div class="lineAllVisited">000625| (*[454438]*)Int64.shift_right_logical word (64 - flen)</div>
653 <div class="lineNone">000626| ) in</div>
654 <div class="lineAllVisited">000627| (*[657723]*)word (*, off+flen, len-flen*)</div>
655 <div class="lineNone">000628| </div>
656 <div class="lineNone">000629| let extract_int64_le_unsigned data off len flen =</div>
657 <div class="lineAllVisited">000630| (*[520]*)let byteoff = off lsr 3 in</div>
658 <div class="lineNone">000631| </div>
659 <div class="lineAllVisited">000632| (*[520]*)let strlen = String.length data in</div>
660 <div class="lineNone">000633| </div>
661 <div class="lineAllVisited">000634| (*[520]*)let word =</div>
662 <div class="lineNone">000635| (* Optimize the common (byte-aligned) case. *)</div>
663 <div class="lineNone">000636| if off land 7 = 0 then (</div>
664 <div class="lineAllVisited">000637| (*[64]*)let word =</div>
665 <div class="lineNone">000638| let c0 = _get_byte64 data byteoff strlen in</div>
666 <div class="lineAllVisited">000639| (*[64]*)let c1 = _get_byte64 data (byteoff+1) strlen in</div>
667 <div class="lineAllVisited">000640| (*[64]*)let c2 = _get_byte64 data (byteoff+2) strlen in</div>
668 <div class="lineAllVisited">000641| (*[64]*)let c3 = _get_byte64 data (byteoff+3) strlen in</div>
669 <div class="lineAllVisited">000642| (*[64]*)let c4 = _get_byte64 data (byteoff+4) strlen in</div>
670 <div class="lineAllVisited">000643| (*[64]*)let c5 = _get_byte64 data (byteoff+5) strlen in</div>
671 <div class="lineAllVisited">000644| (*[64]*)let c6 = _get_byte64 data (byteoff+6) strlen in</div>
672 <div class="lineAllVisited">000645| (*[64]*)let c7 = _get_byte64 data (byteoff+7) strlen in</div>
673 <div class="lineAllVisited">000646| (*[64]*)_make_int64_le c0 c1 c2 c3 c4 c5 c6 c7 in</div>
674 <div class="lineAllVisited">000647| (*[64]*)Int64.logand word (I64.mask flen)</div>
675 <div class="lineNone">000648| ) else (</div>
676 <div class="lineNone">000649| (* Extract the next 64 bits, slow method. *)</div>
677 <div class="lineAllVisited">000650| (*[456]*)let word =</div>
678 <div class="lineNone">000651| let c0 = extract_char_unsigned data off len 8</div>
679 <div class="lineNone">000652| and off = off + 8 and len = len - 8 in</div>
680 <div class="lineAllVisited">000653| (*[456]*)let c1 = extract_char_unsigned data off len 8</div>
681 <div class="lineNone">000654| and off = off + 8 and len = len - 8 in</div>
682 <div class="lineAllVisited">000655| (*[456]*)let c2 = extract_char_unsigned data off len 8</div>
683 <div class="lineNone">000656| and off = off + 8 and len = len - 8 in</div>
684 <div class="lineAllVisited">000657| (*[456]*)let c3 = extract_char_unsigned data off len 8</div>
685 <div class="lineNone">000658| and off = off + 8 and len = len - 8 in</div>
686 <div class="lineAllVisited">000659| (*[456]*)let c4 = extract_char_unsigned data off len 8</div>
687 <div class="lineNone">000660| and off = off + 8 and len = len - 8 in</div>
688 <div class="lineAllVisited">000661| (*[456]*)let c5 = extract_char_unsigned data off len 8</div>
689 <div class="lineNone">000662| and off = off + 8 and len = len - 8 in</div>
690 <div class="lineAllVisited">000663| (*[456]*)let c6 = extract_char_unsigned data off len 8</div>
691 <div class="lineNone">000664| and off = off + 8 and len = len - 8 in</div>
692 <div class="lineAllVisited">000665| (*[456]*)let c7 = extract_char_unsigned data off len 8 in</div>
693 <div class="lineAllVisited">000666| (*[456]*)let c0 = Int64.of_int c0 in</div>
694 <div class="lineAllVisited">000667| (*[456]*)let c1 = Int64.of_int c1 in</div>
695 <div class="lineAllVisited">000668| (*[456]*)let c2 = Int64.of_int c2 in</div>
696 <div class="lineAllVisited">000669| (*[456]*)let c3 = Int64.of_int c3 in</div>
697 <div class="lineAllVisited">000670| (*[456]*)let c4 = Int64.of_int c4 in</div>
698 <div class="lineAllVisited">000671| (*[456]*)let c5 = Int64.of_int c5 in</div>
699 <div class="lineAllVisited">000672| (*[456]*)let c6 = Int64.of_int c6 in</div>
700 <div class="lineAllVisited">000673| (*[456]*)let c7 = Int64.of_int c7 in</div>
701 <div class="lineAllVisited">000674| (*[456]*)_make_int64_le c0 c1 c2 c3 c4 c5 c6 c7 in</div>
702 <div class="lineAllVisited">000675| (*[456]*)Int64.logand word (I64.mask flen)</div>
703 <div class="lineNone">000676| ) in</div>
704 <div class="lineAllVisited">000677| (*[520]*)word (*, off+flen, len-flen*)</div>
705 <div class="lineNone">000678| </div>
706 <div class="lineNone">000679| let extract_int64_ne_unsigned =</div>
707 <div class="lineAllVisited">000680| (*[43]*)if nativeendian = BigEndian</div>
708 <div class="lineAllUnvisited">000681| then (*[0]*)extract_int64_be_unsigned</div>
709 <div class="lineAllVisited">000682| else (*[43]*)extract_int64_le_unsigned</div>
710 <div class="lineNone">000683| </div>
711 <div class="lineNone">000684| let extract_int64_ee_unsigned = function</div>
712 <div class="lineAllUnvisited">000685| | BigEndian -> (*[0]*)extract_int64_be_unsigned</div>
713 <div class="lineAllUnvisited">000686| | LittleEndian -> (*[0]*)extract_int64_le_unsigned</div>
714 <div class="lineAllUnvisited">000687| | NativeEndian -> (*[0]*)extract_int64_ne_unsigned</div>
715 <div class="lineNone">000688| </div>
716 <div class="lineNone">000689| external extract_fastpath_int16_be_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_be_unsigned" "noalloc"</div>
717 <div class="lineNone">000690| </div>
718 <div class="lineNone">000691| external extract_fastpath_int16_le_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_le_unsigned" "noalloc"</div>
719 <div class="lineNone">000692| </div>
720 <div class="lineNone">000693| external extract_fastpath_int16_ne_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_ne_unsigned" "noalloc"</div>
721 <div class="lineNone">000694| </div>
722 <div class="lineNone">000695| external extract_fastpath_int16_be_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_be_signed" "noalloc"</div>
723 <div class="lineNone">000696| </div>
724 <div class="lineNone">000697| external extract_fastpath_int16_le_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_le_signed" "noalloc"</div>
725 <div class="lineNone">000698| </div>
726 <div class="lineNone">000699| external extract_fastpath_int16_ne_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int16_ne_signed" "noalloc"</div>
727 <div class="lineNone">000700| </div>
728 <div class="lineNone">000701| (*</div>
729 <div class="lineNone">000702| external extract_fastpath_int24_be_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_be_unsigned" "noalloc"</div>
730 <div class="lineNone">000703| </div>
731 <div class="lineNone">000704| external extract_fastpath_int24_le_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_le_unsigned" "noalloc"</div>
732 <div class="lineNone">000705| </div>
733 <div class="lineNone">000706| external extract_fastpath_int24_ne_unsigned : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_ne_unsigned" "noalloc"</div>
734 <div class="lineNone">000707| </div>
735 <div class="lineNone">000708| external extract_fastpath_int24_be_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_be_signed" "noalloc"</div>
736 <div class="lineNone">000709| </div>
737 <div class="lineNone">000710| external extract_fastpath_int24_le_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_le_signed" "noalloc"</div>
738 <div class="lineNone">000711| </div>
739 <div class="lineNone">000712| external extract_fastpath_int24_ne_signed : string -> int -> int = "ocaml_bitstring_extract_fastpath_int24_ne_signed" "noalloc"</div>
740 <div class="lineNone">000713| *)</div>
741 <div class="lineNone">000714| </div>
742 <div class="lineNone">000715| external extract_fastpath_int32_be_unsigned : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_be_unsigned" "noalloc"</div>
743 <div class="lineNone">000716| </div>
744 <div class="lineNone">000717| external extract_fastpath_int32_le_unsigned : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_le_unsigned" "noalloc"</div>
745 <div class="lineNone">000718| </div>
746 <div class="lineNone">000719| external extract_fastpath_int32_ne_unsigned : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_ne_unsigned" "noalloc"</div>
747 <div class="lineNone">000720| </div>
748 <div class="lineNone">000721| external extract_fastpath_int32_be_signed : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_be_signed" "noalloc"</div>
749 <div class="lineNone">000722| </div>
750 <div class="lineNone">000723| external extract_fastpath_int32_le_signed : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_le_signed" "noalloc"</div>
751 <div class="lineNone">000724| </div>
752 <div class="lineNone">000725| external extract_fastpath_int32_ne_signed : string -> int -> int32 -> int32 = "ocaml_bitstring_extract_fastpath_int32_ne_signed" "noalloc"</div>
753 <div class="lineNone">000726| </div>
754 <div class="lineNone">000727| (*</div>
755 <div class="lineNone">000728| external extract_fastpath_int40_be_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_be_unsigned" "noalloc"</div>
756 <div class="lineNone">000729| </div>
757 <div class="lineNone">000730| external extract_fastpath_int40_le_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_le_unsigned" "noalloc"</div>
758 <div class="lineNone">000731| </div>
759 <div class="lineNone">000732| external extract_fastpath_int40_ne_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_ne_unsigned" "noalloc"</div>
760 <div class="lineNone">000733| </div>
761 <div class="lineNone">000734| external extract_fastpath_int40_be_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_be_signed" "noalloc"</div>
762 <div class="lineNone">000735| </div>
763 <div class="lineNone">000736| external extract_fastpath_int40_le_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_le_signed" "noalloc"</div>
764 <div class="lineNone">000737| </div>
765 <div class="lineNone">000738| external extract_fastpath_int40_ne_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int40_ne_signed" "noalloc"</div>
766 <div class="lineNone">000739| </div>
767 <div class="lineNone">000740| external extract_fastpath_int48_be_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_be_unsigned" "noalloc"</div>
768 <div class="lineNone">000741| </div>
769 <div class="lineNone">000742| external extract_fastpath_int48_le_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_le_unsigned" "noalloc"</div>
770 <div class="lineNone">000743| </div>
771 <div class="lineNone">000744| external extract_fastpath_int48_ne_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_ne_unsigned" "noalloc"</div>
772 <div class="lineNone">000745| </div>
773 <div class="lineNone">000746| external extract_fastpath_int48_be_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_be_signed" "noalloc"</div>
774 <div class="lineNone">000747| </div>
775 <div class="lineNone">000748| external extract_fastpath_int48_le_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_le_signed" "noalloc"</div>
776 <div class="lineNone">000749| </div>
777 <div class="lineNone">000750| external extract_fastpath_int48_ne_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int48_ne_signed" "noalloc"</div>
778 <div class="lineNone">000751| </div>
779 <div class="lineNone">000752| external extract_fastpath_int56_be_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_be_unsigned" "noalloc"</div>
780 <div class="lineNone">000753| </div>
781 <div class="lineNone">000754| external extract_fastpath_int56_le_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_le_unsigned" "noalloc"</div>
782 <div class="lineNone">000755| </div>
783 <div class="lineNone">000756| external extract_fastpath_int56_ne_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_ne_unsigned" "noalloc"</div>
784 <div class="lineNone">000757| </div>
785 <div class="lineNone">000758| external extract_fastpath_int56_be_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_be_signed" "noalloc"</div>
786 <div class="lineNone">000759| </div>
787 <div class="lineNone">000760| external extract_fastpath_int56_le_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_le_signed" "noalloc"</div>
788 <div class="lineNone">000761| </div>
789 <div class="lineNone">000762| external extract_fastpath_int56_ne_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int56_ne_signed" "noalloc"</div>
790 <div class="lineNone">000763| *)</div>
791 <div class="lineNone">000764| </div>
792 <div class="lineNone">000765| external extract_fastpath_int64_be_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_be_unsigned" "noalloc"</div>
793 <div class="lineNone">000766| </div>
794 <div class="lineNone">000767| external extract_fastpath_int64_le_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_le_unsigned" "noalloc"</div>
795 <div class="lineNone">000768| </div>
796 <div class="lineNone">000769| external extract_fastpath_int64_ne_unsigned : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_ne_unsigned" "noalloc"</div>
797 <div class="lineNone">000770| </div>
798 <div class="lineNone">000771| external extract_fastpath_int64_be_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_be_signed" "noalloc"</div>
799 <div class="lineNone">000772| </div>
800 <div class="lineNone">000773| external extract_fastpath_int64_le_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_le_signed" "noalloc"</div>
801 <div class="lineNone">000774| </div>
802 <div class="lineNone">000775| external extract_fastpath_int64_ne_signed : string -> int -> int64 -> int64 = "ocaml_bitstring_extract_fastpath_int64_ne_signed" "noalloc"</div>
803 <div class="lineNone">000776| </div>
804 <div class="lineNone">000777| (*----------------------------------------------------------------------*)</div>
805 <div class="lineNone">000778| (* Constructor functions. *)</div>
806 <div class="lineNone">000779| </div>
807 <div class="lineNone">000780| module Buffer = struct</div>
808 <div class="lineNone">000781| type t = {</div>
809 <div class="lineNone">000782| buf : Buffer.t;</div>
810 <div class="lineNone">000783| mutable len : int; (* Length in bits. *)</div>
811 <div class="lineNone">000784| (* Last byte in the buffer (if len is not aligned). We store</div>
812 <div class="lineNone">000785| * it outside the buffer because buffers aren't mutable.</div>
813 <div class="lineNone">000786| *)</div>
814 <div class="lineNone">000787| mutable last : int;</div>
815 <div class="lineNone">000788| }</div>
816 <div class="lineNone">000789| </div>
817 <div class="lineNone">000790| let create () =</div>
818 <div class="lineNone">000791| (* XXX We have almost enough information in the generator to</div>
819 <div class="lineNone">000792| * choose a good initial size.</div>
820 <div class="lineNone">000793| *)</div>
821 <div class="lineAllVisited">000794| (*[493152]*){ buf = Buffer.create 128; len = 0; last = 0 }</div>
822 <div class="lineNone">000795| </div>
823 <div class="lineNone">000796| let contents { buf = buf; len = len; last = last } =</div>
824 <div class="lineAllVisited">000797| (*[493152]*)let data =</div>
825 <div class="lineNone">000798| if len land 7 = 0 then</div>
826 <div class="lineAllVisited">000799| (*[63280]*)Buffer.contents buf</div>
827 <div class="lineNone">000800| else</div>
828 <div class="lineAllVisited">000801| (*[429872]*)Buffer.contents buf ^ (String.make 1 (Char.chr last)) in</div>
829 <div class="lineAllVisited">000802| (*[493152]*)data, 0, len</div>
830 <div class="lineNone">000803| </div>
831 <div class="lineNone">000804| (* Add exactly 8 bits. *)</div>
832 <div class="lineNone">000805| let add_byte ({ buf = buf; len = len; last = last } as t) byte =</div>
833 <div class="lineMixed">000806| (*[8266092]*)if (*[8266092]*)byte < 0 || (*[8266092]*)byte > 255 then (*[0]*)invalid_arg "Bitstring.Buffer.add_byte";</div>
834 <div class="lineAllVisited">000807| (*[8266092]*)let shift = len land 7 in</div>
835 <div class="lineAllVisited">000808| (*[8266092]*)if shift = 0 then</div>
836 <div class="lineNone">000809| (* Target buffer is byte-aligned. *)</div>
837 <div class="lineAllVisited">000810| (*[521241]*)Buffer.add_char buf (Char.chr byte)</div>
838 <div class="lineNone">000811| else (</div>
839 <div class="lineNone">000812| (* Target buffer is unaligned. 'last' is meaningful. *)</div>
840 <div class="lineAllVisited">000813| (*[7744851]*)let first = byte lsr shift in</div>
841 <div class="lineAllVisited">000814| (*[7744851]*)let second = (byte lsl (8 - shift)) land 0xff in</div>
842 <div class="lineAllVisited">000815| (*[7744851]*)Buffer.add_char buf (*[7744851]*)(Char.chr (last lor first));</div>
843 <div class="lineAllVisited">000816| (*[7744851]*)t.last <- second</div>
844 <div class="lineNone">000817| );</div>
845 <div class="lineAllVisited">000818| (*[8266092]*)t.len <- t.len + 8</div>
846 <div class="lineNone">000819| </div>
847 <div class="lineNone">000820| (* Add exactly 1 bit. *)</div>
848 <div class="lineNone">000821| let add_bit ({ buf = buf; len = len; last = last } as t) bit =</div>
849 <div class="lineAllVisited">000822| (*[4426193]*)let shift = 7 - (len land 7) in</div>
850 <div class="lineAllVisited">000823| (*[4426193]*)if shift > 0 then</div>
851 <div class="lineNone">000824| (* Somewhere in the middle of 'last'. *)</div>
852 <div class="lineAllVisited">000825| (*[3893270]*)t.last <- last lor ((if bit then (*[3004643]*)1 else (*[888627]*)0) lsl shift)</div>
853 <div class="lineNone">000826| else (</div>
854 <div class="lineNone">000827| (* Just a single spare bit in 'last'. *)</div>
855 <div class="lineAllVisited">000828| (*[532923]*)let last = last lor if bit then (*[407944]*)1 else (*[124979]*)0 in</div>
856 <div class="lineAllVisited">000829| (*[532923]*)Buffer.add_char buf (*[532923]*)(Char.chr last);</div>
857 <div class="lineAllVisited">000830| (*[532923]*)t.last <- 0</div>
858 <div class="lineNone">000831| );</div>
859 <div class="lineAllVisited">000832| (*[4426193]*)t.len <- len + 1</div>
860 <div class="lineNone">000833| </div>
861 <div class="lineNone">000834| (* Add a small number of bits (definitely < 8). This uses a loop</div>
862 <div class="lineNone">000835| * to call add_bit so it's slow.</div>
863 <div class="lineNone">000836| *)</div>
864 <div class="lineNone">000837| let _add_bits t c slen =</div>
865 <div class="lineMixed">000838| (*[318370]*)if (*[318370]*)slen < 1 || (*[318370]*)slen >= 8 then (*[0]*)invalid_arg "Bitstring.Buffer._add_bits";</div>
866 <div class="lineAllVisited">000839| (*[318370]*)for i = slen-1 downto 0 do</div>
867 <div class="lineAllVisited">000840| (*[1273808]*)let bit = c land (1 lsl i) <> 0 in</div>
868 <div class="lineAllVisited">000841| (*[1273808]*)add_bit t bit</div>
869 <div class="lineNone">000842| done</div>
870 <div class="lineNone">000843| </div>
871 <div class="lineNone">000844| let add_bits ({ buf = buf; len = len } as t) str slen =</div>
872 <div class="lineAllVisited">000845| (*[26867]*)if slen > 0 then (</div>
873 <div class="lineAllVisited">000846| (*[1389114]*)if len land 7 = 0 then (</div>
874 <div class="lineAllVisited">000847| (*[575784]*)if slen land 7 = 0 then</div>
875 <div class="lineNone">000848| (* Common case - everything is byte-aligned. *)</div>
876 <div class="lineAllVisited">000849| (*[64322]*)Buffer.add_substring buf str 0 (slen lsr 3)</div>
877 <div class="lineNone">000850| else (</div>
878 <div class="lineNone">000851| (* Target buffer is aligned. Copy whole bytes then leave the</div>
879 <div class="lineNone">000852| * remaining bits in last.</div>
880 <div class="lineNone">000853| *)</div>
881 <div class="lineAllVisited">000854| (*[511462]*)let slenbytes = slen lsr 3 in</div>
882 <div class="lineAllVisited">000855| (*[345655]*)if slenbytes > 0 then (*[165807]*)Buffer.add_substring buf str 0 slenbytes;</div>
883 <div class="lineAllVisited">000856| (*[511462]*)let last = Char.code str.[slenbytes] in (* last char *)</div>
884 <div class="lineAllVisited">000857| (*[511462]*)let mask = 0xff lsl (8 - (slen land 7)) in</div>
885 <div class="lineAllVisited">000858| (*[511462]*)t.last <- last land mask</div>
886 <div class="lineNone">000859| );</div>
887 <div class="lineAllVisited">000860| (*[575784]*)t.len <- len + slen</div>
888 <div class="lineNone">000861| ) else (</div>
889 <div class="lineNone">000862| (* Target buffer is unaligned. Copy whole bytes using</div>
890 <div class="lineNone">000863| * add_byte which knows how to deal with an unaligned</div>
891 <div class="lineNone">000864| * target buffer, then call add_bit for the remaining < 8 bits.</div>
892 <div class="lineNone">000865| *</div>
893 <div class="lineNone">000866| * XXX This is going to be dog-slow.</div>
894 <div class="lineNone">000867| *)</div>
895 <div class="lineAllVisited">000868| (*[813330]*)let slenbytes = slen lsr 3 in</div>
896 <div class="lineAllVisited">000869| (*[813330]*)for i = 0 to slenbytes-1 do</div>
897 <div class="lineAllVisited">000870| (*[5943116]*)let byte = Char.code str.[i] in</div>
898 <div class="lineAllVisited">000871| (*[5943116]*)add_byte t byte</div>
899 <div class="lineNone">000872| done;</div>
900 <div class="lineAllVisited">000873| (*[813330]*)let bitsleft = slen - (slenbytes lsl 3) in</div>
901 <div class="lineAllVisited">000874| (*[144583]*)if bitsleft > 0 then (</div>
902 <div class="lineAllVisited">000875| (*[668747]*)let c = Char.code str.[slenbytes] in</div>
903 <div class="lineAllVisited">000876| (*[668747]*)for i = 0 to bitsleft - 1 do</div>
904 <div class="lineAllVisited">000877| (*[2652755]*)let bit = c land (0x80 lsr i) <> 0 in</div>
905 <div class="lineAllVisited">000878| (*[2652755]*)add_bit t bit</div>
906 <div class="lineNone">000879| done</div>
907 <div class="lineNone">000880| )</div>
908 <div class="lineNone">000881| );</div>
909 <div class="lineNone">000882| )</div>
910 <div class="lineNone">000883| end</div>
911 <div class="lineNone">000884| </div>
912 <div class="lineNone">000885| (* Construct a single bit. *)</div>
913 <div class="lineNone">000886| let construct_bit buf b _ _ =</div>
914 <div class="lineAllVisited">000887| (*[130]*)Buffer.add_bit buf b</div>
915 <div class="lineNone">000888| </div>
916 <div class="lineNone">000889| (* Construct a field, flen = [2..8]. *)</div>
917 <div class="lineNone">000890| let construct_char_unsigned buf v flen exn =</div>
918 <div class="lineAllVisited">000891| (*[1204740]*)let max_val = 1 lsl flen in</div>
919 <div class="lineMixed">000892| (*[1204740]*)if (*[1204740]*)v < 0 || (*[1204740]*)v >= max_val then (*[0]*)raise exn;</div>
920 <div class="lineAllVisited">000893| (*[1204740]*)if flen = 8 then</div>
921 <div class="lineAllVisited">000894| (*[1203960]*)Buffer.add_byte buf v</div>
922 <div class="lineNone">000895| else</div>
923 <div class="lineAllVisited">000896| (*[780]*)Buffer._add_bits buf v flen</div>
924 <div class="lineNone">000897| </div>
925 <div class="lineNone">000898| (* Construct a field of up to 31 bits. *)</div>
926 <div class="lineNone">000899| let construct_int_be_unsigned buf v flen exn =</div>
927 <div class="lineNone">000900| (* Check value is within range. *)</div>
928 <div class="lineMixed">000901| (*[392]*)if not (I.range_unsigned v flen) then (*[0]*)raise exn;</div>
929 <div class="lineNone">000902| (* Add the bytes. *)</div>
930 <div class="lineAllVisited">000903| (*[392]*)I.map_bytes_be (Buffer._add_bits buf) (Buffer.add_byte buf) v flen</div>
931 <div class="lineNone">000904| </div>
932 <div class="lineNone">000905| (* Construct a field of up to 31 bits. *)</div>
933 <div class="lineNone">000906| let construct_int_le_unsigned buf v flen exn =</div>
934 <div class="lineNone">000907| (* Check value is within range. *)</div>
935 <div class="lineMixed">000908| (*[780]*)if not (I.range_unsigned v flen) then (*[0]*)raise exn;</div>
936 <div class="lineNone">000909| (* Add the bytes. *)</div>
937 <div class="lineAllVisited">000910| (*[780]*)I.map_bytes_le (Buffer._add_bits buf) (Buffer.add_byte buf) v flen</div>
938 <div class="lineNone">000911| </div>
939 <div class="lineNone">000912| let construct_int_ne_unsigned =</div>
940 <div class="lineAllVisited">000913| (*[43]*)if nativeendian = BigEndian</div>
941 <div class="lineAllUnvisited">000914| then (*[0]*)construct_int_be_unsigned</div>
942 <div class="lineAllVisited">000915| else (*[43]*)construct_int_le_unsigned</div>
943 <div class="lineNone">000916| </div>
944 <div class="lineNone">000917| let construct_int_ee_unsigned = function</div>
945 <div class="lineAllUnvisited">000918| | BigEndian -> (*[0]*)construct_int_be_unsigned</div>
946 <div class="lineAllUnvisited">000919| | LittleEndian -> (*[0]*)construct_int_le_unsigned</div>
947 <div class="lineAllUnvisited">000920| | NativeEndian -> (*[0]*)construct_int_ne_unsigned</div>
948 <div class="lineNone">000921| </div>
949 <div class="lineNone">000922| (* Construct a field of exactly 32 bits. *)</div>
950 <div class="lineNone">000923| let construct_int32_be_unsigned buf v flen _ =</div>
951 <div class="lineAllVisited">000924| (*[136]*)Buffer.add_byte buf</div>
952 <div class="lineNone">000925| (Int32.to_int (Int32.shift_right_logical v 24));</div>
953 <div class="lineAllVisited">000926| (*[136]*)Buffer.add_byte buf</div>
954 <div class="lineNone">000927| (Int32.to_int ((Int32.logand (Int32.shift_right_logical v 16) 0xff_l)));</div>
955 <div class="lineAllVisited">000928| (*[136]*)Buffer.add_byte buf</div>
956 <div class="lineAllVisited">000929| (*[136]*)(Int32.to_int ((Int32.logand (Int32.shift_right_logical v 8) 0xff_l)));</div>
957 <div class="lineAllVisited">000930| (*[136]*)Buffer.add_byte buf</div>
958 <div class="lineNone">000931| (Int32.to_int (Int32.logand v 0xff_l))</div>
959 <div class="lineNone">000932| </div>
960 <div class="lineNone">000933| let construct_int32_le_unsigned buf v flen _ =</div>
961 <div class="lineAllVisited">000934| (*[272]*)Buffer.add_byte buf</div>
962 <div class="lineNone">000935| (Int32.to_int (Int32.logand v 0xff_l));</div>
963 <div class="lineAllVisited">000936| (*[272]*)Buffer.add_byte buf</div>
964 <div class="lineNone">000937| (Int32.to_int ((Int32.logand (Int32.shift_right_logical v 8) 0xff_l)));</div>
965 <div class="lineAllVisited">000938| (*[272]*)Buffer.add_byte buf</div>
966 <div class="lineAllVisited">000939| (*[272]*)(Int32.to_int ((Int32.logand (Int32.shift_right_logical v 16) 0xff_l)));</div>
967 <div class="lineAllVisited">000940| (*[272]*)Buffer.add_byte buf</div>
968 <div class="lineNone">000941| (Int32.to_int (Int32.shift_right_logical v 24))</div>
969 <div class="lineNone">000942| </div>
970 <div class="lineNone">000943| let construct_int32_ne_unsigned =</div>
971 <div class="lineAllVisited">000944| (*[43]*)if nativeendian = BigEndian</div>
972 <div class="lineAllUnvisited">000945| then (*[0]*)construct_int32_be_unsigned</div>
973 <div class="lineAllVisited">000946| else (*[43]*)construct_int32_le_unsigned</div>
974 <div class="lineNone">000947| </div>
975 <div class="lineNone">000948| let construct_int32_ee_unsigned = function</div>
976 <div class="lineAllVisited">000949| | BigEndian -> (*[6]*)construct_int32_be_unsigned</div>
977 <div class="lineAllVisited">000950| | LittleEndian -> (*[6]*)construct_int32_le_unsigned</div>
978 <div class="lineAllVisited">000951| | NativeEndian -> (*[6]*)construct_int32_ne_unsigned</div>
979 <div class="lineNone">000952| </div>
980 <div class="lineNone">000953| (* Construct a field of up to 64 bits. *)</div>
981 <div class="lineNone">000954| let construct_int64_be_unsigned buf v flen exn =</div>
982 <div class="lineNone">000955| (* Check value is within range. *)</div>
983 <div class="lineMixed">000956| (*[352110]*)if not (I64.range_unsigned v flen) then (*[0]*)raise exn;</div>
984 <div class="lineNone">000957| (* Add the bytes. *)</div>
985 <div class="lineAllVisited">000958| (*[352110]*)I64.map_bytes_be (Buffer._add_bits buf) (Buffer.add_byte buf) v flen</div>
986 <div class="lineNone">000959| </div>
987 <div class="lineNone">000960| (* Construct a field of up to 64 bits. *)</div>
988 <div class="lineNone">000961| let construct_int64_le_unsigned buf v flen exn =</div>
989 <div class="lineNone">000962| (* Check value is within range. *)</div>
990 <div class="lineMixed">000963| (*[520]*)if not (I64.range_unsigned v flen) then (*[0]*)raise exn;</div>
991 <div class="lineNone">000964| (* Add the bytes. *)</div>
992 <div class="lineAllVisited">000965| (*[520]*)I64.map_bytes_le (Buffer._add_bits buf) (Buffer.add_byte buf) v flen</div>
993 <div class="lineNone">000966| </div>
994 <div class="lineNone">000967| let construct_int64_ne_unsigned =</div>
995 <div class="lineAllVisited">000968| (*[43]*)if nativeendian = BigEndian</div>
996 <div class="lineAllUnvisited">000969| then (*[0]*)construct_int64_be_unsigned</div>
997 <div class="lineAllVisited">000970| else (*[43]*)construct_int64_le_unsigned</div>
998 <div class="lineNone">000971| </div>
999 <div class="lineNone">000972| let construct_int64_ee_unsigned = function</div>
1000 <div class="lineAllUnvisited">000973| | BigEndian -> (*[0]*)construct_int64_be_unsigned</div>
1001 <div class="lineAllUnvisited">000974| | LittleEndian -> (*[0]*)construct_int64_le_unsigned</div>
1002 <div class="lineAllUnvisited">000975| | NativeEndian -> (*[0]*)construct_int64_ne_unsigned</div>
1003 <div class="lineNone">000976| </div>
1004 <div class="lineNone">000977| (* Construct from a string of bytes, exact multiple of 8 bits</div>
1005 <div class="lineNone">000978| * in length of course.</div>
1006 <div class="lineNone">000979| *)</div>
1007 <div class="lineNone">000980| let construct_string buf str =</div>
1008 <div class="lineAllVisited">000981| (*[89505]*)let len = String.length str in</div>
1009 <div class="lineAllVisited">000982| (*[89505]*)Buffer.add_bits buf str (len lsl 3)</div>
1010 <div class="lineNone">000983| </div>
1011 <div class="lineNone">000984| (* Construct from a bitstring. *)</div>
1012 <div class="lineNone">000985| let construct_bitstring buf (data, off, len) =</div>
1013 <div class="lineNone">000986| (* Add individual bits until we get to the next byte boundary of</div>
1014 <div class="lineNone">000987| * the underlying string.</div>
1015 <div class="lineNone">000988| *)</div>
1016 <div class="lineAllVisited">000989| (*[1317896]*)let blen = 7 - ((off + 7) land 7) in</div>
1017 <div class="lineAllVisited">000990| (*[1317896]*)let blen = min blen len in</div>
1018 <div class="lineAllVisited">000991| (*[1317896]*)let rec loop off len blen =</div>
1019 <div class="lineAllVisited">000992| (*[1317896]*)if blen = 0 then ((*[1317896]*)off, len)</div>
1020 <div class="lineNone">000993| else (</div>
1021 <div class="lineAllUnvisited">000994| (*[0]*)let b = extract_bit data off len 1</div>
1022 <div class="lineNone">000995| and off = off + 1 and len = len + 1 in</div>
1023 <div class="lineAllUnvisited">000996| (*[0]*)Buffer.add_bit buf (*[0]*)b;</div>
1024 <div class="lineAllUnvisited">000997| (*[0]*)loop off len (blen-1)</div>
1025 <div class="lineNone">000998| )</div>
1026 <div class="lineNone">000999| in</div>
1027 <div class="lineAllVisited">001000| (*[1317896]*)let off, len = loop off len blen in</div>
1028 <div class="lineAllVisited">001001| (*[1317896]*)assert ((*[1317896]*)len = 0 || (off (*[1291094]*)land 7) = 0);</div>
1029 <div class="lineNone">001002| </div>
1030 <div class="lineNone">001003| (* Add the remaining 'len' bits. *)</div>
1031 <div class="lineAllVisited">001004| (*[1317896]*)let data =</div>
1032 <div class="lineNone">001005| let off = off lsr 3 in</div>
1033 <div class="lineNone">001006| (* XXX dangerous allocation *)</div>
1034 <div class="lineAllVisited">001007| (*[1317896]*)if off = 0 then (*[1317896]*)data</div>
1035 <div class="lineAllUnvisited">001008| else (*[0]*)String.sub data off (String.length data - off) in</div>
1036 <div class="lineNone">001009| </div>
1037 <div class="lineAllVisited">001010| (*[1317896]*)Buffer.add_bits buf data len</div>
1038 <div class="lineNone">001011| </div>
1039 <div class="lineNone">001012| (* Concatenate bitstrings. *)</div>
1040 <div class="lineNone">001013| let concat bs =</div>
1041 <div class="lineAllVisited">001014| (*[40461]*)let buf = Buffer.create () in</div>
1042 <div class="lineAllVisited">001015| (*[40461]*)List.iter (construct_bitstring buf) (*[40461]*)bs;</div>
1043 <div class="lineAllVisited">001016| (*[40461]*)Buffer.contents buf</div>
1044 <div class="lineNone">001017| </div>
1045 <div class="lineNone">001018| (*----------------------------------------------------------------------*)</div>
1046 <div class="lineNone">001019| (* Extract a string from a bitstring. *)</div>
1047 <div class="lineNone">001020| let string_of_bitstring (data, off, len) =</div>
1048 <div class="lineAllVisited">001021| (*[73011]*)if off (*[73011]*)land 7 = 0 && len (*[16597]*)land 7 = 0 then</div>
1049 <div class="lineNone">001022| (* Easy case: everything is byte-aligned. *)</div>
1050 <div class="lineAllVisited">001023| (*[9037]*)String.sub data (off lsr 3) (len lsr 3)</div>
1051 <div class="lineNone">001024| else (</div>
1052 <div class="lineNone">001025| (* Bit-twiddling case. *)</div>
1053 <div class="lineAllVisited">001026| (*[63974]*)let strlen = (len + 7) lsr 3 in</div>
1054 <div class="lineAllVisited">001027| (*[63974]*)let str = String.make strlen '\000' in</div>
1055 <div class="lineAllVisited">001028| (*[63974]*)let rec loop data off len i =</div>
1056 <div class="lineAllVisited">001029| (*[326148]*)if len >= 8 then (</div>
1057 <div class="lineAllVisited">001030| (*[262174]*)let c = extract_char_unsigned data off len 8</div>
1058 <div class="lineNone">001031| and off = off + 8 and len = len - 8 in</div>
1059 <div class="lineAllVisited">001032| (*[262174]*)str.[i] (*[262174]*)<- Char.chr c;</div>
1060 <div class="lineAllVisited">001033| (*[262174]*)loop data off len (i+1)</div>
1061 <div class="lineAllVisited">001034| ) else (*[52324]*)if len > 0 then (</div>
1062 <div class="lineAllVisited">001035| (*[11650]*)let c = extract_char_unsigned data off len len in</div>
1063 <div class="lineAllVisited">001036| (*[11650]*)str.[i] <- Char.chr (c lsl (8-len))</div>
1064 <div class="lineNone">001037| )</div>
1065 <div class="lineNone">001038| in</div>
1066 <div class="lineAllVisited">001039| (*[63974]*)loop data off len (*[63974]*)0;</div>
1067 <div class="lineAllVisited">001040| (*[63974]*)str</div>
1068 <div class="lineNone">001041| )</div>
1069 <div class="lineNone">001042| </div>
1070 <div class="lineNone">001043| (* To channel. *)</div>
1071 <div class="lineNone">001044| </div>
1072 <div class="lineNone">001045| let bitstring_to_chan ((data, off, len) as bits) chan =</div>
1073 <div class="lineNone">001046| (* Fail if the bitstring length isn't a multiple of 8. *)</div>
1074 <div class="lineMixed">001047| (*[1]*)if len land 7 <> 0 then (*[0]*)invalid_arg "bitstring_to_chan";</div>
1075 <div class="lineNone">001048| </div>
1076 <div class="lineAllVisited">001049| (*[1]*)if off land 7 = 0 then</div>
1077 <div class="lineNone">001050| (* Easy case: string is byte-aligned. *)</div>
1078 <div class="lineAllVisited">001051| (*[1]*)output chan data (off lsr 3) (len lsr 3)</div>
1079 <div class="lineNone">001052| else (</div>
1080 <div class="lineNone">001053| (* Bit-twiddling case: reuse string_of_bitstring *)</div>
1081 <div class="lineAllUnvisited">001054| (*[0]*)let str = string_of_bitstring bits in</div>
1082 <div class="lineAllUnvisited">001055| (*[0]*)output_string chan str</div>
1083 <div class="lineNone">001056| )</div>
1084 <div class="lineNone">001057| </div>
1085 <div class="lineNone">001058| let bitstring_to_file bits filename =</div>
1086 <div class="lineAllUnvisited">001059| (*[0]*)let chan = open_out_bin filename in</div>
1087 <div class="lineAllUnvisited">001060| (*[0]*)try</div>
1088 <div class="lineAllUnvisited">001061| (*[0]*)bitstring_to_chan bits chan;</div>
1089 <div class="lineAllUnvisited">001062| (*[0]*)close_out chan</div>
1090 <div class="lineNone">001063| with exn -></div>
1091 <div class="lineAllUnvisited">001064| (*[0]*)close_out (*[0]*)chan;</div>
1092 <div class="lineAllUnvisited">001065| (*[0]*)raise exn</div>
1093 <div class="lineNone">001066| </div>
1094 <div class="lineNone">001067| (*----------------------------------------------------------------------*)</div>
1095 <div class="lineNone">001068| (* Comparison. *)</div>
1096 <div class="lineNone">001069| let compare ((data1, off1, len1) as bs1) ((data2, off2, len2) as bs2) =</div>
1097 <div class="lineNone">001070| (* In the fully-aligned case, this is reduced to string comparison ... *)</div>
1098 <div class="lineAllVisited">001071| (*[4624]*)if off1 (*[4624]*)land 7 = 0 && len1 (*[4624]*)land 7 (*[4624]*)= 0 && off2 (*[680]*)land 7 (*[680]*)= 0 && len2 (*[535]*)land 7 = 0</div>
1099 <div class="lineNone">001072| then (</div>
1100 <div class="lineNone">001073| (* ... but we have to do that by hand because the bits may</div>
1101 <div class="lineNone">001074| * not extend to the full length of the underlying string.</div>
1102 <div class="lineNone">001075| *)</div>
1103 <div class="lineAllVisited">001076| (*[100]*)let off1 = off1 lsr 3 and off2 = off2 lsr 3</div>
1104 <div class="lineNone">001077| and len1 = len1 lsr 3 and len2 = len2 lsr 3 in</div>
1105 <div class="lineAllVisited">001078| (*[100]*)let rec loop i =</div>
1106 <div class="lineAllVisited">001079| (*[240]*)if (*[240]*)i < len1 && (*[170]*)i < len2 then (</div>
1107 <div class="lineAllVisited">001080| (*[140]*)let c1 = String.unsafe_get data1 (off1 + i)</div>
1108 <div class="lineNone">001081| and c2 = String.unsafe_get data2 (off2 + i) in</div>
1109 <div class="lineAllVisited">001082| (*[140]*)let r = compare c1 c2 in</div>
1110 <div class="lineMixed">001083| (*[140]*)if r <> 0 then (*[0]*)r</div>
1111 <div class="lineAllVisited">001084| else (*[140]*)loop (i+1)</div>
1112 <div class="lineNone">001085| )</div>
1113 <div class="lineAllVisited">001086| else (*[100]*)len1 - len2</div>
1114 <div class="lineNone">001087| in</div>
1115 <div class="lineAllVisited">001088| (*[100]*)loop 0</div>
1116 <div class="lineNone">001089| )</div>
1117 <div class="lineNone">001090| else (</div>
1118 <div class="lineNone">001091| (* Slow/unaligned. *)</div>
1119 <div class="lineAllVisited">001092| (*[4524]*)let str1 = string_of_bitstring bs1</div>
1120 <div class="lineNone">001093| and str2 = string_of_bitstring bs2 in</div>
1121 <div class="lineAllVisited">001094| (*[4524]*)let r = String.compare str1 str2 in</div>
1122 <div class="lineAllVisited">001095| (*[4524]*)if r <> 0 then (*[3058]*)r else (*[1466]*)len1 - len2</div>
1123 <div class="lineNone">001096| )</div>
1124 <div class="lineNone">001097| </div>
1125 <div class="lineNone">001098| let equals ((_, _, len1) as bs1) ((_, _, len2) as bs2) =</div>
1126 <div class="lineMixed">001099| (*[7]*)if len1 <> len2 then (*[0]*)false</div>
1127 <div class="lineAllVisited">001100| else (*[7]*)if bs1 = bs2 then (*[7]*)true</div>
1128 <div class="lineAllUnvisited">001101| else (*[0]*)0 = compare bs1 bs2</div>
1129 <div class="lineNone">001102| </div>
1130 <div class="lineNone">001103| (*----------------------------------------------------------------------*)</div>
1131 <div class="lineNone">001104| (* Bit get/set functions. *)</div>
1132 <div class="lineNone">001105| </div>
1133 <div class="lineAllUnvisited">001106| let index_out_of_bounds () = (*[0]*)invalid_arg "index out of bounds"</div>
1134 <div class="lineNone">001107| </div>
1135 <div class="lineNone">001108| let put (data, off, len) n v =</div>
1136 <div class="lineAllUnvisited">001109| (*[0]*)if (*[0]*)n < 0 || (*[0]*)off+n >= len then (*[0]*)index_out_of_bounds ()</div>
1137 <div class="lineNone">001110| else (</div>
1138 <div class="lineAllUnvisited">001111| (*[0]*)let i = off+n in</div>
1139 <div class="lineAllUnvisited">001112| (*[0]*)let si = i lsr 3 and mask = 0x80 lsr (i land 7) in</div>
1140 <div class="lineAllUnvisited">001113| (*[0]*)let c = Char.code data.[si] in</div>
1141 <div class="lineAllUnvisited">001114| (*[0]*)let c = if v <> 0 then c (*[0]*)lor mask else c (*[0]*)land (lnot mask) in</div>
1142 <div class="lineAllUnvisited">001115| (*[0]*)data.[si] <- Char.unsafe_chr c</div>
1143 <div class="lineNone">001116| )</div>
1144 <div class="lineNone">001117| </div>
1145 <div class="lineAllUnvisited">001118| let set bits n = (*[0]*)put bits n 1</div>
1146 <div class="lineNone">001119| </div>
1147 <div class="lineAllUnvisited">001120| let clear bits n = (*[0]*)put bits n 0</div>
1148 <div class="lineNone">001121| </div>
1149 <div class="lineNone">001122| let get (data, off, len) n =</div>
1150 <div class="lineMixed">001123| (*[1945548]*)if (*[1945548]*)n < 0 || (*[1945548]*)off+n >= len then (*[0]*)index_out_of_bounds ()</div>
1151 <div class="lineNone">001124| else (</div>
1152 <div class="lineAllVisited">001125| (*[1945548]*)let i = off+n in</div>
1153 <div class="lineAllVisited">001126| (*[1945548]*)let si = i lsr 3 and mask = 0x80 lsr (i land 7) in</div>
1154 <div class="lineAllVisited">001127| (*[1945548]*)let c = Char.code data.[si] in</div>
1155 <div class="lineAllVisited">001128| c (*[1945548]*)land mask</div>
1156 <div class="lineNone">001129| )</div>
1157 <div class="lineNone">001130| </div>
1158 <div class="lineAllVisited">001131| let is_set bits n = (*[1297032]*)get bits n <> 0</div>
1159 <div class="lineNone">001132| </div>
1160 <div class="lineAllVisited">001133| let is_clear bits n = (*[648516]*)get bits n = 0</div>
1161 <div class="lineNone">001134| </div>
1162 <div class="lineNone">001135| (*----------------------------------------------------------------------*)</div>
1163 <div class="lineNone">001136| (* Display functions. *)</div>
1164 <div class="lineNone">001137| </div>
1165 <div class="lineNone">001138| let isprint c =</div>
1166 <div class="lineAllVisited">001139| (*[356]*)let c = Char.code c in</div>
1167 <div class="lineAllVisited">001140| (*[356]*)c (*[356]*)>= 32 && (*[311]*)c < 127</div>
1168 <div class="lineNone">001141| </div>
1169 <div class="lineNone">001142| let hexdump_bitstring chan (data, off, len) =</div>
1170 <div class="lineAllVisited">001143| (*[34]*)let count = ref 0 in</div>
1171 <div class="lineAllVisited">001144| (*[34]*)let off = ref off in</div>
1172 <div class="lineAllVisited">001145| (*[34]*)let len = ref len in</div>
1173 <div class="lineAllVisited">001146| (*[34]*)let linelen = ref 0 in</div>
1174 <div class="lineAllVisited">001147| (*[34]*)let linechars = String.make 16 ' ' in</div>
1175 <div class="lineNone">001148| </div>
1176 <div class="lineAllVisited">001149| (*[34]*)fprintf chan "00000000 ";</div>
1177 <div class="lineNone">001150| </div>
1178 <div class="lineAllVisited">001151| (*[34]*)while !len > 0 do</div>
1179 <div class="lineAllVisited">001152| (*[356]*)let bits = min !len 8 in</div>
1180 <div class="lineAllVisited">001153| (*[356]*)let byte = extract_char_unsigned data !off !len bits in</div>
1181 <div class="lineAllVisited">001154| (*[356]*)off := !off + bits; (*[356]*)len (*[356]*):= !len - bits;</div>
1182 <div class="lineNone">001155| </div>
1183 <div class="lineAllVisited">001156| (*[356]*)let byte = byte lsl (8-bits) in</div>
1184 <div class="lineAllVisited">001157| (*[356]*)fprintf chan "%02x " byte;</div>
1185 <div class="lineNone">001158| </div>
1186 <div class="lineAllVisited">001159| (*[356]*)incr count;</div>
1187 <div class="lineAllVisited">001160| (*[356]*)linechars.[!linelen] <-</div>
1188 <div class="lineNone">001161| (let c = Char.chr byte in</div>
1189 <div class="lineAllVisited">001162| (*[356]*)if isprint c then (*[110]*)c else (*[246]*)'.');</div>
1190 <div class="lineAllVisited">001163| (*[356]*)incr linelen;</div>
1191 <div class="lineAllVisited">001164| (*[335]*)if !linelen = 8 then (*[21]*)fprintf chan " ";</div>
1192 <div class="lineAllVisited">001165| (*[343]*)if !linelen = 16 then (</div>
1193 <div class="lineAllVisited">001166| (*[13]*)fprintf chan " |%s|\n%08x " linechars !count;</div>
1194 <div class="lineAllVisited">001167| (*[13]*)linelen (*[13]*):= 0;</div>
1195 <div class="lineAllVisited">001168| (*[13]*)for i = 0 to 15 do (*[208]*)linechars.[i] <- ' ' done</div>
1196 <div class="lineNone">001169| )</div>
1197 <div class="lineNone">001170| done;</div>
1198 <div class="lineNone">001171| </div>
1199 <div class="lineAllVisited">001172| (*[34]*)if !linelen > 0 then (</div>
1200 <div class="lineAllVisited">001173| (*[32]*)let skip = (16 - !linelen) * 3 + if !linelen < 8 then (*[24]*)1 else (*[8]*)0 in</div>
1201 <div class="lineAllVisited">001174| (*[32]*)for i = 0 to skip-1 do (*[1116]*)fprintf chan " " done;</div>
1202 <div class="lineAllVisited">001175| (*[32]*)fprintf chan " |%s|\n%!" linechars</div>
1203 <div class="lineNone">001176| ) else</div>
1204 <div class="lineAllVisited">001177| (*[2]*)fprintf chan "\n%!"</div>
1206 <hr class="codeSep"/>
1207 <p class="footer">Generated by <a href="http://bisect.x9c.fr">Bisect</a> on 2008-08-27 13:53:18</p>