# NSFS cheat sheet

This is a "cheat sheet" for Non-Sandboxed FileSystem extension by YellowAfterlife.
The extension can be acquired from GM:Marketplace or itch.io.
For questions/support, use forums, or send me an email.
The extension is currently available for Windows (is a DLL).
Click on sections to expand/collapse them.
Quick display controls: Categories · Functions · Everything

- ### General functions

  - ### nsfs_is_available

    This variable holds status (`true`\`false`) of whether the native extension for NSFS was successfully loaded. The extension may not be loaded in a few cases:
    - Extension is not supported on the target platform.
    - Extension' file is amiss (e.g. the user did not unzip the game before running).
    As per GameMaker rules, all calls to unavailable extensions return `0` instead, so you may want to check this and notify the user prior to performing any operations.

  - ### nsfs_status

    Some functions provide additional feedback aside of usual success/failure result.
    In those cases, when the result is `false`, this global variable holds the status/error code that can be used for troubleshooting the issue.
    On Windows, values are as per System Error Codes reference.

  - ### nsfs_set_directory(new_working_directory)

    By default, when a relative path is specified, NSFS will read/write files in game's program directory. If you want to use some other directory instead (e.g. save directory), you can use this function to change the extension's working directory.
    The function returns whether the working directory was successfully changed; nsfs_status contains the error code if it couldn't be.
    One of the few reasons to failure of this function is the target directory not being a valid path (use directory_exists\directory_exists_ns to check).

  - ### nsfs_get_directory()

    Returns the extension's working directory.
    If that somehow fails, returns an empty string and sets nsfs_status.

- ### File manipulation functions

  - ### file_exists_ns(path)

    Returns whether the file exists at the given path.
    Returns `false` if there's a directory of the same name at the path.

  - ### file_copy_ns(oldpath, newpath)

    Copies a file between locations, returns whether successful.
    In case of failure, nsfs_status contains the error code.

  - ### file_rename_ns(oldname, newname)

    Renames a file, returns whether successful.
    Note that if the `oldname` contains a path, `newname` should as well.
    In case of failure, nsfs_status contains the error code.

  - ### file_move_ns(oldpath, newpath)

    Moves a file to a different location, returns whether successful.
    In case of failure, nsfs_status contains the error code.

  - ### file_delete_ns(path)

    Deletes a file, returns whether successful.
    In case of failure, nsfs_status contains the error code.
    Note that you can't remove files currently in use by an application (incl. yours).

- ### Directory manipulation functions

  - ### directory_exists_ns(path)

    Returns whether the file exists at the given path.
    Returns `false` if there's a directory of the same name at the path.

  - ### directory_copy_ns(oldpath, newpath)

    Copies a directory between locations, returns whether successful.
    In case of failure, nsfs_status contains the error code.

  - ### directory_rename_ns(oldname, newname)

    Renames a directory, returns whether successful.
    Note that if the `oldname` contains a path, `newname` should as well.
    In case of failure, nsfs_status contains the error code.
    Directories cannot be renamed if some of their files are currently in use by applications (incl. yours).

  - ### directory_move_ns(oldpath, newpath)

    Moves a directory to a different location, returns whether successful.
    In case of failure, nsfs_status contains the error code.
    Directories cannot be moved if some of their files are currently in use by applications (incl. yours).

  - ### directory_delete_ns(path)

    Deletes a directory, returns whether successful.
    In case of failure, nsfs_status contains the error code.
    Directories cannot be deleted if some of their files are currently in use by applications (incl. yours).

- ### File/directory attribute functions

  - ### file_get_attributes_ns(path)

    Returns attributes of a file/directory at given path.
    Returned attributes (a set of bit flags) are as per MSDN specification.
    If attributes cannot be retrieved (e.g. no object exists at path), returned value is `-1`, and nsfs_status contains the error code.

  - ### file_set_attributes_ns(path, newattributes)

    Changes the attributes of a file/directory at the given path, returns whether successful. The attributes (a set of bit flags) are as per MSDN specification.
    If attributes cannot be changed, nsfs_status contains the error code.

  - ### file_get_size_ns(path)

    Returns the size of the file at given path, in bytes.
    If the size cannot be measured, returns -1 and sets nsfs_status.

