···11+## v0.2.0 (2024-03-18)
22+33+* Rename pp to pp_hexdump
44+* Add a pp which just prints the hex with some spaces, but no newlines
55+66+## v0.1.0 (2024-03-14)
77+88+* Initial release
+23
vendor/opam/ohex/LICENSE.md
···11+Copyright (c) 2024, Hannes Mehnert
22+All rights reserved.
33+44+Redistribution and use in source and binary forms, with or without modification,
55+are permitted provided that the following conditions are met:
66+77+* Redistributions of source code must retain the above copyright notice, this
88+ list of conditions and the following disclaimer.
99+1010+* Redistributions in binary form must reproduce the above copyright notice, this
1111+ list of conditions and the following disclaimer in the documentation and/or
1212+ other materials provided with the distribution.
1313+1414+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1515+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1616+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1717+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1818+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1919+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2020+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2121+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2222+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2323+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+10
vendor/opam/ohex/README.md
···11+## oHEX
22+33+This package with minimal dependency cone provides functionality to decode and
44+encode strings into hexadecimal representation.
55+66+As example, `Ohex.decode "4142" = "AB"`. And `Ohex.encode "AB" = "4142"`.
77+88+There's even the property, for all strings s: `Ohex.(decode (encode s)) = s`.
99+1010+A pretty-printer is provided as well.
···11+22+let string_fold f acc str =
33+ let st = ref acc in
44+ String.iter (fun c -> st := f !st c) str;
55+ !st
66+77+let is_space = function
88+ | ' ' | '\n' | '\r' | '\t' -> true
99+ | _ -> false
1010+1111+let digit = function
1212+ | '0'..'9' as c -> int_of_char c - 0x30
1313+ | 'A'..'F' as c -> int_of_char c - 0x41 + 10
1414+ | 'a'..'f' as c -> int_of_char c - 0x61 + 10
1515+ | _ -> invalid_arg "bad character"
1616+1717+let required_length ?(skip_whitespace = true) src =
1818+ let req =
1919+ string_fold (fun r c ->
2020+ if skip_whitespace && is_space c then
2121+ r
2222+ else (
2323+ ignore (digit c);
2424+ succ r))
2525+ 0 src
2626+ in
2727+ if req mod 2 = 0 then
2828+ req / 2
2929+ else
3030+ invalid_arg "leftover byte in hex string"
3131+3232+let decode_into ?(skip_whitespace = true) src tgt ?(off = 0) () =
3333+ let fold f acc str =
3434+ let st = ref acc in
3535+ String.iter (fun c -> st := f !st c) str;
3636+ !st
3737+ in
3838+ let chars, leftover =
3939+ fold (fun (chars, leftover) c ->
4040+ if skip_whitespace && is_space c then
4141+ chars, leftover
4242+ else
4343+ let c = digit c in
4444+ match leftover with
4545+ | None -> chars, Some (c lsl 4)
4646+ | Some c' -> (c' lor c) :: chars, None)
4747+ ([], None) src
4848+ in
4949+ let chars = List.rev chars in
5050+ if leftover <> None then
5151+ invalid_arg "leftover byte in hex string";
5252+ List.iteri (fun idx c -> Bytes.set_uint8 tgt (off + idx) c) chars
5353+5454+let decode ?(skip_whitespace = true) src =
5555+ let len = required_length ~skip_whitespace src in
5656+ let buf = Bytes.create len in
5757+ decode_into ~skip_whitespace src buf ();
5858+ Bytes.unsafe_to_string buf
5959+6060+let hex_map = "0123456789abcdef"
6161+6262+let encode_into src tgt ?(off = 0) () =
6363+ String.iteri (fun idx c ->
6464+ let hi, lo =
6565+ let i = int_of_char c in
6666+ hex_map.[i lsr 4], hex_map.[i land 0x0F]
6767+ in
6868+ Bytes.set tgt (idx * 2 + off) hi;
6969+ Bytes.set tgt (idx * 2 + off + 1) lo)
7070+ src
7171+7272+let encode src =
7373+ let buf = Bytes.create (String.length src * 2) in
7474+ encode_into src buf ();
7575+ Bytes.unsafe_to_string buf
7676+7777+let printable_ascii c =
7878+ let i = int_of_char c in
7979+ not (i < 0x20 || i >= 0x7f)
8080+8181+let pp ppf s =
8282+ String.iteri (fun idx c ->
8383+ Format.fprintf ppf "%02x" (int_of_char c);
8484+ if idx mod 2 = 1 then
8585+ Format.pp_print_string ppf " ";
8686+ if idx mod 8 = 7 then
8787+ Format.pp_print_string ppf " ")
8888+ s
8989+9090+let pp_hexdump ?(row_numbers = true) ?(chars = true) () ppf s =
9191+ String.iteri (fun idx c ->
9292+ if idx mod 16 = 0 && row_numbers then
9393+ Format.fprintf ppf "%06x " idx;
9494+ Format.fprintf ppf "%02x" (int_of_char c);
9595+ if idx mod 2 = 1 then
9696+ Format.pp_print_string ppf " ";
9797+ if idx mod 8 = 7 then
9898+ Format.pp_print_string ppf " ";
9999+ if idx mod 16 = 15 && chars then
100100+ String.iter (fun c ->
101101+ Format.pp_print_char ppf (if printable_ascii c then c else '.'))
102102+ (String.sub s (idx - 15) 16);
103103+ if idx mod 16 = 15 then
104104+ Format.pp_print_string ppf "\n")
105105+ s;
106106+ (if chars then
107107+ let last_n, pad =
108108+ let l = String.length s in
109109+ let pad = 16 - (l mod 16) in
110110+ let pad = if pad = 16 then 0 else pad in
111111+ String.sub s (l - (l mod 16)) (l mod 16),
112112+ pad
113113+ in
114114+ if pad > 0 then
115115+ let pad_chars = pad * 2 + (pad + 1) / 2 + (if pad > 8 then 1 else 0) + 1 in
116116+ Format.pp_print_string ppf (String.make pad_chars ' ');
117117+ String.iter (fun c ->
118118+ Format.pp_print_char ppf (if printable_ascii c then c else '.'))
119119+ last_n);
120120+ if String.length s mod 16 <> 0 then
121121+ Format.pp_print_string ppf "\n"
+54
vendor/opam/ohex/ohex.mli
···11+(** Convert from and to hexadecimal representation. *)
22+33+val required_length : ?skip_whitespace:bool -> string -> int
44+(** [required_length ~skip_whitespace s] returns the length needed when the
55+ hex string [s] would be decoded into a sequence of octets. The argument
66+ [skip_whitespace] defaults to [true], and skips any whitespace characters
77+ (' ', '\n', '\r', '\t'). This function is useful for estimating the space
88+ required for [decode_into].
99+1010+ @raise Invalid_argument if any character in [s] is not a hex character, or
1111+ an odd amount of characters are present. *)
1212+1313+val decode : ?skip_whitespace:bool -> string -> string
1414+(** [decode ~skip_whitespace s] decodes a hex string [s] into a sequence of
1515+ octets. The argument [skip_whitespace] defaults to [true], and skips any
1616+ whitespace characters in [s] (' ', '\n', '\r', '\t'). An example:
1717+ [decode "4142" = "AB"].
1818+1919+ @raise Invalid_argument if any character in [s] is not a hex character, or
2020+ an odd amount of characters are present. *)
2121+2222+val decode_into : ?skip_whitespace:bool -> string -> bytes -> ?off:int -> unit
2323+ -> unit
2424+(** [decode_into ~skip_whitespace s dst ~off ()] decodes [s] into [dst]
2525+ starting at [off] (defaults to 0). The argument [skip_whitespace] defaults
2626+ to [true] and skips any whitespace characters.
2727+2828+ @raise Invalid_argument if any character in [s] is not a hex character, an
2929+ odd amount of characters are present, or [dst] does not contain enough
3030+ space. *)
3131+3232+val encode : string -> string
3333+(** [encode s] encodes [s] into a freshly allocated string of double size, where
3434+ each character in [s] is encoded as two hex digits in the returned string.
3535+ An example: [encode "AB" = "4142"].
3636+*)
3737+3838+val encode_into : string -> bytes -> ?off:int -> unit -> unit
3939+(** [encode_into s dst ~off ()] encodes [s] into [dst] starting at [off]
4040+ (defaults to 0). Each character is encoded as two hex digits in [dst].
4141+4242+ @raise Invalid_argument if [dst] does not contain enough space. *)
4343+4444+val pp : Format.formatter -> string -> unit
4545+(** [pp ppf s] pretty-prints the string [s] in hexadecimal. Some spaces are
4646+ emitted for easier readability. No newline is emitted. *)
4747+4848+val pp_hexdump : ?row_numbers:bool -> ?chars:bool -> unit ->
4949+ Format.formatter -> string -> unit
5050+(** [pp_hexdump ~row_numbers ~chars () ppf s] pretty-prints the string [s] in
5151+ hexadecimal (similar to [hexdump -C]). If [row_numbers] is provided
5252+ (defaults to [true]), each output line is prefixed with the row number.
5353+ If [chars] is provided (defaults to [true]), in the last column the ASCII
5454+ string is printed (non-printable characters are printed as '.'). *)