binfile.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 BIN_FILE < $FILES
class BIN_FILE < $FILES is
-- This class of binary files permits all of the generic file
-- operations defined on files. The operations defined below provide
-- for input/output in the same style as text-files.
-- Version 1.2 Oct 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 6 May 96 kh Original adapted from Sather 1.0
-- 5 Apr 97 kh Modified for portability, etc
-- 25 Oct 98 kh Refined, added pre/post conditions.
include FILE{BIN_FILE} ;
cursor(
buff_size : CARD
) : BIN_FILE_CURSOR
pre ~void(fyle)
and ((buff_size % 4) = 0)
post true
is
-- This routine provides for buffered I/O using the file cursor
-- returned. This permits the use of large files where reading all of
-- file contents into memory at once would be impractical.
return BIN_FILE_CURSOR::create(fyle,buff_size,readable,writable)
end ;
plus(
entity : BINSTR
) : SAME
pre ~void(fyle)
and writable
and (entity.size > 0)
post void(result)
or (update
and (size >= entity.size))
or (size = (initial(size) + entity.size))
is
-- This routine appends the given item to the current file channel,
-- returning self if successful, otherwise void.
count : CARD := entity.size ;
success : BOOL := FILE_SYS::file_write(entity,1,inout count,fyle) ;
if success then
return self
else
return void
end
end ;
plus(
item : OCTET
) : SAME
pre ~void(fyle)
and writable
post (size = (initial(size) + 1))
is
-- This routine appends the given item to the current channel, returning
-- self if successful, otherwise void.
count : CARD := 1 ;
success : BOOL := FILE_SYS::file_write(BINSTR::create(item),1,
inout count,fyle) ;
if success then
return self
else
return void
end
end ;
buffer : FBINSTR
pre ~void(fyle)
and readable
post void(result)
or (result.size = size)
is
-- This routine returns a buffer containing the entire contents of
-- the file provided that it was possible to set the 'cursor' at the beginning
-- of the file.
file_size : CARD ;
if ~FILE_SYS::size(fyle, out file_size) then
return void -- not accessible!
end ;
res : FBINSTR := FBINSTR::create(file_size) ;
if file_size = 0 then -- Nothing to read!
return res -- an empty (zero size) buffer!
end ;
size : CARD := file_size ; -- in octets!!
if ~FILE_SYS::seek(fyle,0.int,FILE_LOCS::Beginning) then
return void
end ;
if ~FILE_SYS::file_read(res,1,inout size,fyle)
or (size < file_size) then -- some serious IO problem!
return void -- probably not readable!
end ;
res.loc := size ;
return res
end ;
end ; -- BIN_FILE
class BIN_FILE_CURSOR < $FILE_CURSORS{OCTET, BINSTR}
class BIN_FILE_CURSOR < $FILE_CURSORS{OCTET, BINSTR} is
-- This class implements the detailed buffered I/O operations for
-- a binary file. The internal operations are based upon general container
-- facilities since no semantics is attached to any of the file elements.
-- Version 1.2 Oct 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 6 May 96 kh Original from Sather 1.0 & Modula-2
-- 5 Apr 97 kh Modified for portability, etc
-- 25 Oct 98 kh Refined and added pre/post conditions.
include FILE_CURSOR{BIN_FILE_CURSOR, FBINSTR} ;
get(
size : CARD
) : FBINSTR
pre ~void(self)
and readable
and (size > 0)
post ((buff_contents = 0)
and void(result))
or (result.loc = size)
is
-- This routine returns the next item (if any) from the file. If
-- there is insufficient data remaining on the file then void is returned.
res : FBINSTR := FBINSTR::create(size) ;
todo : CARD := size ;
if position >= buff_position then
index := position - buff_position ;
buff_valid := (index < buff_contents)
else -- buffer needs filling!
buff_valid := false
end ;
loop
if ~buff_valid then
fillbuff ;
if buff_contents = 0 then -- not enough data!
return void
end
end ;
cnt : CARD := buff_contents - index ;
if cnt > todo then
cnt := todo
end ;
loop
cnt.times! ;
res := res + buffer.elt!(index)
end ;
index := index + cnt ;
if todo = cnt then
break!
end ;
todo := todo - cnt ;
buff_valid := false
end ;
position := position + size ;
return res
end ;
plus(
item : OCTET
)
pre ~void(self)
and writable
post (buffer[index - 1] = item)
is
-- This routine appends item to the file, starting at the current
-- position of the cursor.
if position < buff_position then
emptybuff ;
fillbuff
elsif index = buff_contents then
emptybuff ;
if ~at_end then -- refill to over-write!
fillbuff
end
else
index := position - buff_position
end ;
buffer.aset(index,item) ;
buff_altered := true ; -- needs writing!
index := index + 1 ;
position := position + 1
end ;
plus(
item : OCTET
) : SAME
pre ~void(self)
and writable
post (buffer[index - 1] = item)
is
-- This routine appends item to the file, returning the cursor.
plus(item) ;
return self
end ;
plus(
item : BINSTR
)
pre ~void(self)
and writable
and ~void(item)
post ((initial(position) + item.size) = position)
is
-- This routine appends item to the file, starting at the current
-- position of the cursor.
if position < buff_position then
emptybuff ;
fillbuff;
elsif index = buffer.size then
emptybuff ;
if ~at_end then -- refill to over-write!
fillbuff;
end
else
index := position - buff_position
end ;
todo : CARD := item.size ;
cnt : CARD := 0 ;
loop
todo := todo - cnt ;
if todo = 0 then
break!
elsif index = buffer.size then
emptybuff ;
fillbuff
end ;
if todo > cnt then
cnt := todo.min(buffer.size - index)
end ;
loop
cnt.times! ;
buffer.aset(index,item.elt!) ;
index := index + 1
end ;
buff_altered := true ;
position := position + cnt
end
end ;
plus(
item : BINSTR
) : SAME
pre ~void(self)
and writable
and ~void(item)
post ((initial(position) + item.size) = position)
is
-- This routine appends item to the file, returning the cursor.
plus(item) ;
return self
end ;
end ; -- BIN_FILE_CURSOR