coding.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 CODE_STR < $IS_EQ, $BINARY, $ELT{CHAR_CODE}
class CODE_STR < $IS_EQ, $BINARY, $ELT{CHAR_CODE} is
-- This class is used for repertoire and character mapping to implement
-- the variable length codes which correspond to a character name token.
-- Version 1.0 Jun 97. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 28 Jul 98 kh Original for code 'conversion'.
include COMPARABLE ;
include BINARY ;
private attr list : FLIST{CHAR_CODE} ;
private attr priv_lib : CARD ;
-- The index into the global list of repertoires.
raw_create(binstr : BINSTR,lib : LIBCHARS) : SAME
pre ~void(binstr) and ~void(lib)
post ~void(result)
is
-- This routine creates a new object from the binary string given, using
-- the given repertoire and encoding.
me : SAME := new ;
me.priv_lib := REP_LIB_LIST::index(lib) ;
loop
chunk : BINSTR := binstr.chunk!(lib.my_size) ;
me.list := me.list.push(CHAR_CODE::raw_build(chunk.cursor,lib))
end ;
return me
end ;
build(cursor : BIN_CURSOR,lib : LIBCHARS) : SAME
pre ~void(cursor)
and ~cursor.is_done
and ~void(lib)
post ~void(result)
or (cursor.index = initial(cursor.index))
is
-- This routine creates a new object from the binary string indicated
-- by cursor. Provided that the binary string is long enough then the object
-- is returned, otherwise void is returned and the cursor has not been moved.
loc_start : CARD := cursor.index ;
me : SAME := new ;
loc_kind : CODE_KINDS := CODE_KINDS::build(cursor) ;
if loc_kind /= lib.culture.kind then -- incompatibility!!
cursor.set_index(loc_start) ;
return void
else
me.priv_lib := REP_LIB_LIST::index(lib)
end ;
loc_cnt : CARD := cursor.card ; -- number of codes - in 4 octets!
loop
loc_cnt.times! ;
if cursor.is_done then
cursor.set_index(loc_start) ;
return void
end ;
me.list := me.list.push(CHAR_CODE::raw_build(cursor,lib))
end ;
return me
end ;
build(cursor : BIN_CURSOR) : SAME
pre ~void(cursor) and ~cursor.is_done
post ~void(result)
or (cursor.index = initial(cursor.index))
is
-- This routine creates a new object from the binary string indicated
-- by cursor. Provided that the binary string is long enough then the object
-- is returned, otherwise void is returned and the cursor has not been moved.
return build(cursor,LIBCHARS::default)
end ;
create(lib : LIBCHARS) : SAME
pre ~void(lib)
is
-- This creation routine provides the common 'background' data required
-- by this object class for normal string building.
me : SAME := new ;
me.list := FLIST{CHAR_CODE}::create ;
me.priv_lib := REP_LIB_LIST::index(lib) ;
--REP_LIB_LIST::inspect;
return me
end ;
create(code : CHAR_CODE) : SAME
pre ~void(code)
post ~void(result)
is
-- This creation routine provides the common 'background' data required
-- by this object class for normal string building.
me : SAME := new ;
me.list := FLIST{CHAR_CODE}::create ;
me.priv_lib := REP_LIB_LIST::index(code.lib) ;
me.list := me.list.push(code) ;
return me
end ;
create(str : STR) : SAME
pre ~void(str)
post ~void(result)
is
-- This creation routine creates a code string from the given text
-- string.
me : SAME := new ;
me.list := FLIST{CHAR_CODE}::create ;
me.priv_lib := REP_LIB_LIST::index(str.index_lib) ;
loop
me.list := me.list.push(str.code!) ;
end ;
return me
end ;
is_eq(other : SAME) : BOOL is
-- This predicate returns true if and only if self and other have the
-- same code-kind and all of the elements are identical.
if lib /= other.lib then
return false
end ;
loop
if list.elt! /= other.list.elt! then
return false
end
end ;
return true
end ;
size : CARD is
-- This routine returns the length of the code list.
if void(self) then
return 0
else
return list.size
end
end ;
lib : LIBCHARS is
-- This routine returns the repertoire in which this is encoded.
if priv_lib < REP_LIB_LIST::lib_list.size then
return REP_LIB_LIST::lib_list[priv_lib]
else
return void
end
end ;
copy : SAME is
-- This routine returns a copy of self as a new object.
res : SAME := create(lib) ;
res.list := list.copy ;
res.priv_lib := priv_lib ;
return res
end ;
aget(index : CARD) : CHAR_CODE
pre ~void(self) and (index < list.size)
post true
is
-- This routine provides the simple string indexing facility based on
-- the use of the list aget.
return list[index]
end ;
aset(index : CARD,val : CHAR_CODE)
pre ~void(self) and (index < list.size)
post true
is
-- This routine provides the simple string indexing facility based on
-- the use of the list aget.
list[index] := val
end ;
plus(elem : CHAR_CODE) : SAME
pre ~void(self)
-- and (lib = elem.lib)
post (result.list.size = initial(list.size) + 1)
and (result.priv_lib = priv_lib)
is
-- This routine appends the given element to the code string returning
-- a new code string object.
--
-- NOTE This routine presumes that elem is in the encoding of rep_map.
-- This cannot be checked here!!!!!
res : SAME := copy ;
res.list := res.list.push(elem) ;
return res
end ;
push(elem : CHAR_CODE) : SAME
pre ~void(self) and ~void(list)
post (list.size = initial(list.size) + 1)
and (list[initial(list.size)] = elem)
is
-- This routine appends the given element to the code string returning
-- self (which may have a new list, dependent on the FLIST operation!).
--
-- NOTE This routine presumes that elem is in the encoding of rep_map.
-- This cannot be checked here!!!!!
list := list.push(elem) ;
return self
end ;
plus(other : SAME) : SAME
pre ~void(self)
and ~void(list)
and (priv_lib = other.priv_lib)
post (result.list.size = initial(list.size) + other.list.size)
is
-- This routine appends the given element to the code string returning self.
res : SAME := copy ;
res.list := res.list.append(other.list) ;
return res
end ;
binstr : BINSTR
pre ~void(self)
post ~void(result) -- and it is a binary representation of self
is
-- This routine returns the value of self as a binary string.
res : BINSTR := BINSTR::create ;
res := res + lib.culture.kind.binstr + list.size.binstr ;
loop
res := res + list.elt!.raw_binstr
end ;
return res
end ;
reverse : SAME is
-- This routine returns a copy of self in which all of the codes are
-- in reverse order.
res : SAME := new ;
res.priv_lib := priv_lib ;
res.list := list.copy ;
res.list.to_reverse ;
return res
end ;
contains(code : CHAR_CODE) : BOOL is
-- This predicate returns true if and only if self contains the given
-- code, otherwise false.
loop
if code = elt! then
return true
end
end ;
return false
end ;
elt! : CHAR_CODE
pre ~void(self)
post ~void(result)
is
-- This iterator yields successive elements of the code 'string' list in turn.
loop
yield list.elt!
end
end ;
elt!(once start : CARD) : CHAR_CODE
pre ~void(self)
post ~void(result)
is
-- This iterator yields successive elements of the code 'string' list
-- in turn, beginning with the indicated element.
loop
yield list.elt!(start)
end
end ;
tgt_str : STR
pre ~void(self)
post (result.size = list.size)
is
-- This routine creates a 'text' string from the internal target codes.
res : FSTR := FSTR::create(lib) ;
loop
loc_code : CHAR_CODE := list.elt! ;
loc_ch : CHAR := loc_code.char ;
res := res + loc_ch
end ;
return res.str
end ;
tgt_runes : RUNES
pre ~void(self)
post (result.size = list.size)
is
-- This routine creates a 'text' string from the internal target codes,
-- provided that all code values will fit into the 'character' objects.
res : FRUNES := FRUNES::create(lib) ;
loop
loc_code : CHAR_CODE := list.elt! ;
res := res + loc_code.rune
end ;
return res.runes
end ;
end ; -- CODE_STR
immutable class TOKEN < $IS_EQ, $STR, $BINARY, $HASH, $NIL
immutable class TOKEN < $IS_EQ, $STR, $BINARY, $HASH, $NIL is
-- This class provides tokens for use in determining collating order
-- of strings. It provides a numeric identifier for all of the names which
-- appear in the source form of repertoire maps and locale files. It is
-- congruent to the CARD class - but with only equality testing, creation
-- and string representation actions available!.
-- NOTE A token must have an encoding with one or more bits set. Void is
-- NOT a valid token.
-- Version 1.1 Sep 97. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 12 Mar 97 kh Original
-- 15 Sep 97 kh Changed to include NUM_CODE
include NUM_CODE
maxval ->,
minval ->,
is_lt -> ; -- not ordered!
nil : SAME is
-- This routine returns the value of the nil token, in this class that
-- is the void value.
return create(0)
end ;
build(str_cursor : BIN_CURSOR,octet_cnt : CARD) : SAME
pre ~void(str_cursor)
and ~str_cursor.is_done
post true
is
-- This routine creates a token object from the binary string
-- attached to the cursor! Note that this automatically returns void if
-- a 'zero' number was built!
case octet_cnt
when 1 then
return OCTET::build(str_cursor).quad.token
when 2 then
return HEXTET::build(str_cursor).quad.token
when 3 then
loc_str : BINSTR := str_cursor.get_upto(octet_cnt) ;
return create(CARD::build(loc_str.cursor))
when 4 then
return QUADBITS::build(str_cursor).token
else
return void
end
end ;
build(str_cursor : BIN_CURSOR) : SAME
pre ~void(str_cursor) and ~str_cursor.is_done
post true
is
-- This routine creates a token object from the binary string
-- attached to the cursor! Note that this automatically returns void if
-- a 'zero' number was built!
return QUADBITS::build(str_cursor).token
end ;
create(str : STR) : SAME
pre str.size > 0
post (result.asize = str.size)
is
-- This routine creates a token object from a string of hexadecimal
-- digits - if the string is a hexadecimal number representation - otherwise
-- void!
if card.is_hex(str) = CONVERSION_RESULTS::All_Right then
return create(CARD::build_based(str.cursor,16))
else
return void
end
end ;
binstr(octet_cnt : CARD) : BINSTR
pre ~(self = nil)
post ~void(result)
is
-- This routine returns the binary string form of self. It may be
-- necessary to precede the result with a count for filing purposes.
return card.binstr.tail(octet_cnt)
end ;
binstr : BINSTR
pre ~(self = nil)
post ~void(result)
is
-- This routine returns the binary string form of self. It may be
-- necessary to precede the result with a count for filing purposes.
return card.binstr
end ;
is_eq(other : SAME) : BOOL is
-- This predicate returns true if and only if self and other are
-- the same valid token values, otherwise false.
return ~(card = 0) and (card = other.card)
end ;
is_nil : BOOL is
-- This predicate returns true if and only if self is nil - for this
-- class void is the same as nil.
return (card = 0)
end ;
private const Max_24 : CARD := 16777215 ; -- Max value in 24 bits!
card : CARD
pre ~is_nil
post result > 0
is
-- This routine returns the token as a cardinal number the significance
-- of which depends upon the using classes.
builtin CARD_CARD
end ;
hash : CARD is
-- This routine returns a hash value computed from self by successive
-- shifts and xors of the bit-pattern forming the numeric value.
return (NUM_BITS::create(card)).hash
end ;
octet! : OCTET is
-- This iter yields successive octets of self INCLUDING a preceding
-- octet giving the count of following octets in MS first order!
num : CARD := card ;
size : CARD := 1 ; -- default!
if num > Max_24 then
size := 4
elsif num > HEXTET::Hextet_Max then
size := 3
elsif num > OCTET::Octet_Max then
size := 2
end ;
yield OCTET::create(size) ;
loc_oct : ARRAY{OCTET} := ARRAY{OCTET}::create(size) ;
loop -- enter in reverse order
loc_index : CARD := (size - 1).downto!(0) ;
loc_oct[loc_index] := OCTET::create(num % (OCTET::Octet_Max + 1)) ;
num := num / (OCTET::Octet_Max + 1)
end ;
loop -- yield in MS octet first order!
yield loc_oct.elt!
end
end ;
hex_str(lib : LIBCHARS) : STR
pre ~void(lib)
post result.size > 0
is
-- This routine returns self as a hexadecimal string without a prefix
-- using the current encoding and repertoire.
res : STR := STR::create(lib) ;
first : BOOL := true ;
loop
loc_val : OCTET := octet! ;
if first then
first := false
else
res := res + loc_val.hex_str(lib)
end
end ;
return res
end ;
hex_str : STR
pre true
post result.size > 0
is
-- This routine returns the string form of self using the default
-- encoding and repertoire.
return hex_str(LIBCHARS::default)
end ;
str(lib : LIBCHARS) : STR
pre ~void(lib)
post result.size > 0
is
-- This routine returns the string form of self using the default
-- encoding and repertoire.
return hex_str(lib)
end ;
str : STR
pre true
post result.size > 0
is
-- This routine returns the string form of self using the default
-- encoding and repertoire.
return hex_str(LIBCHARS::default)
end ;
end ; -- TOKEN