(********************************************************************)
(*                                                                  *)
(*  bigfile.s7i   bigInteger versions of seek, tell and length      *)
(*  Copyright (C) 2006  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.                       *)
(*                                                                  *)
(********************************************************************)


include "bigint.s7i";
include "external_file.s7i";


(* clib_file *)

const func bigInteger: bigLength (ref clib_file: aFile)           is action "FIL_BIG_LNG";
const proc: seek (ref clib_file: aFile, ref bigInteger: position) is action "FIL_BIG_SEEK";
const func bigInteger: bigTell (ref clib_file: aFile)             is action "FIL_BIG_TELL";


(* file *)

const func bigInteger: bigLength (ref file: aFile)           is DYNAMIC;
const proc: seek (ref file: aFile, ref bigInteger: position) is DYNAMIC;
const func bigInteger: bigTell (ref file: aFile)             is DYNAMIC;


(* null_file *)


(**
 *  Obtain the length of a file.
 *  A [[null_file]] is not seekable, therefore FILE_ERROR is raised.
 *  Derived types of [[null_file]] need to override this function.
 *  @return nothing, because FILE_ERROR is always raised.
 *  @exception FILE_ERROR Is always raised, because a [[null_file]] is
 *             not seekable.
 *)
const func bigInteger: bigLength (ref null_file: aFile) is func
  result
    var bigInteger: length is 0_;
  begin
    raise FILE_ERROR;
  end func;


(**
 *  Set the current file position.
 *  A [[null_file]] is not seekable, therefore FILE_ERROR is raised.
 *  If a derived type is seekable it needs to override this function.
 *  @exception FILE_ERROR Is always raised, because a [[null_file]] is
 *             not seekable.
 *)
const proc: seek (ref null_file: aFile, ref bigInteger: position) is func
  begin
    raise FILE_ERROR;
  end func;


(**
 *  Obtain the current file position.
 *  A [[null_file]] is not seekable, therefore FILE_ERROR is raised.
 *  If a derived type is seekable it needs to override this function.
 *  @return nothing, because FILE_ERROR is always raised.
 *  @exception FILE_ERROR Is always raised, because a [[null_file]] is
 *             not seekable.
 *)
const func bigInteger: bigTell (ref null_file: aFile) is func
  result
    var bigInteger: position is 0_;
  begin
    raise FILE_ERROR;
  end func;


(* external_file *)


(**
 *  Determine the size of a file and return it as bigInteger.
 *  The file length is measured in bytes.
 *  @return the size of the given file.
 *  @exception FILE_ERROR A system function returns an error or the
 *             file length reported by the system is negative.
 *  @exception MEMORY_ERROR Not enough memory to represent the result.
 *)
const func bigInteger: bigLength (ref external_file: aFile) is
  return bigLength(aFile.ext_file);


(**
 *  Set the current file position.
 *  The file position is measured in bytes from the start of the file.
 *  The first byte in the file has the position 1.
 *  @exception RANGE_ERROR The file position is negative or zero or
 *             the file position is not representable in the system
 *             file position type.
 *  @exception FILE_ERROR A system function returns an error.
 *)
const proc: seek (ref external_file: aFile, in bigInteger: position) is func
  begin
    seek(aFile.ext_file, position);
  end func;


(**
 *  Obtain the current file position.
 *  The file position is measured in bytes from the start of the file.
 *  The first byte in the file has the position 1.
 *  @return the current file position.
 *  @exception FILE_ERROR A system function returns an error or the
 *             file position reported by the system is negative.
 *  @exception MEMORY_ERROR Not enough memory to represent the result.
 *)
const func bigInteger: bigTell (ref external_file: aFile) is
  return bigTell(aFile.ext_file);