package slice

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file slice_bytes.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(*
 * Copyright (c) 2024 Romain Calascibetta <romain.calascibetta@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESBytes_labels. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *)

type t = Bytes_labels.t Slice.t

external ( < ) : 'a -> 'a -> bool = "%lessthan"
external ( <= ) : 'a -> 'a -> bool = "%lessequal"
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
external ( > ) : 'a -> 'a -> bool = "%greaterthan"

let ( > ) (x : int) y = x > y [@@inline]
let ( < ) (x : int) y = x < y [@@inline]
let ( <= ) (x : int) y = x <= y [@@inline]
let ( >= ) (x : int) y = x >= y [@@inline]
let min (a : int) b = if a <= b then a else b [@@inline]
let max (a : int) b = if a >= b then a else b [@@inline]

open Slice

let make ?(off= 0) ?len buf =
  let len = match len with
    | Some len -> len
    | None -> Bytes_labels.length buf - off in
  if len < 0
  || off < 0
  || off > Bytes_labels.length buf - len
  then invalid_arg "Slice.make";
  Slice.unsafe_make ~off ~len buf

let empty = unsafe_make ~off:0 ~len:0 Bytes_labels.empty
let length { len; _ } = len
let get { off; buf; _ } idx = Bytes_labels.get buf (off + idx)
let get_int8 { off; buf; _ } idx = Bytes_labels.get_int8 buf (off + idx)
let get_uint8 { off; buf; _ } idx = Bytes_labels.get_uint8 buf (off + idx)
let get_uint16_ne { off; buf; _ } idx = Bytes_labels.get_uint16_ne buf (off + idx)
let get_uint16_le { off; buf; _ } idx = Bytes_labels.get_uint16_le buf (off + idx)
let get_uint16_be { off; buf; _ } idx = Bytes_labels.get_uint16_be buf (off + idx)
let get_int16_ne { off; buf; _ } idx = Bytes_labels.get_int16_ne buf (off + idx)
let get_int16_le { off; buf; _ } idx = Bytes_labels.get_int16_ne buf (off + idx)
let get_int16_be { off; buf; _ } idx = Bytes_labels.get_int16_be buf (off + idx)
let get_int32_ne { off; buf; _ } idx = Bytes_labels.get_int32_ne buf (off + idx)
let get_int32_le { off; buf; _ } idx = Bytes_labels.get_int32_le buf (off + idx)
let get_int32_be { off; buf; _ } idx = Bytes_labels.get_int32_be buf (off + idx)
let get_int64_ne { off; buf; _ } idx = Bytes_labels.get_int64_ne buf (off + idx)
let get_int64_le { off; buf; _ } idx = Bytes_labels.get_int64_le buf (off + idx)
let get_int64_be { off; buf; _ } idx = Bytes_labels.get_int64_be buf (off + idx)
let set { off; buf; _ } idx v = Bytes_labels.set buf (off + idx) v
let set_int8 { off; buf; _ } idx v = Bytes_labels.set_int8 buf (off + idx) v
let set_uint8 { off; buf; _ } idx v = Bytes_labels.set_uint8 buf (off + idx) v
let set_uint16_ne { off; buf; _ } idx v = Bytes_labels.set_uint16_ne buf (off + idx) v
let set_uint16_le { off; buf; _ } idx v = Bytes_labels.set_uint16_le buf (off + idx) v
let set_uint16_be { off; buf; _ } idx v = Bytes_labels.set_uint16_be buf (off + idx) v
let set_int16_ne { off; buf; _ } idx v = Bytes_labels.set_int16_ne buf (off + idx) v
let set_int16_le { off; buf; _ } idx v = Bytes_labels.set_int16_ne buf (off + idx) v
let set_int16_be { off; buf; _ } idx v = Bytes_labels.set_int16_be buf (off + idx) v
let set_int32_ne { off; buf; _ } idx v = Bytes_labels.set_int32_ne buf (off + idx) v
let set_int32_le { off; buf; _ } idx v = Bytes_labels.set_int32_le buf (off + idx) v
let set_int32_be { off; buf; _ } idx v = Bytes_labels.set_int32_be buf (off + idx) v
let set_int64_ne { off; buf; _ } idx v = Bytes_labels.set_int64_ne buf (off + idx) v
let set_int64_le { off; buf; _ } idx v = Bytes_labels.set_int64_le buf (off + idx) v
let set_int64_be { off; buf; _ } idx v = Bytes_labels.set_int64_be buf (off + idx) v

