forked from ermine/sulci
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.ml
161 lines (144 loc) · 3.71 KB
/
common.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
149
150
151
152
153
154
155
156
157
158
159
160
161
(*
* (c) 2004-2010 Anastasia Gornostaeva
*)
let string_after s n =
if n = 0 then
s
else if String.length s = n then
""
else
String.sub s n (String.length s - n)
let is_prefix s1 s2 =
let len1 = String.length s1 in
let len2 = String.length s2 in
if len1 > len2 then
false
else
let rec aux_compare i =
if i < len1 then
if s1.[i] = s2.[i] then
aux_compare (succ i)
else
false
else
true
in
aux_compare 0
let skip_ws str i =
if str = "" then str
else
let rec cycle i =
if i < String.length str then
if List.mem str.[i] [' '; '\n'; '\r'; '\t'] then cycle (succ i)
else if i > 0 then string_after str i
else str
else
""
in
cycle i
let rskip_ws str =
if str = "" then str
else
let rec cycle i =
if i = -1 then ""
else
if List.mem str.[i] [' '; '\n'; '\t'; '\r'] then cycle (pred i)
else String.sub str 0 (i+1)
in
cycle (pred (String.length str))
let trim str =
let r1 = skip_ws str 0 in
rskip_ws r1
exception InvalidUTF8
let length_utf8 text =
let rec aux_sub i j =
if i < String.length text then
match text.[i] with
| '\000' .. '\127' ->
aux_sub (succ i) (succ j)
| '\193' .. '\223' ->
aux_sub (i+2) (succ j)
| '\224' .. '\239' ->
aux_sub (i+3) (succ j)
| '\240' .. '\248' ->
aux_sub (i+4) (succ j)
| _ -> raise InvalidUTF8
else
j
in
aux_sub 0 0
let sub_utf8_string text count =
let len = String.length text in
let rec aux_sub i l =
if l = count then
String.sub text 0 i
else if i < len then
match text.[i] with
| '\000' .. '\127' ->
aux_sub (i+1) (l+1)
| '\193' .. '\223' ->
aux_sub (i+2) (l+1)
| '\224' .. '\239' ->
aux_sub (i+3) (l+1)
| '\240' .. '\248' ->
aux_sub (i+4) (l+1)
| _ -> raise InvalidUTF8
else
text
in
aux_sub 0 0
let sub_utf8 text length =
let rec aux_sub i j =
if i < 0 then
0
else
match text.[i] with
| '\000' .. '\127' -> i
| '\193' .. '\223' ->
if j = 1 then i else aux_sub (i-1) 0
| '\224' .. '\239' ->
if j = 2 then i else aux_sub (i-1) 0
| '\240' .. '\248' ->
if j = 3 then i else aux_sub (i-1) 0
| _ ->
aux_sub (i-1) (j+1)
in
if String.length text <= length then
text
else
let len = aux_sub (length - 1) 0 in
if len > 0 then String.sub text 0 len else ""
let clean_tail str =
if str = "" then str
else
let rec cycle i =
if i = -1 then str
else
if Char.code str.[i] < 128 &&
List.mem str.[i] [' '; '\n'; '\t'; '\r'; ','; '.'; ':'; ';'] then
String.sub str 0 (i+1)
else
cycle (pred i)
in
cycle (pred (String.length str))
let split_long_message limit msg tail =
let rec aux_split acc rest =
if String.length rest <= limit then
if String.length rest + String.length tail <= limit then
List.rev ((rest ^ tail) :: acc)
else
List.rev (tail :: rest :: acc)
else
let part = sub_utf8 rest limit in
let cleaned = clean_tail part in
let new_tail = string_after rest (String.length cleaned) in
aux_split (cleaned :: acc) new_tail
in
aux_split [] msg
exception Error
(* temp code *)
exception DNSPrepError
let dnsprep str =
if String.contains str '.' then ()
else raise DNSPrepError
let opt_try f x = try Some (f x) with Not_found -> None