From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id 687A6BC6B for ; Thu, 11 Oct 2007 16:48:22 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAALzUDUfLENaMn2dsb2JhbACOSgEBAQEHBAYJIA X-IronPort-AV: E=Sophos;i="4.21,260,1188770400"; d="scan'208";a="2874876" Received: from ipmail01.adl2.internode.on.net ([203.16.214.140]) by mail2-smtp-roc.national.inria.fr with ESMTP; 11 Oct 2007 16:48:21 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAI7TDUd5LCRs/2dsb2JhbAAM X-IronPort-AV: E=Sophos;i="4.21,260,1188743400"; d="scan'208";a="208474169" Received: from ppp121-44-36-108.lns10.syd7.internode.on.net (HELO [192.168.1.201]) ([121.44.36.108]) by ipmail01.adl2.internode.on.net with ESMTP; 12 Oct 2007 00:18:18 +0930 Subject: Re: [Caml-list] Re: Rope is the new string From: skaller To: Vincent Hanquez Cc: caml-list@yquem.inria.fr, Chris King In-Reply-To: <20071011142141.GA8001@snarc.org> References: <20071009.122004.251675959.Christophe.Troestler+ocaml@umh.ac.be> <200710091440.48381.jon@ffconsultancy.com> <20071009155702.GB26282@snarc.org> <6f9f8f4a0710090942u2afe6c5erc2d5b11ecfff2253@mail.gmail.com> <20071009165520.GA27507@snarc.org> <6f9f8f4a0710091032r3dace80bi4f9b584ae5056675@mail.gmail.com> <20071009195119.GA29263@snarc.org> <875c7e070710091504j203ff78y8703fc5c22086671@mail.gmail.com> <20071011130354.GA7016@snarc.org> <1192110864.6045.12.camel@rosella.wigram> <20071011142141.GA8001@snarc.org> Content-Type: text/plain Date: Fri, 12 Oct 2007 00:48:16 +1000 Message-Id: <1192114097.6184.7.camel@rosella.wigram> Mime-Version: 1.0 X-Mailer: Evolution 2.10.1 Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; 0200,:01 camomile:01 camomile:01 integers:01 unspecified:01 ord:01 failwith:01 ord:01 sourceforge:01 char:01 char:01 wrote:01 wrote:01 integer:01 caml-list:01 On Thu, 2007-10-11 at 16:21 +0200, Vincent Hanquez wrote: > On Thu, Oct 11, 2007 at 11:54:24PM +1000, skaller wrote: > > You can't: Camomile is massive for a reason.. the problem it > > aims to solve is complex and hard to do efficiently without > > a large set of specialised functions. > > You are assuming that i want efficiency where i want to print few > unicode string in an ui here and there. I *DON'T* want to be exposed to > full unicode, i need something like 1/100 of camomile library. In that case, you can use an int Array.t for Unicode provided it is only 31 bit OR you have a 64 bit machine. These routines should help converting to and from UTF-8: (* parse the first utf8 encoded character of a string s starting at index position i, return a pair consisting of the decoded integers, and the position of the first character not decoded. If the first character is bad, it is returned, otherwise if the encoding is bad, the result is an unspecified value. Fails if the index is past or at the end of the string. COMPATIBILITY NOTE: if this function is called with a SINGLE character string, it will return the usual value for the character, in range 0 .. 255 *) let parse_utf8 (s : string) (i : int) : int * int = let ord = int_of_char and n = (String.length s) - i in if n <= 0 then failwith ( "parse_utf8: index "^ string_of_int i^ " >= "^string_of_int (String.length s)^ " = length of '" ^ s ^ "'" ) else let lead = ord (s.[i]) in if (lead land 0x80) = 0 then lead land 0x7F,i+1 (* ASCII *) else if lead land 0xE0 = 0xC0 && n > 1 then ((lead land 0x1F) lsl 6) lor (ord(s.[i+1]) land 0x3F),i+2 else if lead land 0xF0 = 0xE0 && n > 2 then ((lead land 0x1F) lsl 12) lor ((ord(s.[i+1]) land 0x3F) lsl 6) lor (ord(s.[i+2]) land 0x3F),i+3 else if lead land 0xF8 = 0xF0 && n > 3 then ((lead land 0x1F) lsl 18) lor ((ord(s.[i+1]) land 0x3F) lsl 12) lor ((ord(s.[i+2]) land 0x3F) lsl 6) lor (ord(s.[i+3]) land 0x3F),i+4 else if lead land 0xFC = 0xF8 && n > 4 then ((lead land 0x1F) lsl 24) lor ((ord(s.[i+1]) land 0x3F) lsl 18) lor ((ord(s.[i+2]) land 0x3F) lsl 12) lor ((ord(s.[i+3]) land 0x3F) lsl 6) lor (ord(s.[i+4]) land 0x3F),i+5 else if lead land 0xFE = 0xFC && n > 5 then ((lead land 0x1F) lsl 30) lor ((ord(s.[i+1]) land 0x3F) lsl 24) lor ((ord(s.[i+2]) land 0x3F) lsl 18) lor ((ord(s.[i+3]) land 0x3F) lsl 12) lor ((ord(s.[i+4]) land 0x3F) lsl 6) lor (ord(s.[i+5]) land 0x3F),i+6 else lead, i+1 (* error, just use bad character *) (* convert an integer into a utf-8 encoded string of bytes *) let utf8_of_int i = let chr x = String.make 1 (Char.chr x) in if i < 0x80 then chr(i) else if i < 0x800 then chr(0xC0 lor ((i lsr 6) land 0x1F)) ^ chr(0x80 lor (i land 0x3F)) else if i < 0x10000 then chr(0xE0 lor ((i lsr 12) land 0xF)) ^ chr(0x80 lor ((i lsr 6) land 0x3F)) ^ chr(0x80 lor (i land 0x3F)) else if i < 0x200000 then chr(0xF0 lor ((i lsr 18) land 0x7)) ^ chr(0x80 lor ((i lsr 12) land 0x3F)) ^ chr(0x80 lor ((i lsr 6) land 0x3F)) ^ chr(0x80 lor (i land 0x3F)) else if i < 0x4000000 then chr(0xF8 lor ((i lsr 24) land 0x3)) ^ chr(0x80 lor ((i lsr 18) land 0x3F)) ^ chr(0x80 lor ((i lsr 12) land 0x3F)) ^ chr(0x80 lor ((i lsr 6) land 0x3F)) ^ chr(0x80 lor (i land 0x3F)) else chr(0xFC lor ((i lsr 30) land 0x1)) ^ chr(0x80 lor ((i lsr 24) land 0x3F)) ^ chr(0x80 lor ((i lsr 18) land 0x3F)) ^ chr(0x80 lor ((i lsr 12) land 0x3F)) ^ chr(0x80 lor ((i lsr 6) land 0x3F)) ^ chr(0x80 lor (i land 0x3F)) -- John Skaller Felix, successor to C++: http://felix.sf.net