- ### File/directory search functions

  - ### file_find_first_ns(mask)

    Begins the search for files/directories matching the given mask and returns the first result. Returns "" and sets nsfs_status if nothing can be found.
    This is much akin to file_find_first, but with one remark: instead of taking attributes as a second parameter (which gives very limited freedom to filtering results), there is a file_find_attributes_ns function that returns the attributes of the current file in search.
    For example, if you wanted to pick through just files (no directories) in `maps` subdirectory in game's directory, you would do that like so:

        for (var f = file_find_first_ns("maps/*.*"); f != ""; f = file_find_next_ns()) {
            if (file_find_attributes_ns() & fa_directory) continue;
            // file is not a directory - do something here
            show_debug_message(f + ": " + string(file_find_size_ns() / 1024) + "KB");
        }
        file_find_close();

    which would display results like `some.map` (given `maps/some.map`).

  - ### file_find_next_ns()

    Returns the next result matching the mask (from file_find_first_ns).
    Returns `""` if there are no more results left.

  - ### file_find_close_ns()

    Finalizes the current search and frees up the related resources.
    file_find_first_ns will automatically do this prior to starting the next search if you forget, but it is recommended that you do this by yourself when a search is complete.

  - ### file_find_attributes_ns()

    Returns the attributes (much like file_get_attributes_ns) of the current (most recently returned) file in search. Due to how file search works, this is generally faster than retrieving the attributes by absolute path.

  - ### file_find_size_ns()

    Returns the size (in bytes) of the current (most recently returned) file in search. This is generally faster than retrieving the size by absolute path.
    This function considers directories to have size of 0 bytes.

- ### Text file functions

  - ### file_text_open_read_ns(path, codepage)

    Opens a text file at given path for reading and returns file ID.
    Codepage numbers can be found on MSDN.
    `-1` can be specified as a codepage to use UTF-8 (GMS default).
    If the file cannot be opened for reading, returns `-1` and sets nsfs_status.
    IDs used by these functions are separate from those used by built-in ones.

  - ### file_text_open_write_ns(path, codepage)

    Opens a text file at given path for writing and returns file ID.
    If the file is already present, it is overwritten.
    Codepage numbers can be found on MSDN.
    `-1` can be specified as a codepage to use UTF-8 (GMS default).
    If the file cannot be opened for writing, returns `-1` and sets nsfs_status.

  - ### file_text_open_append_ns(path, codepage)

    Opens a text file at given path for writing and returns file ID.
    If the file is already present, appends to the end of the file.
    Codepage numbers can be found on MSDN.
    `-1` can be specified as a codepage to use UTF-8 (GMS default).
    If the file cannot be opened for writing, returns `-1` and sets nsfs_status.

  - ### file_text_close_ns(file_id)

    Closes the given text file, freeing it for operations or use by other applications.
    Returns whether the file was actually open (and thus could be closed).

  - ### file_text_eof_ns(file_id)

    Returns whether end of file was reached for the given file.
    Only makes sense for files opened for reading.
    Returns `true` for invalid file IDs.

  - ### file_text_read_line_ns(file_id)

    Reads and returns the next line from the given file.
    This is equivalent to file_text_read_string + file_text_readln. That is, it reads and returns the text on the current line, and skips the line delimiter (CR\LF\CRLF\LFCR).
    Returns `""` if the file handle is invalid or end of file has been reached.

  - ### file_text_write_line_ns(file_id, text)

    Writes a string to the given file, returns whether successful.
    Adds a linebreak (CRLF) prior to writing automatically if it is not the first line.

- ### Buffer functions

  - ### buffer_load_ns(path)

    Loads a GM buffer from the file and returns it's ID.
    Is a direct equivalent of the built-in buffer_load function.
    If the file cannot be read, returns `-1` and sets nsfs_status.

  - ### buffer_save_ns(buffer, path)

    Saves the contents of the given buffer to a file, returns whether successful.
    Is akin to the built-in buffer_save function (but has a return value).
    If the file cannot be written, returns `false` and sets nsfs_status.

  - ### buffer_save_ext_ns(buffer, path, offset, size)

    Saves a subsection of the given buffer to a file, returns whether successful.
    Is akin to the built-in buffer_save_ext function (but has a return value).
    If the file cannot be written, returns `false` and sets nsfs_status.

- ### Misc functions

  - ### string_codepage(string, oldcodepage, newcodepage)

    Converts contents of a string between codepages.
    Codepage numbers can be found on MSDN.
    `-1` can be specified as a codepage to use UTF-8 (GMS default).
    This is particularly handy if you

- ### Workarounds

  Certain functions cannot be reasonably implemented in scope of this extension, e.g.
  - GM:S does not allow extensions to load assets directly, meaning that they would have to be copied into an "allowed" directory by either yourself or an extension.
  - `file_bin_` functions are noticeably outperformed by a `buffer_fast` buffer, leaving little reason to reimplement them instead of using buffers.
  In majority of situations, the issues can be bypassed by using file_copy_ns or directory_copy_ns accordingly.