package ocaml-protoc-plugin

  1. Overview
  2. Docs

Source file littleEndian.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
module type Integer = sig
  type t
  val zero: t
  val logand: t -> t -> t
  val of_int: int -> t
  val to_int: t -> int
  val shift_right_logical: t -> int -> t
  val shift_left: t -> int -> t
  val add: t -> t -> t
end

(** For Little-endian platform *)
module LittleEndian = struct
  let set_int (type t) (module T: Integer with type t = t) size buffer offset v =
    let open T in
    let rec inner acc = function
      | n when n = size -> ()
      | n ->
        let ch = logand acc (of_int 0xff) |> to_int |> Char.chr in
        Bytes.set buffer (n + offset) ch;
        inner (shift_right_logical acc 8) (n+1)
    in
    inner v 0

  let get_int (type t) (module T: Integer with type t = t) size buffer offset =
    let open T in
    let rec inner acc = function
      | 0 -> acc
      | n ->
        let v = String.get buffer (offset + n - 1) |> Char.code in
        let acc = add (shift_left acc 8) (of_int v) in
        inner acc (n - 1)
    in
    inner T.zero size

  let get_int64 = get_int (module Int64) 8
  let get_int32 = get_int (module Int32) 4
  let set_int64 = set_int (module Int64) 8
  let set_int32 = set_int (module Int32) 4

end

(** For Bigendian platform *)
module BigEndian = struct
  let set_int (type t) (module T: Integer with type t = t) size buffer offset v =
    let open T in
    let rec inner acc = function
      | n when n = size -> ()
      | n ->
        let ch = logand acc (of_int 0xff) |> to_int |> Char.chr in
        Bytes.set buffer ((size - n - 1) + offset) ch;
        inner (shift_right_logical acc 8) (n+1)
    in
    inner v 0

  let get_int (type t) (module T: Integer with type t = t) size buffer offset =
    let open T in
    let rec inner acc = function
      | 0 -> acc
      | n ->
        let v = String.get buffer (offset + size - n) |> Char.code in
        let acc = add (shift_left acc 8) (of_int v) in
        inner acc (n - 1)
    in
    inner T.zero size

  let get_int64 = get_int (module Int64) 8
  let get_int32 = get_int (module Int32) 4
  let set_int64 = set_int (module Int64) 8
  let set_int32 = set_int (module Int32) 4

end

let get_int64 = match Sys.big_endian with true -> BigEndian.get_int64 | false -> LittleEndian.get_int64
let get_int32 = match Sys.big_endian with true -> BigEndian.get_int32 | false -> LittleEndian.get_int32
let set_int64 = match Sys.big_endian with true -> BigEndian.set_int64 | false -> LittleEndian.set_int64
let set_int32 = match Sys.big_endian with true -> BigEndian.set_int32 | false -> LittleEndian.set_int32


module Test = struct
  let test _ =
    let (_:bool) =
      let buffer = Bytes.create 8 in
      let v = 1234567876543L in
      set_int64 buffer 0 v;
      get_int64 (Bytes.to_string buffer) 0 = v || failwith "int64"
    in
    let (_:bool) =
      let buffer = Bytes.create 4 in
      let v = 12345673l in
      set_int32 buffer 0 v;
      get_int32 (Bytes.to_string buffer) 0 = v || failwith "int32"
    in
    ()
end
OCaml

Innovation. Community. Security.