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