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