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