(********************************************************************) (* *) (* fileutil.s7i File utility functions. *) (* Copyright (C) 2019, 2020 Thomas Mertes *) (* *) (* This file is part of the Seed7 Runtime Library. *) (* *) (* The Seed7 Runtime Library is free software; you can *) (* redistribute it and/or modify it under the terms of the GNU *) (* Lesser General Public License as published by the Free Software *) (* Foundation; either version 2.1 of the License, or (at your *) (* option) any later version. *) (* *) (* The Seed7 Runtime 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 the GNU Lesser General Public License for more *) (* details. *) (* *) (* You should have received a copy of the GNU Lesser General *) (* Public License along with this program; if not, write to the *) (* Free Software Foundation, Inc., 51 Franklin Street, *) (* Fifth Floor, Boston, MA 02110-1301, USA. *) (* *) (********************************************************************) (** * Copy a file from source to destination. * The ''source'' file is copied to ''dest'' until end-of-file * is reached. *) const proc: copyFile (inout file: source, inout file: dest) is func local var string: buffer is ""; begin buffer := gets(source, 1000000); while buffer <> "" do write(dest, buffer); buffer := gets(source, 1000000); end while; end func; (** * Copy at most ''numChars'' bytes from ''source'' to ''dest''. * The ''source'' file is copied to ''dest'' until '''numChars'' bytes * are copied or end-of-file is reached. * @return the number of bytes copied (which is less or equal ''numChars''). *) const func integer: copyFile (inout file: source, inout file: dest, in integer: numChars) is func result var integer: charsCopied is 0; local var string: buffer is ""; begin buffer := gets(source, min(numChars, 1000000)); while buffer <> "" do charsCopied +:= length(buffer); write(dest, buffer); buffer := gets(source, min(numChars - charsCopied, 1000000)); end while; end func; (** * Insert an area of ''numChars'' chars beginning at ''insertPos'' into ''aFile''. * @exception RANGE_ERROR If ''insertPos'' is negative or zero, or * if ''numChars'' is negative. *) const proc: insertArea (inout file: aFile, in integer: insertPos, in integer: numChars) is func local const integer: bufferSize is 2 ** 20; var integer: length is 0; var string: buffer is ""; var integer: pos is 0; var integer: bytesMissing is 0; begin # writeln("insertArea: " <& insertPos <& ", " <& numChars); if insertPos <= 0 or numChars < 0 then raise RANGE_ERROR else length := length(aFile); # writeln("length: " <& length); if insertPos <= length and numChars <> 0 then pos := length - bufferSize + 1; while pos > insertPos do seek(aFile, pos); buffer := gets(aFile, bufferSize); seek(aFile, pos + numChars); write(aFile, buffer); pos -:= bufferSize; end while; bytesMissing := bufferSize - (insertPos - pos); seek(aFile, insertPos); buffer := gets(aFile, bytesMissing); seek(aFile, insertPos + numChars); write(aFile, buffer); # Fill inserted area with spaces: # seek(aFile, insertPos); # write(aFile, " " mult numChars); end if; end if; end func; (** * Delete an area of ''numChars'' chars beginning at ''deletePos'' from ''aFile''. * @exception RANGE_ERROR If ''deletePos'' is negative or zero, or * if ''numChars'' is negative. *) const proc: deleteArea (inout file: aFile, in integer: deletePos, in integer: numChars) is func local const integer: bufferSize is 2 ** 20; var integer: length is 0; var string: buffer is ""; var integer: pos is 0; begin # writeln("deleteArea: " <& deletePos <& ", " <& numChars); if deletePos <= 0 or numChars < 0 then raise RANGE_ERROR else length := length(aFile); # writeln("length: " <& length); if deletePos <= length and numChars <> 0 then pos := deletePos + numChars; while pos <= length do seek(aFile, pos); buffer := gets(aFile, bufferSize); seek(aFile, pos - numChars); write(aFile, buffer); pos +:= bufferSize; end while; if length - numChars >= pred(deletePos) then truncate(aFile, length - numChars); else truncate(aFile, pred(deletePos)); end if; end if; end if; end func;