------------------------------------------------------------------------------ -- PURPOSE: Package Body for Network Protocols . -- -- -- NOTES: This program was produced by the Westinghouse Electric Corporation, -- as part of the STARS Foundation Ada Software procurement effort. -- -- (c) Copyright 1987 Westinghouse Electric Corporation -- (c) Copyright 1988 Westinghouse Electric Corporation - Updates -- All Rights Reserved. -- -- This material may be reproduced by or for the U.S. Government -- pursuant to the copyright licence under DOD FAR Suppl. Clause -- 52.227-7013 August 1984. -- Author : Jay Michael -------------------------------------------------------------------------------- with TEXT_IO ; use TEXT_IO ; separate (NETWORK_PROTOCOLS) package body GENERIC_TEXT_FILE_IO is -- this package body handles opening, closing, reading, writing of the -- data file to be sent/received type BYTE_STRING is array (INTEGER range <>) of BYTE ; CR : constant BYTE := BYTE'VAL ( CHARACTER'POS ( ASCII.CR ) ) ; FF : constant BYTE := BYTE'VAL ( CHARACTER'POS ( ASCII.FF ) ) ; LF : constant BYTE := BYTE'VAL ( CHARACTER'POS ( ASCII.LF ) ) ; NUL : constant BYTE := BYTE'VAL ( CHARACTER'POS ( ASCII.NUL ) ) ; IFILE, OFILE : FILE_TYPE ; -- keep track of whether a previous call to F_READ decided to return -- a sequence of characters TO_RETURN : constant BYTE_STRING(1..2) := (LF,FF) ; TO_RETURN_LF : constant := 1 ; TO_RETURN_FF : constant := 2 ; N_RETURNED, N_TO_RETURN : INTEGER ; -- retain last character received to prevent CR/LF and LF/CR from -- producing more than one end-of-line apiece PREV_CHAR_RECEIVED : BYTE ; procedure OPEN_READ ( NAME : STRING ; FORM : STRING := "" ) is -- open the data file begin OPEN(IFILE,IN_FILE,NAME,FORM) ; N_TO_RETURN := TO_RETURN'LAST ; N_RETURNED := N_TO_RETURN ; end OPEN_READ ; procedure F_READ ( C : out BYTE ; EOFILE : out BOOLEAN ) is -- read a byte from the data file CH : CHARACTER ; begin if N_RETURNED < N_TO_RETURN then -- character sequence "queued" -- return next character in sequence N_RETURNED := N_RETURNED + 1 ; C := TO_RETURN(N_RETURNED) ; elsif END_OF_LINE(IFILE) then -- for end-of-line, return carriage-return/line-feed -- for end-of-page, follow CR/LF with form-feed C := CR ; N_RETURNED := TO_RETURN'FIRST - 1 ; -- I don't believe anyone wants the stupid page terminator the -- LRM requires that TEXT_IO pretend/insist precedes the -- file terminator if END_OF_PAGE(IFILE) and not END_OF_FILE(IFILE) then N_TO_RETURN := TO_RETURN_FF ; else N_TO_RETURN := TO_RETURN_LF ; end if ; -- the only way to tell if END_OF_LINE (or END_OF_PAGE, for that -- matter) is due to the file terminator being "next" is to -- try to skip the line terminator SKIP_LINE(IFILE) ; -- if we're still here, the file terminator wasn't next else -- return next character of file GET(IFILE,CH) ; C := BYTE'VAL ( CHARACTER'POS ( CH ) ) ; end if ; -- indicate returning a character EOFILE := FALSE ; exception when END_ERROR => EOFILE := TRUE ; end F_READ ; procedure CLOSE_READ is -- close the data file begin CLOSE(IFILE) ; end CLOSE_READ ; procedure OPEN_WRITE ( NAME : STRING ; FORM : STRING := "" ) is -- open the file to accept data--always create a new version if a file -- of this name already exists begin CREATE(OFILE,OUT_FILE,NAME,FORM) ; PREV_CHAR_RECEIVED := NUL ; end OPEN_WRITE ; procedure F_WRITE ( C : BYTE ) is -- write data byte to file REMEMBER : BYTE ; begin -- will probably want to retain new character for next call REMEMBER := C ; if C = CR or C = LF then -- treat as line terminator unless previous character was the -- complementary end-of-line character if BYTE'POS(C) + BYTE'POS(PREV_CHAR_RECEIVED) = BYTE'POS(CR) + BYTE'POS(LF) then -- C is the complement of the last character received -- don't end another line, but make sure the next CR or LF is -- treated as an end-of-line REMEMBER := NUL ; else -- C constitutes an end-of-line NEW_LINE(OFILE) ; end if ; elsif C = FF then -- convert form-feed to end-of-page NEW_PAGE(OFILE) ; else -- mundane character -- write to file PUT(OFILE,CHARACTER'VAL(BYTE'POS(C))) ; end if ; PREV_CHAR_RECEIVED := REMEMBER ; end F_WRITE ; procedure CLOSE_WRITE is -- close the data file begin CLOSE(OFILE) ; end CLOSE_WRITE ; function NAME_OF_FILE_BEING_TRANSFERRED return STRING is -- obtain the file name, using text_io.name function begin return NAME(IFILE); end; end GENERIC_TEXT_FILE_IO ;