rune.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


class RUNE < $CHAR{RUNE}

class RUNE < $CHAR{RUNE} is -- This class implements the notion of a logical character (ie having -- the semantics associated with such a token in the cultural environment -- concerned). It satisfies Level 3 conformance to ISO/IEC 10646-1:1993. -- Version 1.5 Apr 99. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 6 May 96 kh Original from Sather CHAR class -- 11 Nov 96 kh Redesign for portability. -- 5 Apr 97 kh Converted INT to CARD -- 13 Oct 98 kh Revised and added pre/post conditions -- 21 Feb 99 kh Modified to conform to character/code changes -- 9 Apr 99 kh Rewrite for version 8 of text classes. private include AREF{OCTET} create ->, asize -> asize, -- for use in RUNES aelt! -> aelt! ; -- for use in RUNES include COMPARABLE ; include CHAR_STR ; include BINARY ; include CHAR_INCL ; -- The common implementations! private attr priv_lib : CARD ; -- This is the index into the global repertoire list. build( cursor : BIN_CURSOR, lib : LIBCHARS ) : SAME pre ~void(lib) and ~void(cursor) and (cursor.remaining >= lib.my_size) post void(result) or (initial(cursor.remaining) > cursor.remaining) is -- This routine takes the number of octets required to form a single -- rune in the indicated repertoire and encoding. Providing the first -- encoding encountered is non-combining (when void will be returned), -- successive codes are taken from the string until a further non-combining -- encoding is found (which is not taken from the string!) or the end of -- the string is encountered. start_index : CARD := cursor.index ; loc_code : CHAR_CODE := CHAR_CODE::raw_build(cursor,lib) ; if loc_code.is_combining then cursor.set_index(start_index) ; return void end ; loc_res : FLIST{CHAR_CODE} := FLIST{CHAR_CODE}::create ; if (lib.has_combining and UNICODE::is_valid(loc_code.card)) or lib.culture.charmap.valid(loc_code) then loc_res := loc_res.push(loc_code) else cursor.set_index(cursor.index - lib.my_size) ; return void end ; loop -- get combining codes! if cursor.is_done then break! end ; start_index := cursor.index ; loc_code := CHAR_CODE::raw_build(cursor,lib) ; if loc_code.is_combining then loc_res := loc_res.push(loc_code) else cursor.set_index(start_index) ; break! end end ; res : SAME := new(loc_res.size * lib.my_size) ; res.priv_lib := REP_LIB_LIST::index(lib) ; loop code_val : CHAR_CODE := loc_res.elt! ; loop res.aset!(code_val.octet!) end end ; return res end ; build( index : BIN_CURSOR ) : SAME pre (index.remaining >= LIBCHARS::default.my_size) post ~void(result) or (index.remaining < initial(index.remaining)) is -- This routine builds a character from the binary string attached -- to the given cursor in the default repertoire and encoding. return build(index,LIBCHARS::default) end ; create( code : CHAR_CODE ) : SAME pre true post ~void(result) is -- This creates a new rune from the given character code. me : SAME := new(code.lib.my_size) ; me.priv_lib := REP_LIB_LIST::index(code.lib) ; loop index : CARD := 0.upto!(code.lib.my_size - 1) ; me[index] := code.octet! end ; return me end ; create( code : CONTROL_CODES, lib : LIBCHARS ) : SAME pre ~void(lib) post ~void(result) is -- This creates a 'control character' from the given control code! return create(CHAR_CODE::create(code.card,lib)) end ; lib : LIBCHARS is -- This routine returns the repertoire for this rune. return REP_LIB_LIST::lib_list[priv_lib] end ; nil : SAME is -- This routine returns a nil value - which cannot be a valid character. res : SAME := null ; res.priv_lib := CARD::nil ; return res end ; null : SAME is -- This routine returns the character corresponding to the control -- function name NUL. return create(CONTROL_CODES::NUL,LIBCHARS::default) end ; valid( num : CARD, lib : LIBCHARS ) : BOOL pre ~void(lib) post true is -- This routine returns true if and only if the value of num may be -- interpreted as a character bit-pattern valid in the gicen encoding and -- repertoire, otherwise false. return lib.culture.charmap.valid(CHAR_CODE::create(num,lib)) end ; valid( num : CARD ) : BOOL pre ~void(lib) post true is -- This routine returns true if and only if the value of num may be -- interpreted as a character bit-pattern, otherwise false. return valid(num,LIBCHARS::default) end ; copy : SAME pre ~void(self) post result = self is -- This routine returns an exact copy of self. res : SAME := new(asize) ; res.priv_lib := priv_lib ; res.acopy(self) ; return res end ; size : CARD pre ~void(self) post (result > 0) is -- This routine returns the number of codes in self. It is theerefore -- intended for use only within the required library. return asize / lib.my_size end ; num_codes : CARD pre ~void(self) post (result > 1) is -- This routine is a synonym for size above, returning the number of -- individual codes in self. return asize / lib.my_size end ; is_eq( other : SAME ) : BOOL pre ~void(self) and ~void(other) post true is -- This routine returns true if and only if self and other are the same -- rune irrespective of encoding!! return CULTURE::default.collating.same(self,other) end ; is_lt( other : SAME ) : BOOL pre ~void(self) and ~void(other) post true is -- This routine returns true if and only if self is earlier than other -- in the repertoire defined ordering of runes. return CULTURE::default.collating.earlier(self,other) end ; is_nil : BOOL is -- This routine returns true if and only if self is the nil character. return is_eq(nil) end ; plus( code : CHAR_CODE ) : SAME pre ~void(self) and code.is_combining and (code.lib = lib) post true is -- This routine appends code to self if and only if it is a combining -- code, otherwise self is returned unaltered. res : SAME := new(asize + lib.my_size) ; res.priv_lib := priv_lib ; res.acopy(self) ; loop index : CARD := asize.upto!(res.asize - 1) ; res[index] := code.octet!(lib.my_size) end ; return res end ; binstr( lib : LIBCHARS ) : BINSTR pre ~void(self) post (asize = result.size - 1) is -- This routine returns a representation of self as a binary string, -- preceded by the given repertoire and encoding. res : BINSTR := lib.culture.kind.binstr ; loop res := res + aelt! end ; return res end ; binstr : BINSTR pre ~void(self) post (asize = result.size - 1) is -- This routine returns a representation of self as a binary string, -- using the repertoire and encoding of the rune itself. return binstr(lib) end ; convert( to_lib : LIBCHARS ) : SAME pre ~void(lib) and (lib /= LIBCHARS::default) post true is -- This routine converts self to be in the given encoding and repertoire. loc_res : CODE_STR := CODE_STR::create(lib) ; loop loc_res := loc_res + code! end ; tmp_res : RUNES := CODE_CONVERTER::runes(loc_res) ; loc_res := CODE_CONVERTER::codes(to_lib,tmp_res) ; res : SAME ; first : BOOL := true ; loop code : CHAR_CODE := loc_res.elt! ; if first then first := false ; res := create(code) else res := res + code end end ; return res end ; char : CHAR pre ~void(self) post true is -- This routine returns the bit-pattern of self as a character code -- belonging to the default repertoire and encoding. if asize > lib.my_size then return void else return CHAR::create(code) end end ; code( lib : LIBCHARS ) : CHAR_CODE pre ~void(self) and ~void(lib) post true is -- This routine returns the bit-pattern of the first coding in self. -- This is provided solely for compatibility with the required sub-type -- signature. loop return code! end end ; code : CHAR_CODE pre ~void(self) post true is -- This routine returns the bit-pattern of the first coding in self as -- a character code. loop return code! end end ; rune( lib : LIBCHARS ) : RUNE pre ~void(self) and ~void(lib) post true is -- This routine returns a simple copy of self. This does not -- use the parameter given, since it is provided solely for compatibility -- with the class interface. return copy end ; rune : RUNE pre ~void(self) post true is -- This routine returns a simple copy of self. return copy end ; hash : CARD pre ~void(self) post true is -- This routine returns a hash value of the encoding for the purposes of -- mapping etc. return binstr.hash end ; upper( dummy_lib : LIBCHARS ) : SAME pre ~void(self) and ~void(lib) and self.is_lower(lib) post result.is_upper(lib) is -- Providing that there exists an upper case version of self then -- an encoding giving that character is returned, otherwise the current -- value of self. Note that the parameter is unused in this version. res : SAME ; first : BOOL := true ; loop loc_code : CHAR_CODE := code! ; if first then first := false ; res := CHAR_CODE::create(CHAR_MAPPINGS::To_Upper.to_range( loc_code.char,lib.culture),lib).rune else res := res + loc_code end end ; return res end ; upper : SAME pre ~void(self) and self.is_lower post result.is_upper is -- Providing that there exists an upper case version of self then -- an encoding giving that character is returned, otherwise the current -- value of self. return upper(LIBCHARS::default) end ; lower( lib : LIBCHARS ) : SAME pre ~void(self) and ~void(lib) and self.is_upper(lib) post result.is_lower is -- Providing that there exists a lower case version of self then -- an encoding giving that character is returned, otherwise the current -- value of self. res : SAME ; first : BOOL := true ; loop loc_code : CHAR_CODE := code! ; if first then first := false ; res := CHAR_CODE::create(CHAR_MAPPINGS::To_Lower.to_range( loc_code.char,lib.culture),lib).rune else res := res + loc_code end end ; return res end ; lower : SAME pre ~void(self) and self.is_upper post result.is_lower is -- Providing that there exists a lower case version of self then -- an encoding giving that character is returned, otherwise the current -- value of self. return lower(LIBCHARS::default) end ; code!( once lib : LIBCHARS ) : CHAR_CODE is -- This iter merely yields the sequence of codes corresponding to self! -- Note that the parameter is provided solely for compatibility with the -- class sub-typing requirements. loop yield code! end end ; code! : CHAR_CODE is -- This iter yields a sequence of the codes in self. loc_bin : BINSTR := binstr ; loc_bin := loc_bin.tail(loc_bin.size - 1) ; -- skip code kind! loop yield CHAR_CODE::create(loc_bin.chunk!(lib.my_size),lib) end end ; end ; -- RUNE