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