TTudor BrindusUse OxCaml
11c9f605创建于 2025年12月12日历史提交
open! Core

let intable_of_hex_string
  (type a)
  (module M : Int_intf.S with type t = a)
  ?(remove_hex_prefix = false)
  str
  =
  (* Bit hacks for fast parsing of hex strings.
   *
   * Note that in ASCII, ('1' | 'a' | 'A') & 0xF = 1.
   *
   * So for each character, take the bottom 4 bits, and add 9 if it's
   * not a digit. *)
  let res = ref (M.of_int_exn 0) in
  let fifteen = M.of_int_exn 0xF in
  let eight = M.of_int_exn 0x8 in
  for i = if remove_hex_prefix then 2 else 0 to String.length str - 1 do
    let open M in
    let c = of_int_exn (Char.to_int (String.unsafe_get str i)) in
    res := (!res lsl 4) lor ((c land fifteen) + ((c lsr 6) lor ((c lsr 3) land eight)))
  done;
  !res
;;

let int64_of_hex_string = intable_of_hex_string (module Int64)
let int_trunc_of_hex_string = intable_of_hex_string (module Int)

module%test _ = struct
  open Core

  let check ?remove_hex_prefix str =
    print_s
      [%message
        ""
          ~int64:(int64_of_hex_string ?remove_hex_prefix str |> sprintf "0x%Lx")
          ~int:(int_trunc_of_hex_string ?remove_hex_prefix str |> sprintf "0x%x")]
  ;;

  let%expect_test "int64 hex parsing" =
    check ~remove_hex_prefix:true "0x7f9db48c1d80";
    [%expect {|
        ((int64 0x7f9db48c1d80) (int 0x7f9db48c1d80)) |}];
    check "7f9db48c1d80";
    [%expect {|
        ((int64 0x7f9db48c1d80) (int 0x7f9db48c1d80)) |}];
    check "fF";
    [%expect {|
        ((int64 0xff) (int 0xff)) |}];
    check "f0f";
    [%expect {|
        ((int64 0xf0f) (int 0xf0f)) |}];
    check "fA0f";
    [%expect {|
          ((int64 0xfa0f) (int 0xfa0f)) |}];
    check "0";
    [%expect {|
        ((int64 0x0) (int 0x0)) |}];
    (* Test a value that doesn't fit in a 63-bit int. *)
    check "0xffffffffff22f000";
    [%expect {| ((int64 0xffffffffff22f000) (int 0x7fffffffff22f000)) |}]
  ;;
end

let experimental_flag ~default flag =
  if Env_vars.experimental then flag else Command.Param.return default
;;