123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115(*
* oBus_string.ml
* --------------
* Copyright : (c) 2008, Jeremie Dimino <jeremie@dimino.org>
* Licence : BSD3
*
* This file is a part of obus, an ocaml implementation of D-Bus.
*)typet=stringtypeerror={typ:string;str:string;ofs:int;msg:string;}lettype=e.typletstre=e.strletofse=e.ofsletmsge=e.msgtypevalidator=string->erroroptionexceptionInvalid_stringoferrorleterror_messageerror=iferror.ofs<0thenPrintf.sprintf"invalid D-Bus %s (%S): %s"error.typerror.strerror.msgelsePrintf.sprintf"invalid D-Bus %s (%S), at position %d: %s"error.typerror.strerror.ofserror.msglet()=Printexc.register_printer(function|Invalid_stringerror->Some(error_messageerror)|_->None)let()=Printexc.register_printer(function|Invalid_stringerror->Some(error_messageerror)|_->None)letvalidates=letfailimsg=Some{typ="string";str=s;ofs=i;msg=msg}inletlen=String.lengthsinletrecmaini=ifi=lenthenNoneelseletch=String.unsafe_getsiinmatchchwith|'\x00'->faili"null byte"|'\x01'..'\x7f'->main(i+1)|'\xc0'..'\xdf'->ifi+1>=lenthenfaillen"premature end of UTF8 sequence"elsebeginletbyte1=Char.code(String.unsafe_gets(i+1))inifbyte1land0xc0!=0x80thenfail(i+1)"malformed UTF8 sequence"elseif((Char.codechland0x1f)lsl6)lor(byte1land0x3f)<0x80thenfaili"overlong UTF8 sequence"elsemain(i+2)end|'\xe0'..'\xef'->ifi+2>=lenthenfaillen"premature end of UTF8 sequence"elsebeginletbyte1=Char.code(String.unsafe_gets(i+1))andbyte2=Char.code(String.unsafe_gets(i+2))inifbyte1land0xc0!=0x80thenfail(i+1)"malformed UTF8 sequence"elseifbyte2land0xc0!=0x80thenfail(i+2)"malformed UTF8 sequence"elseif((Char.codechland0x0f)lsl12)lor((byte1land0x3f)lsl6)lor(byte2land0x3f)<0x800thenfaili"overlong UTF8 sequence"elsemain(i+3)end|'\xf0'..'\xf7'->ifi+3>=lenthenfaillen"premature end of UTF8 sequence"elsebeginletbyte1=Char.code(String.unsafe_gets(i+1))andbyte2=Char.code(String.unsafe_gets(i+2))andbyte3=Char.code(String.unsafe_gets(i+3))inifbyte1land0xc0!=0x80thenfail(i+1)"malformed UTF8 sequence"elseifbyte2land0xc0!=0x80thenfail(i+2)"malformed UTF8 sequence"elseifbyte3land0xc0!=0x80thenfail(i+3)"malformed UTF8 sequence"elseif((Char.codechland0x0f)lsl18)lor((byte1land0x3f)lsl12)lor((byte2land0x3f)lsl6)lor(byte3land0x3f)<0x10000thenfaili"overlong UTF8 sequence"elsemain(i+4)end|_->faili"invalid start of UTF8 sequence"inmain0letassert_validatevalidatorstr=matchvalidatorstrwith|Someerror->raise(Invalid_stringerror)|None->()