aboutsummaryrefslogtreecommitdiff
path: root/lib/jid.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jid.ml')
-rw-r--r--lib/jid.ml39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/jid.ml b/lib/jid.ml
index 19759eb..33c9a9d 100644
--- a/lib/jid.ml
+++ b/lib/jid.ml
@@ -3,3 +3,42 @@ type t = {
domainpart : string;
resourcepart : string option;
}
+
+exception InvalidUTF8
+
+let of_string (jid : string) : t =
+ let open Uchar in
+ let len = String.length jid in
+ let rec to_localpart i =
+ if i <= 0 then
+ None
+ else
+ let c = String.get_utf_8_uchar jid i in
+ if not (utf_decode_is_valid c)
+ then raise InvalidUTF8
+ else
+ let k = utf_decode_length c in
+ match utf_decode_uchar c |> to_char with
+ | '@' -> Some (i + 1)
+ | _ -> to_localpart (i - k)
+ and to_resourcepart i =
+ if i >= len then
+ None
+ else
+ let c = String.get_utf_8_uchar jid i in
+ if not (utf_decode_is_valid c)
+ then raise InvalidUTF8
+ else
+ let k = utf_decode_length c in
+ match utf_decode_uchar c |> to_char with
+ | '/' -> Some i
+ | _ -> to_resourcepart (i + k)
+ in let r = to_resourcepart 0 in
+ let rv = Option.value ~default:len r in
+ let l = to_localpart (rv-1) in
+ let lv = Option.value ~default:0 l in
+ {
+ localpart = Option.map (fun i -> String.sub jid 0 (i-1)) l;
+ resourcepart = Option.map (fun i -> String.sub jid (i+1) (len-i-1)) r;
+ domainpart = String.sub jid lv (rv-lv);
+ }