let blit a b =
  let len = Int.min a.len b.len in
  Bytes_labels.blit a.buf ~src_off:a.off b.buf ~dst_off:b.off ~len:len

let blit_from_bytes src ~src_off { Slice.buf; off; _ } ?dst_off len =
  let dst_off = match dst_off with
    | Some dst_off -> dst_off + off
    | None -> off in
  if len < 0
  || dst_off < 0
  || dst_off > Bytes_labels.length buf - len
  then invalid_arg "Slice.blit_from_bytes";
  Bytes_labels.blit_from_bytes src ~src_off buf ~dst_off ~len

let blit_to_bytes { Slice.buf; off; _ } ?src_off dst ~dst_off ~len =
  let src_off = match src_off with
    | Some src_off -> src_off + off
    | None -> off in
  if len < 0
  || src_off < 0
  || src_off > Bytes_labels.length buf - len
  then invalid_arg "Slice.blit_to_bytes";
  Bytes_labels.blit_to_bytes buf ~src_off dst ~dst_off ~len

let fill { off; len; buf; } ?off:(off'= 0) ?len:len' chr =
  let len' = match len' with
    | Some len' -> len'
    | None -> len - off' in
  Bytes_labels.fill buf ~off:(off + off') ~len:len' chr

let sub t ~off ~len = Slice.sub t ~off ~len
let shift t n = Slice.shift t n
let is_empty t = Slice.is_empty t

let sub_string { Slice.buf; off; _ } ~off:off' ~len =
  let dst = Bytes.create len in
  Bytes_labels.blit_to_bytes buf ~src_off:(off + off') dst ~dst_off:0 ~len;
  Bytes.unsafe_to_string dst

let to_string { Slice.buf; off= src_off; len } =
  let dst = Bytes.create len in
  Bytes_labels.blit_to_bytes buf ~src_off dst ~dst_off:0 ~len;
  Bytes.unsafe_to_string dst

let of_string str =
  let off = 0 and len = String.length str in
  Slice.unsafe_make ~off ~len (Bytes_labels.of_string str)

let string ?(off= 0) ?len str =
  let len = match len with 
    | None -> String.length str - off 
    | Some len -> len in
  Slice.unsafe_make ~off:0 ~len (Bytes_labels.string ~off ~len str)

let overlap ({ buf= buf0; _ } as a) ({ buf= buf1; _ } as b) =
  match Bytes_labels.overlap buf0 buf1 with
  | None -> None
  | Some (_, 0, 0) ->
      let len =
        max 0 (min (a.off + a.len) (b.off + b.len)) - max a.off b.off in
      if a.off >= b.off && a.off < b.off + b.len
      then
        let offset = a.off - b.off in Some (len, 0, offset)
      else if b.off >= a.off && b.off < a.off + a.len
      then
        let offset = b.off + a.off in Some (len, offset, 0)
      else None
  | Some _ ->
      let a = Bytes_labels.sub buf0 ~off:a.off ~len:a.len
      and b = Bytes_labels.sub buf1 ~off:b.off ~len:b.len in
      Bytes_labels.overlap a b
      (* TODO(dinosaure): this case appears only for bigstrings, but we could
         optimize it and avoid [Bytes_labels.sub]. *)
OCaml

Innovation. Community. Security.