fstr.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 FSTR < $FTEXT_STRING{CHAR,STR,FSTR}

class FSTR < $FTEXT_STRING{CHAR,STR,FSTR} is -- This class implements the concept of a fast mutable text string (of -- characters in this case). -- Version 1.3 Apr 99. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 4 Apr 97 kh Original adapted from 1.1 release -- 27 Oct 98 kh Major octet/char fix, added pre/post conds. -- 8 Feb 99 kh Redone to fix broken indexing, name change. -- 12 Apr 99 kh Complete rewrite for V8 of text classes include FTEXT_STRING{CHAR,STR} ; include FTEXT_INCL{CHAR} oct_acopy -> oct_acopy, ind! -> ; private const Default_Size : CARD := 16 ; -- character codes -- not CHARs create( sz : CARD, lib : LIBCHARS ) : SAME pre ~void(lib) post sz >= result.size is -- This routine creates a new buffer of the given element count. if sz = 0 then return void end ; me : SAME := raw_create(sz * lib.my_size) ; me.priv_lib := REP_LIB_LIST::index(lib) ; me.loc := 0 ; return me end ; create( sz : CARD ) : SAME is -- This routine creates a new buffer of the given storage size. return create(sz,LIBCHARS::default) end ; create( lib : LIBCHARS ) : SAME is -- This routine creates a new buffer of the default storage size. return create(Default_Size,lib) end ; create : SAME is -- This routine returns a new buffer. return create(0,LIBCHARS::default) end ; create( src : STR ) : SAME is -- This routine creates and fills a buffer from src. if (src.size = 0) then return create -- just produce a default buffer else res : SAME := create(src.size,src.index_lib) ; res.acopy(src) ; res.loc := src.asize ; return res end end ; nil : SAME is -- This routine returns a new nil (empty but not void) string. return create end ; binstr : BINSTR pre ~void(self) post (result.size = loc) is -- This routine returns the text string as a binary string. res : BINSTR := BINSTR::create(loc) ; loop index : CARD := 0.upto!(loc - 1) ; res.aset!(oct_aget(index)) end ; return res end ; size : CARD pre true post ((void(self) or (asize = 0)) and (result = 0)) or (result = loc / index_lib.my_size) is -- The number of characters in self. 0 if self is void. if void(self) or (asize = 0) then return 0 else return loc / index_lib.my_size end end ; push( elem : CHAR ) : SAME pre true post (result.size = (initial(size) + 1)) is -- This routine appends a new element to the end of self and returns -- the result. If self is void a new list is created. res : SAME ; loc_index : CARD := size ; if void(self) then res := create(2,LIBCHARS::default) elsif (loc < asize) then res := self else res := create(2 * (asize + 1),index_lib) ; -- Amortised doubling res.loc := loc ; res.acopy(self) ; SYS::destroy(self) -- old one shouldn't be used now. end ; res.aset(loc_index,elem) ; return res end ; aget( index : CARD ) : CHAR pre ~void(self) and (index < size) post true is -- This routine is the 'array' indexing facility for characters in -- a string, returning the character indexed. loc_start : CARD := index * index_lib.my_size ; res : CARD ; loop loc_index : CARD := loc_start.upto!( loc_start + index_lib.my_size - 1) ; res := res * (OCTET::Octet_Max + 1) + oct_aget(loc_index).card end ; return CHAR_CODE::create(res,index_lib).char end ; aset( index : CARD, elem : CHAR ) pre ~void(self) and ((index < size) or ((index * index_lib.my_size) < asize)) post true is -- This routine is the 'array' indexing facility for characters in -- a string, setting the element specified to the given character coding. loc_start : CARD := index * index_lib.my_size ; if loc_start = loc then loc := loc + index_lib.my_size ; end ; loop -- over octets! index_lib.my_size.times! ; aset(loc_start.up!,elem.aelt!) end end ; append_file( name : STR ) : SAME pre true post (result = self) -- if file couldn't be found or (result.size > initial(size)) -- and contains the file contents is -- This routine attempts to open the file which has the given name. If -- successful then the contents of the file are appended to self which is -- returned after closing the file. -- -- NOTE If there is a file reading error then an exception is raised! fyle : TEXT_FILE := TEXT_FILE::open_for_read(name) ; if void(fyle) then return self end ; loc_buff : SAME := fyle.fstr ; fyle.close ; res : SAME ; if void(self) then res := loc_buff ; res.priv_lib := REP_LIB_LIST::index(LIBCHARS::default) else loc_buff.priv_lib := priv_lib ; res := self + loc_buff end ; return res end ; append_file_range( name : STR, start, size : CARD ) : SAME pre true post (result = self) -- if file couldn't be found or (result.size > initial(size)) -- and contains the file contents is -- This routine attempts to open the named file and append the contents -- (starting at start for size octets) to self. If the file cannot be opened -- then nothing is done. fyle : REFERENCE := FILE_SYS::open(name,FILE_MODES::Read_Text) ; if void(fyle) then return self end ; file_size : CARD ; if ~FILE_SYS::size(fyle,out file_size) then return self end ; if file_size = 0 then return self end ; actual_size : CARD := (file_size - start).min(size) ; -- in octets res : SAME ; buffer_start : CARD ; if void(self) then res := create(actual_size,LIBCHARS::default) ; buffer_start := 0 ; res.loc := actual_size elsif actual_size <= (actual_size - loc) then res := self ; buffer_start := loc ; res.loc := loc + actual_size else res := create((2 * asize).max(loc + actual_size),index_lib) ; buffer_start := loc ; res.acopy(self) ; res.loc := loc + actual_size end ; -- NOTE This reading routine starts to store data at -- the buffer_start position, not necessarily its beginning. if ~FILE_SYS::file_read(res,actual_size,inout buffer_start,start,fyle) then SYS_ERROR::create.error(self,SYS_EXCEPT::Access_Error,name) end ; FILE_SYS::close(fyle) ; return res end ; separate!( str : STR ) : STR pre ~void(str) and ~void(self) and (index_lib = str.index_lib) post (result = str.str) or (result = self.str + str.str) is -- On the first iteration this iter yields the string str. On successive -- iterations it yields self followed by str. Created for use in forming -- lists whose elements are separated by self. yield str.str ; loc_fstr : SAME := create(index_lib) + str ; loop num : CARD := (loc / index_lib.my_size) + str.size ; fstr : SAME := create(num,index_lib) ; fstr.loc := num ; fstr.acopy(self) ; fstr.acopy(loc,loc_fstr) ; yield fstr.str end end ; str : STR pre ~void(self) post (result.size = self.size) is -- This routine returns a string version of self. res : STR := STR::from_fstr(self) ; return res end ; end ; -- FSTR