Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

fuzion/sys/fileio.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation 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 General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature fuzion.sys.fileio
#
#  Author: Wael Youssfi (wael.youssfi@tokiwa.software)
#
# -----------------------------------------------------------------------

# fuzion.sys.fileio -- fileio presents basic features to handle File I/O operations
#

module fileio is

  # reads n bytes of a file opened as fd
  #
  # in case the outcome is an array, it may be shorter than n. this means the end of file
  # has been reached.
  #
  module read(fd File_Descriptor, n u64) outcome (array u8) =>
    len := n.as_i32
    arr := fuzion.sys.internal_array_init u8 len
    res := fzE_file_read fd arr.data len

    if res < -1
      error "failed reading, error: {res}"
    else if res < 0
      []
    else
      buf := arr.as_array
      (buf.slice 0 res).as_array


  # retrieves the file size in bytes and returns an outcome of error in case of an error
  #
  get_file_size(
                        # the (relative or absolute) file name, using platform specific path separators
                        path String) outcome i64 =>
    md := fuzion.sys.internal_array_init i64 4
    if fzE_stat (fuzion.sys.c_string path) md.data = 0 then md[0]
    else error "error getting file size for: $path"


  # writes the content of an array of bytes to a file opened as fd
  #
  # this might overwrite parts or all of an existing file.
  #
  module write(fd File_Descriptor, content array u8) outcome unit =>
    res := fzE_file_write fd content.internal_array.data content.length

    if res < 0
      error "failed writing, error: {res}"


  # wrapper for fzE_file_flush
  #
  module flush(fd File_Descriptor) outcome unit =>
    if fzE_file_flush fd = 0
      unit
    else
      error "error when flushing"


  # deletes the file/dir found in the path
  # returns unit as outcome in case of successful deletion and error in case of failure
  # if the targeted dir has content, then the return value will be error and the deletion will not take place
  #
  module delete(
                # the (relative or absolute) file name, using platform specific path separators
                path String) outcome unit =>
    arr := fuzion.sys.c_string path
    if fzE_rm arr != 0
      error "an error occurred while performing the delete operation on the following file/dir: \"$path\""


  #  moves file/dir from an old path to a the new path
  # can rename the file/dir as well by changing the name of the old file/dir to a new name in the new_path
  # returns a unit type as outcome in case of success and error in case of failure
  #
  module move(
              # the old (relative or absolute) file name, using platform specific path separators
              old_path String,
              # the new (relative or absolute) file name, using platform specific path separators
              new_path String) outcome unit =>
    arr0 := fuzion.sys.c_string old_path
    arr1 := fuzion.sys.c_string new_path
    if fzE_file_move arr0 arr1 != 0
      error "an error occurred while performing the following move operation: \"$old_path\" --> \"$new_path\""


  # creates a directory using the specified path
  # parent directories in the path should exist otherwise, no creation will take place and an error will be the outcome
  #
  module create_dir(
                    # the (relative or absolute) dir name, using platform specific path separators
                    path String) outcome unit =>
    arr := fuzion.sys.c_string path
    if fzE_mkdir arr != 0
      error "an error occurred while creating the following directory: \"$path\""


  # Opens an IO source using a Fuzion Pointer as path and flag to represent the opening method (Read: 0, Write: 1, Append: 2)
  # returns outcome i64 representing the file descriptor in success
  # returns an error in failure
  #
  module open(
              # a Fuzion Object represention the path for the source to be opened
              path String,
              # a flag to specify the open method (Read: 0, Write: 1, Append: 2)
              flag i32) outcome File_Descriptor =>
    open_results := fuzion.sys.internal_array_init i64 1  # [error number]
    res := fzE_file_open (fuzion.sys.c_string path) open_results.data flag
    if open_results[0] = 0
      res
    else
      error "failed opening file, error number: {open_results[0]}"


  # Closes an IO source using an i64 representing the source handler (file descriptor)
  # returns outcome unit in case of success and an error in case of failure
  #
  module close(
               # file descriptor
               fd File_Descriptor) outcome unit =>
    closing_result := fzE_file_close fd
    if closing_result != 0
      error "failed closing file, error number: $closing_result"


  # seek offset in the stream represented by fd
  # returns an outcome i64 that represents the new offset
  # returns an error in case of failure
  #
  module seek(
              # file descriptor
              fd File_Descriptor,
              # the offset to seek from the beginning of this file
              offset i64) outcome unit =>
    res := fzE_file_seek fd offset
    if res = -1
      error "failed seeking file, error number: {res}"


  # returns the current file-pointer offset as an outcome i64,
  # the offset is measured from the beginning of the file indicated by the file descriptor
  # returns the current offset in success and error in failure
  #
  module file_position(
                       # file descriptor
                       fd File_Descriptor) outcome i64 =>
    res := fzE_file_position fd
    if res = -1
      error "failed getting position in file, error number: {res}"
    else
      res


  # open the directory given by path
  #
  # returns an integer that is intended to be used as an opaque reference
  # to the opened directory, or an error if one was encountered.
  #
  module open_dir(path String) outcome Directory_Descriptor =>
    open_results := fuzion.sys.internal_array_init i64 1  # [error number]
    res := fzE_opendir (fuzion.sys.c_string path) open_results.data
    if open_results[0] = 0
      res
    else
      error "failed opening directory, error number: {open_results[0]}"

last changed: 2025-07-10