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
type inner_buffer = {buffer: Bstr.t; length: int}
type t = {
mutable inner: inner_buffer;
mutable position: int;
initial_buffer: Bstr.t;
}
let create n =
let n = if n < 1 then 1 else n in
let n = if n > Sys.max_string_length then Sys.max_string_length else n in
let s = Bstr.create n in
{inner= {buffer= s; length= n}; position= 0; initial_buffer= s}
let resize b more =
let old_pos = b.position in
let old_len = b.inner.length in
let new_len = ref old_len in
while old_pos + more > !new_len do
new_len := 2 * !new_len
done;
if !new_len > Sys.max_string_length then begin
if old_pos + more <= Sys.max_string_length then
new_len := Sys.max_string_length
else failwith "Buffer.add: cannot grow buffer"
end;
let new_buffer = Bstr.create !new_len in
Bstr.blit b.inner.buffer ~src_off:0 new_buffer ~dst_off:0 ~len:b.position;
b.inner <- {buffer= new_buffer; length= !new_len}
let add_substring b s offset len =
if offset < 0 || len < 0 || offset > String.length s - len then
invalid_arg "Buffer.add_substring";
let position = b.position in
let {buffer; length} = b.inner in
let new_position = position + len in
if new_position > length then (
resize b len;
Bstr.blit_from_string s ~src_off:offset b.inner.buffer ~dst_off:b.position
~len)
else Bstr.blit_from_string s ~src_off:offset buffer ~dst_off:position ~len;
b.position <- new_position
let add_string b str = add_substring b str 0 (String.length str)
let sub b ofs len =
if ofs < 0 || len < 0 || ofs > b.position - len then invalid_arg "Buffer.sub"
else Bstr.sub b.inner.buffer ~off:ofs ~len
let length b = b.position
let blit src srcoff dst dstoff len =
if
len < 0
|| srcoff < 0
|| srcoff > src.position - len
|| dstoff < 0
|| dstoff > Bstr.length dst - len
then invalid_arg "Buffer.blit"
else Bstr.blit src.inner.buffer ~src_off:srcoff dst ~dst_off:dstoff ~len