Permalink
Newer
Older
100644 121 lines (91 sloc) 3.62 KB
1
(*
2
Copyright © 2011 MLstate
3
4
This file is part of OPA.
5
6
OPA is free software: you can redistribute it and/or modify it under the
7
terms of the GNU Affero General Public License, version 3, as published by
8
the Free Software Foundation.
9
10
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
11
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
13
more details.
14
15
You should have received a copy of the GNU Affero General Public License
16
along with OPA. If not, see <http://www.gnu.org/licenses/>.
17
*)
18
19
(* Simple library, like Buffer but fixed size but can also look like String if required *)
20
21
type buf = { mutable str : string; mutable i : int }
22
type t = buf
23
24
let empty = { str=""; i=0; }
25
26
let create size = { str=String.create size; i=0; }
27
28
let make size ch = { str=String.make size ch; i=size; }
29
30
let resize buf size =
31
let str = String.create size in
32
let newlen = min buf.i (String.length str) in
33
if buf.i > 0 then String.unsafe_blit buf.str 0 str 0 newlen;
34
buf.str <- str;
35
buf.i <- newlen
36
37
let clear buf = buf.i <- 0
38
39
let reset buf = buf.str <- ""; buf.i <- 0
40
41
let length buf = buf.i
42
43
let real_length buf = String.length buf.str
44
45
let get buf i =
46
if i < 0 || i >= buf.i then invalid_arg (Printf.sprintf "Buf.get index out of bounds %d" i);
47
String.get buf.str i
48
let nth = get
49
50
let unsafe_get buf i = String.unsafe_get buf.str i
51
52
let set buf i ch =
53
if i < 0 || i >= buf.i then invalid_arg (Printf.sprintf "Buf.set index out of bounds %d" i);
54
String.set buf.str i ch
55
56
let unsafe_set buf i ch = String.unsafe_set buf.str i ch
57
58
let sub buf base len =
59
if base < 0 || base + len > buf.i then invalid_arg (Printf.sprintf "Buf.sub index out of bounds %d %d" base len);
60
String.sub buf.str base len
61
62
let add_char buf ch =
63
if String.length buf.str - buf.i < 1 then invalid_arg (Printf.sprintf "Buf.add_char %c" ch);
64
buf.str.[buf.i] <- ch;
65
buf.i <- buf.i + 1
66
67
let add_substring buf str base len =
68
if String.length buf.str - buf.i < len then invalid_arg (Printf.sprintf "Buf.add_substring %s %d %d" str base len);
69
String.unsafe_blit str base buf.str buf.i len;
70
buf.i <- buf.i + len
71
72
let append buf str len = add_substring buf str 0 len
73
74
let extend buf len =
75
if String.length buf.str - buf.i < len then invalid_arg (Printf.sprintf "Buf.extend %d" len);
76
buf.i <- buf.i + len
77
78
let add_string buf str =
79
append buf str (String.length str)
80
81
let add_buf buf1 buf2 =
82
append buf1 buf2.str buf2.i
83
84
let of_string str = { str; i=String.length str; }
85
86
let to_string buf = String.sub buf.str 0 buf.i
87
let contents = to_string
88
89
let spare buf = String.length buf.str - buf.i
90
91
(* Test code *)
92
(*
93
let buf = of_string "abc";;
94
let () = set buf 1 'B';;
95
let ch = get buf 0;;
96
let ch = get buf 1;;
97
let ch = get buf 2;;
98
let str = try ignore (get buf 3); "NOT OK" with Invalid_argument str -> "OK: "^str;;
99
let str = try ignore (set buf 4 'x'); "NOT OK" with Invalid_argument str -> "OK: "^str;;
100
let buf = create 5;;
101
let () = add_char buf 'D';;
102
let () = add_string buf "ef";;
103
let len = length buf;;
104
let rlen = real_length buf;;
105
let str = to_string buf;;
106
let () = resize buf 8;;
107
let len = length buf;;
108
let rlen = real_length buf;;
109
let str = to_string buf;;
110
let () = resize buf 2;;
111
let len = length buf;;
112
let rlen = real_length buf;;
113
let str = to_string buf;;
114
let str = try ignore (add_char empty 'x'); "NOT OK" with Invalid_argument str -> "OK: "^str;;
115
let () = resize buf 10;;
116
let () = add_string buf "fghi";;
117
let str = to_string buf;;
118
let str = sub buf 1 3;;
119
let str = try ignore (sub buf 100 100); "NOT OK" with Invalid_argument str -> "OK: "^str;;
120
*)