- <div class="lineNone">000129| let subbitstring (data, off, len) off' len' =</div>
- <div class="lineAllUnvisited">000130| (*[0]*)let off = off + off' in</div>
- <div class="lineAllUnvisited">000131| (*[0]*)if len < off' + len' then (*[0]*)invalid_arg "subbitstring";</div>
- <div class="lineAllUnvisited">000132| ((*[0]*)data, off, len')</div>
- <div class="lineNone">000133| </div>
- <div class="lineNone">000134| let dropbits n (data, off, len) =</div>
- <div class="lineAllVisited">000135| (*[335487]*)let off = off + n in</div>
- <div class="lineAllVisited">000136| (*[335487]*)let len = len - n in</div>
- <div class="lineMixed">000137| (*[335487]*)if len < 0 then (*[0]*)invalid_arg "dropbits";</div>
- <div class="lineAllVisited">000138| ((*[335487]*)data, off, len)</div>
- <div class="lineNone">000139| </div>
- <div class="lineNone">000140| let takebits n (data, off, len) =</div>
- <div class="lineAllUnvisited">000141| (*[0]*)if len < n then (*[0]*)invalid_arg "takebits";</div>
- <div class="lineAllUnvisited">000142| ((*[0]*)data, off, n)</div>
- <div class="lineNone">000143| </div>
- <div class="lineNone">000144| (*----------------------------------------------------------------------*)</div>
- <div class="lineNone">000145| (* Bitwise functions.</div>
- <div class="lineNone">000146| *</div>
- <div class="lineNone">000147| * We try to isolate all bitwise functions within these modules.</div>
- <div class="lineNone">000148| *)</div>
- <div class="lineNone">000149| </div>
- <div class="lineNone">000150| module I = struct</div>
- <div class="lineNone">000151| (* Bitwise operations on ints. Note that we assume int <= 31 bits. *)</div>
- <div class="lineNone">000152| external (<<<) : int -> int -> int = "%lslint"</div>
- <div class="lineNone">000153| external (>>>) : int -> int -> int = "%lsrint"</div>
- <div class="lineNone">000154| external to_int : int -> int = "%identity"</div>
- <div class="lineAllVisited">000155| let zero = (*[28]*)0</div>
- <div class="lineAllVisited">000156| let one = (*[28]*)1</div>
- <div class="lineAllVisited">000157| let minus_one = (*[28]*)-1</div>
- <div class="lineAllVisited">000158| let ff = (*[28]*)0xff</div>
- <div class="lineNone">000159| </div>
- <div class="lineNone">000160| (* Create a mask 0-31 bits wide. *)</div>
- <div class="lineNone">000161| let mask bits =</div>
- <div class="lineAllVisited">000162| (*[2]*)if bits < 30 then</div>
- <div class="lineAllVisited">000163| ((*[2]*)one <<< bits) - 1</div>
- <div class="lineAllUnvisited">000164| else (*[0]*)if bits = 30 then</div>
- <div class="lineAllUnvisited">000165| (*[0]*)max_int</div>
- <div class="lineAllUnvisited">000166| else (*[0]*)if bits = 31 then</div>
- <div class="lineAllUnvisited">000167| (*[0]*)minus_one</div>
- <div class="lineNone">000168| else</div>
- <div class="lineAllUnvisited">000169| (*[0]*)invalid_arg "Bitstring.I.mask"</div>
- <div class="lineNone">000170| </div>
- <div class="lineNone">000171| (* Byte swap an int of a given size. *)</div>
- <div class="lineNone">000172| let byteswap v bits =</div>
- <div class="lineAllUnvisited">000173| (*[0]*)if bits <= 8 then (*[0]*)v</div>
- <div class="lineAllUnvisited">000174| else (*[0]*)if bits <= 16 then (</div>
- <div class="lineAllUnvisited">000175| (*[0]*)let shift = bits-8 in</div>
- <div class="lineAllUnvisited">000176| (*[0]*)let v1 = v >>> shift in</div>
- <div class="lineAllUnvisited">000177| (*[0]*)let v2 = ((v land (mask shift)) <<< 8) in</div>
- <div class="lineAllUnvisited">000178| v2 (*[0]*)lor v1</div>
- <div class="lineAllUnvisited">000179| ) else (*[0]*)if bits <= 24 then (</div>
- <div class="lineAllUnvisited">000180| (*[0]*)let shift = bits - 16 in</div>
- <div class="lineAllUnvisited">000181| (*[0]*)let v1 = v >>> (8+shift) in</div>
- <div class="lineAllUnvisited">000182| (*[0]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
- <div class="lineAllUnvisited">000183| (*[0]*)let v3 = (v land (mask shift)) <<< 16 in</div>
- <div class="lineAllUnvisited">000184| v3 lor v2 (*[0]*)lor v1</div>
- <div class="lineNone">000185| ) else (</div>
- <div class="lineAllUnvisited">000186| (*[0]*)let shift = bits - 24 in</div>
- <div class="lineAllUnvisited">000187| (*[0]*)let v1 = v >>> (16+shift) in</div>
- <div class="lineAllUnvisited">000188| (*[0]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
- <div class="lineAllUnvisited">000189| (*[0]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
- <div class="lineAllUnvisited">000190| (*[0]*)let v4 = (v land (mask shift)) <<< 24 in</div>
- <div class="lineAllUnvisited">000191| v4 lor v3 lor v2 (*[0]*)lor v1</div>
- <div class="lineNone">000192| )</div>
- <div class="lineNone">000193| </div>
- <div class="lineNone">000194| (* Check a value is in range 0 .. 2^bits-1. *)</div>
- <div class="lineNone">000195| let range_unsigned v bits =</div>
- <div class="lineAllVisited">000196| (*[2]*)let mask = lnot (mask bits) in</div>
- <div class="lineAllVisited">000197| (v (*[2]*)land mask) = zero</div>
- <div class="lineNone">000198| </div>
- <div class="lineNone">000199| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000200| * (big endian - so start at top).</div>
- <div class="lineNone">000201| *)</div>
- <div class="lineNone">000202| let rec map_bytes_be g f v bits =</div>
- <div class="lineAllVisited">000203| (*[6]*)if bits >= 8 then (</div>
- <div class="lineAllVisited">000204| (*[4]*)map_bytes_be g f (v >>> 8) (*[4]*)(bits-8);</div>
- <div class="lineAllVisited">000205| (*[4]*)let lsb = v land ff in</div>
- <div class="lineAllVisited">000206| (*[4]*)f (to_int lsb)</div>
- <div class="lineAllVisited">000207| ) else (*[2]*)if bits > 0 then (</div>
- <div class="lineAllUnvisited">000208| (*[0]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllUnvisited">000209| (*[0]*)g (to_int lsb) bits</div>
- <div class="lineNone">000210| )</div>
- <div class="lineNone">000211| </div>
- <div class="lineNone">000212| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000213| * (little endian - so start at root).</div>
- <div class="lineNone">000214| *)</div>
- <div class="lineNone">000215| let rec map_bytes_le g f v bits =</div>
- <div class="lineAllUnvisited">000216| (*[0]*)if bits >= 8 then (</div>
- <div class="lineAllUnvisited">000217| (*[0]*)let lsb = v land ff in</div>
- <div class="lineAllUnvisited">000218| (*[0]*)f (*[0]*)(to_int lsb);</div>
- <div class="lineAllUnvisited">000219| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
- <div class="lineAllUnvisited">000220| ) else (*[0]*)if bits > 0 then (</div>
- <div class="lineAllUnvisited">000221| (*[0]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllUnvisited">000222| (*[0]*)g (to_int lsb) bits</div>
- <div class="lineNone">000223| )</div>
- <div class="lineNone">000224| end</div>
- <div class="lineNone">000225| </div>
- <div class="lineNone">000226| module I32 = struct</div>
- <div class="lineNone">000227| (* Bitwise operations on int32s. Note we try to keep it as similar</div>
- <div class="lineNone">000228| * as possible to the I module above, to make it easier to track</div>
- <div class="lineNone">000229| * down bugs.</div>
- <div class="lineNone">000230| *)</div>
- <div class="lineAllVisited">000231| let (<<<) = (*[28]*)Int32.shift_left</div>
- <div class="lineAllVisited">000232| let (>>>) = (*[28]*)Int32.shift_right_logical</div>
- <div class="lineAllVisited">000233| let (land) = (*[28]*)Int32.logand</div>
- <div class="lineAllVisited">000234| let (lor) = (*[28]*)Int32.logor</div>
- <div class="lineAllVisited">000235| let lnot = (*[28]*)Int32.lognot</div>
- <div class="lineAllVisited">000236| let pred = (*[28]*)Int32.pred</div>
- <div class="lineAllVisited">000237| let max_int = (*[28]*)Int32.max_int</div>
- <div class="lineAllVisited">000238| let to_int = (*[28]*)Int32.to_int</div>
- <div class="lineAllVisited">000239| let zero = (*[28]*)Int32.zero</div>
- <div class="lineAllVisited">000240| let one = (*[28]*)Int32.one</div>
- <div class="lineAllVisited">000241| let minus_one = (*[28]*)Int32.minus_one</div>
- <div class="lineAllVisited">000242| let ff = (*[28]*)0xff_l</div>
- <div class="lineNone">000243| </div>
- <div class="lineNone">000244| (* Create a mask so many bits wide. *)</div>
- <div class="lineNone">000245| let mask bits =</div>
- <div class="lineAllVisited">000246| (*[12]*)if bits < 31 then</div>
- <div class="lineAllVisited">000247| (*[12]*)pred (one <<< bits)</div>
- <div class="lineAllUnvisited">000248| else (*[0]*)if bits = 31 then</div>
- <div class="lineAllUnvisited">000249| (*[0]*)max_int</div>
- <div class="lineAllUnvisited">000250| else (*[0]*)if bits = 32 then</div>
- <div class="lineAllUnvisited">000251| (*[0]*)minus_one</div>
- <div class="lineNone">000252| else</div>
- <div class="lineAllUnvisited">000253| (*[0]*)invalid_arg "Bitstring.I32.mask"</div>
- <div class="lineNone">000254| </div>
- <div class="lineNone">000255| (* Byte swap an int of a given size. *)</div>
- <div class="lineNone">000256| let byteswap v bits =</div>
- <div class="lineMixed">000257| (*[12]*)if bits <= 8 then (*[0]*)v</div>
- <div class="lineAllVisited">000258| else (*[12]*)if bits <= 16 then (</div>
- <div class="lineAllUnvisited">000259| (*[0]*)let shift = bits-8 in</div>
- <div class="lineAllUnvisited">000260| (*[0]*)let v1 = v >>> shift in</div>
- <div class="lineAllUnvisited">000261| (*[0]*)let v2 = (v land (mask shift)) <<< 8 in</div>
- <div class="lineAllUnvisited">000262| v2 (*[0]*)lor v1</div>
- <div class="lineAllVisited">000263| ) else (*[12]*)if bits <= 24 then (</div>
- <div class="lineAllUnvisited">000264| (*[0]*)let shift = bits - 16 in</div>
- <div class="lineAllUnvisited">000265| (*[0]*)let v1 = v >>> (8+shift) in</div>
- <div class="lineAllUnvisited">000266| (*[0]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
- <div class="lineAllUnvisited">000267| (*[0]*)let v3 = (v land (mask shift)) <<< 16 in</div>
- <div class="lineAllUnvisited">000268| v3 lor v2 (*[0]*)lor v1</div>
- <div class="lineNone">000269| ) else (</div>
- <div class="lineAllVisited">000270| (*[12]*)let shift = bits - 24 in</div>
- <div class="lineAllVisited">000271| (*[12]*)let v1 = v >>> (16+shift) in</div>
- <div class="lineAllVisited">000272| (*[12]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
- <div class="lineAllVisited">000273| (*[12]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
- <div class="lineAllVisited">000274| (*[12]*)let v4 = (v land (mask shift)) <<< 24 in</div>
- <div class="lineAllVisited">000275| v4 lor v3 lor v2 (*[12]*)lor v1</div>
- <div class="lineNone">000276| )</div>
- <div class="lineNone">000277| </div>
- <div class="lineNone">000278| (* Check a value is in range 0 .. 2^bits-1. *)</div>
- <div class="lineNone">000279| let range_unsigned v bits =</div>
- <div class="lineAllUnvisited">000280| (*[0]*)let mask = lnot (mask bits) in</div>
- <div class="lineAllUnvisited">000281| (v (*[0]*)land mask) = zero</div>
- <div class="lineNone">000282| </div>
- <div class="lineNone">000283| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000284| * (big endian - so start at top).</div>
- <div class="lineNone">000285| *)</div>
- <div class="lineNone">000286| let rec map_bytes_be g f v bits =</div>
- <div class="lineAllUnvisited">000287| (*[0]*)if bits >= 8 then (</div>
- <div class="lineAllUnvisited">000288| (*[0]*)map_bytes_be g f (v >>> 8) (*[0]*)(bits-8);</div>
- <div class="lineAllUnvisited">000289| (*[0]*)let lsb = v land ff in</div>
- <div class="lineAllUnvisited">000290| (*[0]*)f (to_int lsb)</div>
- <div class="lineAllUnvisited">000291| ) else (*[0]*)if bits > 0 then (</div>
- <div class="lineAllUnvisited">000292| (*[0]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllUnvisited">000293| (*[0]*)g (to_int lsb) bits</div>
- <div class="lineNone">000294| )</div>
- <div class="lineNone">000295| </div>
- <div class="lineNone">000296| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000297| * (little endian - so start at root).</div>
- <div class="lineNone">000298| *)</div>
- <div class="lineNone">000299| let rec map_bytes_le g f v bits =</div>
- <div class="lineAllUnvisited">000300| (*[0]*)if bits >= 8 then (</div>
- <div class="lineAllUnvisited">000301| (*[0]*)let lsb = v land ff in</div>
- <div class="lineAllUnvisited">000302| (*[0]*)f (*[0]*)(to_int lsb);</div>
- <div class="lineAllUnvisited">000303| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
- <div class="lineAllUnvisited">000304| ) else (*[0]*)if bits > 0 then (</div>
- <div class="lineAllUnvisited">000305| (*[0]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllUnvisited">000306| (*[0]*)g (to_int lsb) bits</div>
- <div class="lineNone">000307| )</div>
- <div class="lineNone">000308| end</div>
- <div class="lineNone">000309| </div>
- <div class="lineNone">000310| module I64 = struct</div>
- <div class="lineNone">000311| (* Bitwise operations on int64s. Note we try to keep it as similar</div>
- <div class="lineNone">000312| * as possible to the I/I32 modules above, to make it easier to track</div>
- <div class="lineNone">000313| * down bugs.</div>
- <div class="lineNone">000314| *)</div>
- <div class="lineAllVisited">000315| let (<<<) = (*[28]*)Int64.shift_left</div>
- <div class="lineAllVisited">000316| let (>>>) = (*[28]*)Int64.shift_right_logical</div>
- <div class="lineAllVisited">000317| let (land) = (*[28]*)Int64.logand</div>
- <div class="lineAllVisited">000318| let (lor) = (*[28]*)Int64.logor</div>
- <div class="lineAllVisited">000319| let lnot = (*[28]*)Int64.lognot</div>
- <div class="lineAllVisited">000320| let pred = (*[28]*)Int64.pred</div>
- <div class="lineAllVisited">000321| let max_int = (*[28]*)Int64.max_int</div>
- <div class="lineAllVisited">000322| let to_int = (*[28]*)Int64.to_int</div>
- <div class="lineAllVisited">000323| let zero = (*[28]*)Int64.zero</div>
- <div class="lineAllVisited">000324| let one = (*[28]*)Int64.one</div>
- <div class="lineAllVisited">000325| let minus_one = (*[28]*)Int64.minus_one</div>
- <div class="lineAllVisited">000326| let ff = (*[28]*)0xff_L</div>
- <div class="lineNone">000327| </div>
- <div class="lineNone">000328| (* Create a mask so many bits wide. *)</div>
- <div class="lineNone">000329| let mask bits =</div>
- <div class="lineAllVisited">000330| (*[669050]*)if bits < 63 then</div>
- <div class="lineAllVisited">000331| (*[664100]*)pred (one <<< bits)</div>
- <div class="lineAllVisited">000332| else (*[4950]*)if bits = 63 then</div>
- <div class="lineAllVisited">000333| (*[4950]*)max_int</div>
- <div class="lineAllUnvisited">000334| else (*[0]*)if bits = 64 then</div>
- <div class="lineAllUnvisited">000335| (*[0]*)minus_one</div>
- <div class="lineNone">000336| else</div>
- <div class="lineAllUnvisited">000337| (*[0]*)invalid_arg "Bitstring.I64.mask"</div>
- <div class="lineNone">000338| </div>
- <div class="lineNone">000339| (* Byte swap an int of a given size. *)</div>
- <div class="lineNone">000340| (* let byteswap v bits = *)</div>
- <div class="lineNone">000341| </div>
- <div class="lineNone">000342| (* Check a value is in range 0 .. 2^bits-1. *)</div>
- <div class="lineNone">000343| let range_unsigned v bits =</div>
- <div class="lineAllVisited">000344| (*[351850]*)let mask = lnot (mask bits) in</div>
- <div class="lineAllVisited">000345| (v (*[351850]*)land mask) = zero</div>
- <div class="lineNone">000346| </div>
- <div class="lineNone">000347| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000348| * (big endian - so start at top).</div>
- <div class="lineNone">000349| *)</div>
- <div class="lineNone">000350| let rec map_bytes_be g f v bits =</div>
- <div class="lineAllVisited">000351| (*[1460650]*)if bits >= 8 then (</div>
- <div class="lineAllVisited">000352| (*[1108800]*)map_bytes_be g f (v >>> 8) (*[1108800]*)(bits-8);</div>
- <div class="lineAllVisited">000353| (*[1108800]*)let lsb = v land ff in</div>
- <div class="lineAllVisited">000354| (*[1108800]*)f (to_int lsb)</div>
- <div class="lineAllVisited">000355| ) else (*[34650]*)if bits > 0 then (</div>
- <div class="lineAllVisited">000356| (*[317200]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllVisited">000357| (*[317200]*)g (to_int lsb) bits</div>
- <div class="lineNone">000358| )</div>
- <div class="lineNone">000359| </div>
- <div class="lineNone">000360| (* Call function g on the top bits, then f on each full byte</div>
- <div class="lineNone">000361| * (little endian - so start at root).</div>
- <div class="lineNone">000362| *)</div>
- <div class="lineNone">000363| let rec map_bytes_le g f v bits =</div>
- <div class="lineAllUnvisited">000364| (*[0]*)if bits >= 8 then (</div>
- <div class="lineAllUnvisited">000365| (*[0]*)let lsb = v land ff in</div>
- <div class="lineAllUnvisited">000366| (*[0]*)f (*[0]*)(to_int lsb);</div>
- <div class="lineAllUnvisited">000367| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
- <div class="lineAllUnvisited">000368| ) else (*[0]*)if bits > 0 then (</div>
- <div class="lineAllUnvisited">000369| (*[0]*)let lsb = v land (mask bits) in</div>
- <div class="lineAllUnvisited">000370| (*[0]*)g (to_int lsb) bits</div>
- <div class="lineNone">000371| )</div>
- <div class="lineNone">000372| end</div>
- <div class="lineNone">000373| </div>
- <div class="lineNone">000374| (*----------------------------------------------------------------------*)</div>
- <div class="lineNone">000375| (* Extraction functions.</div>
- <div class="lineNone">000376| *</div>
- <div class="lineNone">000377| * NB: internal functions, called from the generated macros, and</div>
- <div class="lineNone">000378| * the parameters should have been checked for sanity already).</div>
- <div class="lineNone">000379| *)</div>
- <div class="lineNone">000380| </div>
- <div class="lineNone">000381| (* Extract and convert to numeric. A single bit is returned as</div>
- <div class="lineNone">000382| * a boolean. There are no endianness or signedness considerations.</div>
- <div class="lineNone">000383| *)</div>
- <div class="lineNone">000384| let extract_bit data off len _ = (* final param is always 1 *)</div>
- <div class="lineAllVisited">000385| (*[2515152]*)let byteoff = off lsr 3 in</div>
- <div class="lineAllVisited">000386| (*[2515152]*)let bitmask = 1 lsl (7 - (off land 7)) in</div>
- <div class="lineAllVisited">000387| (*[2515152]*)let b = Char.code data.[byteoff] land bitmask <> 0 in</div>
- <div class="lineAllVisited">000388| (*[2515152]*)b (*, off+1, len-1*)</div>
- <div class="lineNone">000389| </div>
- <div class="lineNone">000390| (* Returns 8 bit unsigned aligned bytes from the string.</div>
- <div class="lineNone">000391| * If the string ends then this returns 0's.</div>
- <div class="lineNone">000392| *)</div>
- <div class="lineNone">000393| let _get_byte data byteoff strlen =</div>
- <div class="lineAllVisited">000394| (*[9813846]*)if strlen > byteoff then (*[9247619]*)Char.code data.[byteoff] else (*[566227]*)0</div>
- <div class="lineNone">000395| let _get_byte32 data byteoff strlen =</div>
- <div class="lineMixed">000396| (*[72]*)if strlen > byteoff then (*[72]*)Int32.of_int (Char.code data.[byteoff]) else (*[0]*)0l</div>
- <div class="lineNone">000397| let _get_byte64 data byteoff strlen =</div>
- <div class="lineAllVisited">000398| (*[1626200]*)if strlen > byteoff then (*[1517793]*)Int64.of_int (Char.code data.[byteoff]) else (*[108407]*)0L</div>
- <div class="lineNone">000399| </div>
- <div class="lineNone">000400| (* Extract [2..8] bits. Because the result fits into a single</div>
- <div class="lineNone">000401| * byte we don't have to worry about endianness, only signedness.</div>
- <div class="lineNone">000402| *)</div>
- <div class="lineNone">000403| let extract_char_unsigned data off len flen =</div>
- <div class="lineAllVisited">000404| (*[5009970]*)let byteoff = off lsr 3 in</div>
- <div class="lineNone">000405| </div>
- <div class="lineNone">000406| (* Optimize the common (byte-aligned) case. *)</div>
- <div class="lineAllVisited">000407| (*[5009970]*)if off land 7 = 0 then (</div>
- <div class="lineAllVisited">000408| (*[103047]*)let byte = Char.code data.[byteoff] in</div>
- <div class="lineAllVisited">000409| byte (*[103047]*)lsr (8 - flen) (*, off+flen, len-flen*)</div>
- <div class="lineNone">000410| ) else (</div>
- <div class="lineNone">000411| (* Extract the 16 bits at byteoff and byteoff+1 (note that the</div>
- <div class="lineNone">000412| * second byte might not exist in the original string).</div>
- <div class="lineNone">000413| *)</div>
- <div class="lineAllVisited">000414| (*[4906923]*)let strlen = String.length data in</div>
- <div class="lineNone">000415| </div>
- <div class="lineAllVisited">000416| (*[4906923]*)let word =</div>
- <div class="lineNone">000417| (_get_byte data byteoff strlen lsl 8) +</div>
- <div class="lineNone">000418| _get_byte data (byteoff+1) strlen in</div>
- <div class="lineNone">000419| </div>
- <div class="lineNone">000420| (* Mask off the top bits. *)</div>
- <div class="lineAllVisited">000421| (*[4906923]*)let bitmask = (1 lsl (16 - (off land 7))) - 1 in</div>
- <div class="lineAllVisited">000422| (*[4906923]*)let word = word land bitmask in</div>
- <div class="lineNone">000423| (* Shift right to get rid of the bottom bits. *)</div>
- <div class="lineAllVisited">000424| (*[4906923]*)let shift = 16 - ((off land 7) + flen) in</div>
- <div class="lineAllVisited">000425| (*[4906923]*)let word = word lsr shift in</div>
- <div class="lineNone">000426| </div>
- <div class="lineAllVisited">000427| (*[4906923]*)word (*, off+flen, len-flen*)</div>
- <div class="lineNone">000428| )</div>
- <div class="lineNone">000429| </div>
- <div class="lineNone">000430| (* Extract [9..31] bits. We have to consider endianness and signedness. *)</div>
- <div class="lineNone">000431| let extract_int_be_unsigned data off len flen =</div>
- <div class="lineAllUnvisited">000432| (*[0]*)let byteoff = off lsr 3 in</div>
- <div class="lineNone">000433| </div>
- <div class="lineAllUnvisited">000434| (*[0]*)let strlen = String.length data in</div>
+ <div class="lineAllVisited">000129| let bitstring_length (_, _, len) = (*[1565296]*)len</div>
+ <div class="lineNone">000130| </div>
+ <div class="lineNone">000131| let subbitstring (data, off, len) off' len' =</div>
+ <div class="lineAllUnvisited">000132| (*[0]*)let off = off + off' in</div>
+ <div class="lineAllUnvisited">000133| (*[0]*)if len < off' + len' then (*[0]*)invalid_arg "subbitstring";</div>
+ <div class="lineAllUnvisited">000134| ((*[0]*)data, off, len')</div>
+ <div class="lineNone">000135| </div>
+ <div class="lineNone">000136| let dropbits n (data, off, len) =</div>
+ <div class="lineAllVisited">000137| (*[336643]*)let off = off + n in</div>
+ <div class="lineAllVisited">000138| (*[336643]*)let len = len - n in</div>
+ <div class="lineMixed">000139| (*[336643]*)if len < 0 then (*[0]*)invalid_arg "dropbits";</div>
+ <div class="lineAllVisited">000140| ((*[336643]*)data, off, len)</div>
+ <div class="lineNone">000141| </div>
+ <div class="lineNone">000142| let takebits n (data, off, len) =</div>
+ <div class="lineAllUnvisited">000143| (*[0]*)if len < n then (*[0]*)invalid_arg "takebits";</div>
+ <div class="lineAllUnvisited">000144| ((*[0]*)data, off, n)</div>
+ <div class="lineNone">000145| </div>
+ <div class="lineNone">000146| (*----------------------------------------------------------------------*)</div>
+ <div class="lineNone">000147| (* Bitwise functions.</div>
+ <div class="lineNone">000148| *</div>
+ <div class="lineNone">000149| * We try to isolate all bitwise functions within these modules.</div>
+ <div class="lineNone">000150| *)</div>
+ <div class="lineNone">000151| </div>
+ <div class="lineNone">000152| module I = struct</div>
+ <div class="lineNone">000153| (* Bitwise operations on ints. Note that we assume int <= 31 bits. *)</div>
+ <div class="lineNone">000154| external (<<<) : int -> int -> int = "%lslint"</div>
+ <div class="lineNone">000155| external (>>>) : int -> int -> int = "%lsrint"</div>
+ <div class="lineNone">000156| external to_int : int -> int = "%identity"</div>
+ <div class="lineAllVisited">000157| let zero = (*[34]*)0</div>
+ <div class="lineAllVisited">000158| let one = (*[34]*)1</div>
+ <div class="lineAllVisited">000159| let minus_one = (*[34]*)-1</div>
+ <div class="lineAllVisited">000160| let ff = (*[34]*)0xff</div>
+ <div class="lineNone">000161| </div>
+ <div class="lineNone">000162| (* Create a mask 0-31 bits wide. *)</div>
+ <div class="lineNone">000163| let mask bits =</div>
+ <div class="lineAllVisited">000164| (*[2]*)if bits < 30 then</div>
+ <div class="lineAllVisited">000165| ((*[2]*)one <<< bits) - 1</div>
+ <div class="lineAllUnvisited">000166| else (*[0]*)if bits = 30 then</div>
+ <div class="lineAllUnvisited">000167| (*[0]*)max_int</div>
+ <div class="lineAllUnvisited">000168| else (*[0]*)if bits = 31 then</div>
+ <div class="lineAllUnvisited">000169| (*[0]*)minus_one</div>
+ <div class="lineNone">000170| else</div>
+ <div class="lineAllUnvisited">000171| (*[0]*)invalid_arg "Bitstring.I.mask"</div>
+ <div class="lineNone">000172| </div>
+ <div class="lineNone">000173| (* Byte swap an int of a given size. *)</div>
+ <div class="lineNone">000174| let byteswap v bits =</div>
+ <div class="lineAllUnvisited">000175| (*[0]*)if bits <= 8 then (*[0]*)v</div>
+ <div class="lineAllUnvisited">000176| else (*[0]*)if bits <= 16 then (</div>
+ <div class="lineAllUnvisited">000177| (*[0]*)let shift = bits-8 in</div>
+ <div class="lineAllUnvisited">000178| (*[0]*)let v1 = v >>> shift in</div>
+ <div class="lineAllUnvisited">000179| (*[0]*)let v2 = ((v land (mask shift)) <<< 8) in</div>
+ <div class="lineAllUnvisited">000180| v2 (*[0]*)lor v1</div>
+ <div class="lineAllUnvisited">000181| ) else (*[0]*)if bits <= 24 then (</div>
+ <div class="lineAllUnvisited">000182| (*[0]*)let shift = bits - 16 in</div>
+ <div class="lineAllUnvisited">000183| (*[0]*)let v1 = v >>> (8+shift) in</div>
+ <div class="lineAllUnvisited">000184| (*[0]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
+ <div class="lineAllUnvisited">000185| (*[0]*)let v3 = (v land (mask shift)) <<< 16 in</div>
+ <div class="lineAllUnvisited">000186| v3 lor v2 (*[0]*)lor v1</div>
+ <div class="lineNone">000187| ) else (</div>
+ <div class="lineAllUnvisited">000188| (*[0]*)let shift = bits - 24 in</div>
+ <div class="lineAllUnvisited">000189| (*[0]*)let v1 = v >>> (16+shift) in</div>
+ <div class="lineAllUnvisited">000190| (*[0]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
+ <div class="lineAllUnvisited">000191| (*[0]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
+ <div class="lineAllUnvisited">000192| (*[0]*)let v4 = (v land (mask shift)) <<< 24 in</div>
+ <div class="lineAllUnvisited">000193| v4 lor v3 lor v2 (*[0]*)lor v1</div>
+ <div class="lineNone">000194| )</div>
+ <div class="lineNone">000195| </div>
+ <div class="lineNone">000196| (* Check a value is in range 0 .. 2^bits-1. *)</div>
+ <div class="lineNone">000197| let range_unsigned v bits =</div>
+ <div class="lineAllVisited">000198| (*[2]*)let mask = lnot (mask bits) in</div>
+ <div class="lineAllVisited">000199| (v (*[2]*)land mask) = zero</div>
+ <div class="lineNone">000200| </div>
+ <div class="lineNone">000201| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000202| * (big endian - so start at top).</div>
+ <div class="lineNone">000203| *)</div>
+ <div class="lineNone">000204| let rec map_bytes_be g f v bits =</div>
+ <div class="lineAllVisited">000205| (*[6]*)if bits >= 8 then (</div>
+ <div class="lineAllVisited">000206| (*[4]*)map_bytes_be g f (v >>> 8) (*[4]*)(bits-8);</div>
+ <div class="lineAllVisited">000207| (*[4]*)let lsb = v land ff in</div>
+ <div class="lineAllVisited">000208| (*[4]*)f (to_int lsb)</div>
+ <div class="lineAllVisited">000209| ) else (*[2]*)if bits > 0 then (</div>
+ <div class="lineAllUnvisited">000210| (*[0]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllUnvisited">000211| (*[0]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000212| )</div>
+ <div class="lineNone">000213| </div>
+ <div class="lineNone">000214| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000215| * (little endian - so start at root).</div>
+ <div class="lineNone">000216| *)</div>
+ <div class="lineNone">000217| let rec map_bytes_le g f v bits =</div>
+ <div class="lineAllUnvisited">000218| (*[0]*)if bits >= 8 then (</div>
+ <div class="lineAllUnvisited">000219| (*[0]*)let lsb = v land ff in</div>
+ <div class="lineAllUnvisited">000220| (*[0]*)f (*[0]*)(to_int lsb);</div>
+ <div class="lineAllUnvisited">000221| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
+ <div class="lineAllUnvisited">000222| ) else (*[0]*)if bits > 0 then (</div>
+ <div class="lineAllUnvisited">000223| (*[0]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllUnvisited">000224| (*[0]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000225| )</div>
+ <div class="lineNone">000226| end</div>
+ <div class="lineNone">000227| </div>
+ <div class="lineNone">000228| module I32 = struct</div>
+ <div class="lineNone">000229| (* Bitwise operations on int32s. Note we try to keep it as similar</div>
+ <div class="lineNone">000230| * as possible to the I module above, to make it easier to track</div>
+ <div class="lineNone">000231| * down bugs.</div>
+ <div class="lineNone">000232| *)</div>
+ <div class="lineAllVisited">000233| let (<<<) = (*[34]*)Int32.shift_left</div>
+ <div class="lineAllVisited">000234| let (>>>) = (*[34]*)Int32.shift_right_logical</div>
+ <div class="lineAllVisited">000235| let (land) = (*[34]*)Int32.logand</div>
+ <div class="lineAllVisited">000236| let (lor) = (*[34]*)Int32.logor</div>
+ <div class="lineAllVisited">000237| let lnot = (*[34]*)Int32.lognot</div>
+ <div class="lineAllVisited">000238| let pred = (*[34]*)Int32.pred</div>
+ <div class="lineAllVisited">000239| let max_int = (*[34]*)Int32.max_int</div>
+ <div class="lineAllVisited">000240| let to_int = (*[34]*)Int32.to_int</div>
+ <div class="lineAllVisited">000241| let zero = (*[34]*)Int32.zero</div>
+ <div class="lineAllVisited">000242| let one = (*[34]*)Int32.one</div>
+ <div class="lineAllVisited">000243| let minus_one = (*[34]*)Int32.minus_one</div>
+ <div class="lineAllVisited">000244| let ff = (*[34]*)0xff_l</div>
+ <div class="lineNone">000245| </div>
+ <div class="lineNone">000246| (* Create a mask so many bits wide. *)</div>
+ <div class="lineNone">000247| let mask bits =</div>
+ <div class="lineAllVisited">000248| (*[12]*)if bits < 31 then</div>
+ <div class="lineAllVisited">000249| (*[12]*)pred (one <<< bits)</div>
+ <div class="lineAllUnvisited">000250| else (*[0]*)if bits = 31 then</div>
+ <div class="lineAllUnvisited">000251| (*[0]*)max_int</div>
+ <div class="lineAllUnvisited">000252| else (*[0]*)if bits = 32 then</div>
+ <div class="lineAllUnvisited">000253| (*[0]*)minus_one</div>
+ <div class="lineNone">000254| else</div>
+ <div class="lineAllUnvisited">000255| (*[0]*)invalid_arg "Bitstring.I32.mask"</div>
+ <div class="lineNone">000256| </div>
+ <div class="lineNone">000257| (* Byte swap an int of a given size. *)</div>
+ <div class="lineNone">000258| let byteswap v bits =</div>
+ <div class="lineMixed">000259| (*[12]*)if bits <= 8 then (*[0]*)v</div>
+ <div class="lineAllVisited">000260| else (*[12]*)if bits <= 16 then (</div>
+ <div class="lineAllUnvisited">000261| (*[0]*)let shift = bits-8 in</div>
+ <div class="lineAllUnvisited">000262| (*[0]*)let v1 = v >>> shift in</div>
+ <div class="lineAllUnvisited">000263| (*[0]*)let v2 = (v land (mask shift)) <<< 8 in</div>
+ <div class="lineAllUnvisited">000264| v2 (*[0]*)lor v1</div>
+ <div class="lineAllVisited">000265| ) else (*[12]*)if bits <= 24 then (</div>
+ <div class="lineAllUnvisited">000266| (*[0]*)let shift = bits - 16 in</div>
+ <div class="lineAllUnvisited">000267| (*[0]*)let v1 = v >>> (8+shift) in</div>
+ <div class="lineAllUnvisited">000268| (*[0]*)let v2 = ((v >>> shift) land ff) <<< 8 in</div>
+ <div class="lineAllUnvisited">000269| (*[0]*)let v3 = (v land (mask shift)) <<< 16 in</div>
+ <div class="lineAllUnvisited">000270| v3 lor v2 (*[0]*)lor v1</div>
+ <div class="lineNone">000271| ) else (</div>
+ <div class="lineAllVisited">000272| (*[12]*)let shift = bits - 24 in</div>
+ <div class="lineAllVisited">000273| (*[12]*)let v1 = v >>> (16+shift) in</div>
+ <div class="lineAllVisited">000274| (*[12]*)let v2 = ((v >>> (8+shift)) land ff) <<< 8 in</div>
+ <div class="lineAllVisited">000275| (*[12]*)let v3 = ((v >>> shift) land ff) <<< 16 in</div>
+ <div class="lineAllVisited">000276| (*[12]*)let v4 = (v land (mask shift)) <<< 24 in</div>
+ <div class="lineAllVisited">000277| v4 lor v3 lor v2 (*[12]*)lor v1</div>
+ <div class="lineNone">000278| )</div>
+ <div class="lineNone">000279| </div>
+ <div class="lineNone">000280| (* Check a value is in range 0 .. 2^bits-1. *)</div>
+ <div class="lineNone">000281| let range_unsigned v bits =</div>
+ <div class="lineAllUnvisited">000282| (*[0]*)let mask = lnot (mask bits) in</div>
+ <div class="lineAllUnvisited">000283| (v (*[0]*)land mask) = zero</div>
+ <div class="lineNone">000284| </div>
+ <div class="lineNone">000285| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000286| * (big endian - so start at top).</div>
+ <div class="lineNone">000287| *)</div>
+ <div class="lineNone">000288| let rec map_bytes_be g f v bits =</div>
+ <div class="lineAllUnvisited">000289| (*[0]*)if bits >= 8 then (</div>
+ <div class="lineAllUnvisited">000290| (*[0]*)map_bytes_be g f (v >>> 8) (*[0]*)(bits-8);</div>
+ <div class="lineAllUnvisited">000291| (*[0]*)let lsb = v land ff in</div>
+ <div class="lineAllUnvisited">000292| (*[0]*)f (to_int lsb)</div>
+ <div class="lineAllUnvisited">000293| ) else (*[0]*)if bits > 0 then (</div>
+ <div class="lineAllUnvisited">000294| (*[0]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllUnvisited">000295| (*[0]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000296| )</div>
+ <div class="lineNone">000297| </div>
+ <div class="lineNone">000298| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000299| * (little endian - so start at root).</div>
+ <div class="lineNone">000300| *)</div>
+ <div class="lineNone">000301| let rec map_bytes_le g f v bits =</div>
+ <div class="lineAllUnvisited">000302| (*[0]*)if bits >= 8 then (</div>
+ <div class="lineAllUnvisited">000303| (*[0]*)let lsb = v land ff in</div>
+ <div class="lineAllUnvisited">000304| (*[0]*)f (*[0]*)(to_int lsb);</div>
+ <div class="lineAllUnvisited">000305| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
+ <div class="lineAllUnvisited">000306| ) else (*[0]*)if bits > 0 then (</div>
+ <div class="lineAllUnvisited">000307| (*[0]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllUnvisited">000308| (*[0]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000309| )</div>
+ <div class="lineNone">000310| end</div>
+ <div class="lineNone">000311| </div>
+ <div class="lineNone">000312| module I64 = struct</div>
+ <div class="lineNone">000313| (* Bitwise operations on int64s. Note we try to keep it as similar</div>
+ <div class="lineNone">000314| * as possible to the I/I32 modules above, to make it easier to track</div>
+ <div class="lineNone">000315| * down bugs.</div>
+ <div class="lineNone">000316| *)</div>
+ <div class="lineAllVisited">000317| let (<<<) = (*[34]*)Int64.shift_left</div>
+ <div class="lineAllVisited">000318| let (>>>) = (*[34]*)Int64.shift_right_logical</div>
+ <div class="lineAllVisited">000319| let (land) = (*[34]*)Int64.logand</div>
+ <div class="lineAllVisited">000320| let (lor) = (*[34]*)Int64.logor</div>
+ <div class="lineAllVisited">000321| let lnot = (*[34]*)Int64.lognot</div>
+ <div class="lineAllVisited">000322| let pred = (*[34]*)Int64.pred</div>
+ <div class="lineAllVisited">000323| let max_int = (*[34]*)Int64.max_int</div>
+ <div class="lineAllVisited">000324| let to_int = (*[34]*)Int64.to_int</div>
+ <div class="lineAllVisited">000325| let zero = (*[34]*)Int64.zero</div>
+ <div class="lineAllVisited">000326| let one = (*[34]*)Int64.one</div>
+ <div class="lineAllVisited">000327| let minus_one = (*[34]*)Int64.minus_one</div>
+ <div class="lineAllVisited">000328| let ff = (*[34]*)0xff_L</div>
+ <div class="lineNone">000329| </div>
+ <div class="lineNone">000330| (* Create a mask so many bits wide. *)</div>
+ <div class="lineNone">000331| let mask bits =</div>
+ <div class="lineAllVisited">000332| (*[669050]*)if bits < 63 then</div>
+ <div class="lineAllVisited">000333| (*[664100]*)pred (one <<< bits)</div>
+ <div class="lineAllVisited">000334| else (*[4950]*)if bits = 63 then</div>
+ <div class="lineAllVisited">000335| (*[4950]*)max_int</div>
+ <div class="lineAllUnvisited">000336| else (*[0]*)if bits = 64 then</div>
+ <div class="lineAllUnvisited">000337| (*[0]*)minus_one</div>
+ <div class="lineNone">000338| else</div>
+ <div class="lineAllUnvisited">000339| (*[0]*)invalid_arg "Bitstring.I64.mask"</div>
+ <div class="lineNone">000340| </div>
+ <div class="lineNone">000341| (* Byte swap an int of a given size. *)</div>
+ <div class="lineNone">000342| (* let byteswap v bits = *)</div>
+ <div class="lineNone">000343| </div>
+ <div class="lineNone">000344| (* Check a value is in range 0 .. 2^bits-1. *)</div>
+ <div class="lineNone">000345| let range_unsigned v bits =</div>
+ <div class="lineAllVisited">000346| (*[351850]*)let mask = lnot (mask bits) in</div>
+ <div class="lineAllVisited">000347| (v (*[351850]*)land mask) = zero</div>
+ <div class="lineNone">000348| </div>
+ <div class="lineNone">000349| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000350| * (big endian - so start at top).</div>
+ <div class="lineNone">000351| *)</div>
+ <div class="lineNone">000352| let rec map_bytes_be g f v bits =</div>
+ <div class="lineAllVisited">000353| (*[1460650]*)if bits >= 8 then (</div>
+ <div class="lineAllVisited">000354| (*[1108800]*)map_bytes_be g f (v >>> 8) (*[1108800]*)(bits-8);</div>
+ <div class="lineAllVisited">000355| (*[1108800]*)let lsb = v land ff in</div>
+ <div class="lineAllVisited">000356| (*[1108800]*)f (to_int lsb)</div>
+ <div class="lineAllVisited">000357| ) else (*[34650]*)if bits > 0 then (</div>
+ <div class="lineAllVisited">000358| (*[317200]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllVisited">000359| (*[317200]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000360| )</div>
+ <div class="lineNone">000361| </div>
+ <div class="lineNone">000362| (* Call function g on the top bits, then f on each full byte</div>
+ <div class="lineNone">000363| * (little endian - so start at root).</div>
+ <div class="lineNone">000364| *)</div>
+ <div class="lineNone">000365| let rec map_bytes_le g f v bits =</div>
+ <div class="lineAllUnvisited">000366| (*[0]*)if bits >= 8 then (</div>
+ <div class="lineAllUnvisited">000367| (*[0]*)let lsb = v land ff in</div>
+ <div class="lineAllUnvisited">000368| (*[0]*)f (*[0]*)(to_int lsb);</div>
+ <div class="lineAllUnvisited">000369| (*[0]*)map_bytes_le g f (v >>> 8) (bits-8)</div>
+ <div class="lineAllUnvisited">000370| ) else (*[0]*)if bits > 0 then (</div>
+ <div class="lineAllUnvisited">000371| (*[0]*)let lsb = v land (mask bits) in</div>
+ <div class="lineAllUnvisited">000372| (*[0]*)g (to_int lsb) bits</div>
+ <div class="lineNone">000373| )</div>
+ <div class="lineNone">000374| end</div>
+ <div class="lineNone">000375| </div>
+ <div class="lineNone">000376| (*----------------------------------------------------------------------*)</div>
+ <div class="lineNone">000377| (* Extraction functions.</div>
+ <div class="lineNone">000378| *</div>
+ <div class="lineNone">000379| * NB: internal functions, called from the generated macros, and</div>
+ <div class="lineNone">000380| * the parameters should have been checked for sanity already).</div>
+ <div class="lineNone">000381| *)</div>
+ <div class="lineNone">000382| </div>
+ <div class="lineNone">000383| (* Extract and convert to numeric. A single bit is returned as</div>
+ <div class="lineNone">000384| * a boolean. There are no endianness or signedness considerations.</div>
+ <div class="lineNone">000385| *)</div>
+ <div class="lineNone">000386| let extract_bit data off len _ = (* final param is always 1 *)</div>
+ <div class="lineAllVisited">000387| (*[2515152]*)let byteoff = off lsr 3 in</div>
+ <div class="lineAllVisited">000388| (*[2515152]*)let bitmask = 1 lsl (7 - (off land 7)) in</div>
+ <div class="lineAllVisited">000389| (*[2515152]*)let b = Char.code data.[byteoff] land bitmask <> 0 in</div>
+ <div class="lineAllVisited">000390| (*[2515152]*)b (*, off+1, len-1*)</div>
+ <div class="lineNone">000391| </div>
+ <div class="lineNone">000392| (* Returns 8 bit unsigned aligned bytes from the string.</div>
+ <div class="lineNone">000393| * If the string ends then this returns 0's.</div>
+ <div class="lineNone">000394| *)</div>
+ <div class="lineNone">000395| let _get_byte data byteoff strlen =</div>
+ <div class="lineAllVisited">000396| (*[9818264]*)if strlen > byteoff then (*[9252298]*)Char.code data.[byteoff] else (*[565966]*)0</div>
+ <div class="lineNone">000397| let _get_byte32 data byteoff strlen =</div>
+ <div class="lineMixed">000398| (*[72]*)if strlen > byteoff then (*[72]*)Int32.of_int (Char.code data.[byteoff]) else (*[0]*)0l</div>
+ <div class="lineNone">000399| let _get_byte64 data byteoff strlen =</div>
+ <div class="lineAllVisited">000400| (*[1626456]*)if strlen > byteoff then (*[1517847]*)Int64.of_int (Char.code data.[byteoff]) else (*[108609]*)0L</div>
+ <div class="lineNone">000401| </div>
+ <div class="lineNone">000402| (* Extract [2..8] bits. Because the result fits into a single</div>
+ <div class="lineNone">000403| * byte we don't have to worry about endianness, only signedness.</div>
+ <div class="lineNone">000404| *)</div>
+ <div class="lineNone">000405| let extract_char_unsigned data off len flen =</div>
+ <div class="lineAllVisited">000406| (*[5030404]*)let byteoff = off lsr 3 in</div>
+ <div class="lineNone">000407| </div>
+ <div class="lineNone">000408| (* Optimize the common (byte-aligned) case. *)</div>
+ <div class="lineAllVisited">000409| (*[5030404]*)if off land 7 = 0 then (</div>
+ <div class="lineAllVisited">000410| (*[121272]*)let byte = Char.code data.[byteoff] in</div>
+ <div class="lineAllVisited">000411| byte (*[121272]*)lsr (8 - flen) (*, off+flen, len-flen*)</div>
+ <div class="lineNone">000412| ) else (</div>
+ <div class="lineNone">000413| (* Extract the 16 bits at byteoff and byteoff+1 (note that the</div>
+ <div class="lineNone">000414| * second byte might not exist in the original string).</div>
+ <div class="lineNone">000415| *)</div>
+ <div class="lineAllVisited">000416| (*[4909132]*)let strlen = String.length data in</div>
+ <div class="lineNone">000417| </div>
+ <div class="lineAllVisited">000418| (*[4909132]*)let word =</div>
+ <div class="lineNone">000419| (_get_byte data byteoff strlen lsl 8) +</div>
+ <div class="lineNone">000420| _get_byte data (byteoff+1) strlen in</div>
+ <div class="lineNone">000421| </div>
+ <div class="lineNone">000422| (* Mask off the top bits. *)</div>
+ <div class="lineAllVisited">000423| (*[4909132]*)let bitmask = (1 lsl (16 - (off land 7))) - 1 in</div>
+ <div class="lineAllVisited">000424| (*[4909132]*)let word = word land bitmask in</div>
+ <div class="lineNone">000425| (* Shift right to get rid of the bottom bits. *)</div>
+ <div class="lineAllVisited">000426| (*[4909132]*)let shift = 16 - ((off land 7) + flen) in</div>
+ <div class="lineAllVisited">000427| (*[4909132]*)let word = word lsr shift in</div>
+ <div class="lineNone">000428| </div>
+ <div class="lineAllVisited">000429| (*[4909132]*)word (*, off+flen, len-flen*)</div>
+ <div class="lineNone">000430| )</div>
+ <div class="lineNone">000431| </div>
+ <div class="lineNone">000432| (* Extract [9..31] bits. We have to consider endianness and signedness. *)</div>
+ <div class="lineNone">000433| let extract_int_be_unsigned data off len flen =</div>
+ <div class="lineAllUnvisited">000434| (*[0]*)let byteoff = off lsr 3 in</div>