Readded Ruby bindings, since contributor contacted me with permission to
switch to zlib license.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/installer.rb Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,103 @@
+# $Id: installer.rb,v 1.3 2003/07/21 03:46:50 icculus Exp $
+
+require 'rbconfig'
+require 'find'
+require 'ftools'
+
+include Config
+
+module Slimb
+ class Installer
+ def initialize target_dir = "", &user_skip
+ @user_skip = user_skip or proc {|f| false}
+
+ @version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
+ @libdir = File.join(CONFIG["libdir"], "ruby", @version)
+ @sitedir = CONFIG["sitedir"] || File.join(@libdir, "site_ruby")
+ @dest = File.join @sitedir, target_dir
+
+ File::makedirs @dest
+ File::chmod 0755, @dest, true
+ end
+
+ def skip? file
+ @user_skip[file] or
+ file[0] == ?. or file[-1] == ?~ or file[-1] == ?#
+ end
+
+ def install_dir dir
+ File::makedirs(File.join(@dest, dir))
+ File::chmod(0755, File.join(@dest, dir), true)
+ Dir.foreach(dir) {|file|
+ next if skip? file
+
+ if File.ftype(File.join(dir, file)) == "directory"
+ install_dir File.join(dir, file)
+ else
+ install_file File.join(dir, file)
+ end
+ }
+ end
+
+ def install_file file
+ if file =~ /\.so$/
+ install_so file
+ else
+ File::install file, File.join(@dest, file), 0644, true
+ end
+ end
+
+ def install_so file
+ File::install file, File.join(CONFIG["sitearchdir"], file), 0644, true
+ end
+
+ def uninstall_so file
+ file = File.join(CONFIG["sitearchdir"], file)
+ File::safe_unlink file
+ end
+
+ def install something
+ case something
+ when Array
+ something.each {|x|
+ install x if x.is_a? String
+ }
+ when String
+ if File.ftype(something) == "directory"
+ install_dir something
+ else
+ install_file something
+ end
+ end
+ end
+
+ def uninstall what = "*"
+ case what
+ when Array
+ files = what.map {|x| File.join(@dest, x)}
+ when String
+ files = Dir[File.join(@dest, what)]
+ end
+
+ files.each {|x|
+ # FIXME: recursive uninstall is a must
+ next if FileTest.directory? x
+ File::safe_unlink x
+ }
+ end
+
+ def run files, argv
+ if !argv.grep(/--uninstall/).empty?
+ uninstall files
+ else
+ install files
+ end
+ end
+ end
+end
+
+# self-installation
+if $0 == __FILE__
+ $stderr.puts "Installing slimb installer..."
+ Slimb::Installer.new("slimb").install File.basename(__FILE__)
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/extconf.rb Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,9 @@
+require 'mkmf'
+
+$CFLAGS += `sdl-config --cflags`.chomp
+$LDFLAGS += `sdl-config --libs`.chomp
+
+have_library "physfs", "PHYSFS_init"
+have_library "SDL", "SDL_AllocRW"
+
+create_makefile "physfs_so"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/install.rb Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,7 @@
+#!/usr/local/bin/ruby
+
+if __FILE__ == $0
+ require 'slimb/installer'
+ files = ["physfs.rb", "physfs_so.so"]
+ installer = Slimb::Installer.new.run files, ARGV
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/make_install_test.sh Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,9 @@
+#!/bin/sh
+ruby extconf.rb
+make
+cd ..
+ruby installer.rb
+cd physfs
+ruby install.rb
+cd test
+ruby test_physfs.rb
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/physfs.rb Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,121 @@
+#
+# PhysicsFS - ruby interface
+#
+# Author: Ed Sinjiashvili (slimb@vlinkmail.com)
+# License: LGPL
+#
+
+require 'physfs_so'
+
+module PhysicsFS
+
+ class Version
+ def initialize major, minor, patch
+ @major = major
+ @minor = minor
+ @patch = patch
+ end
+
+ attr_reader :major, :minor, :patch
+
+ def to_s
+ "#@major.#@minor.#@patch"
+ end
+ end
+
+ class ArchiveInfo
+ def initialize ext, desc, author, url
+ @extension = ext
+ @description = desc
+ @author = author
+ @url = url
+ end
+
+ attr_reader :extension, :description
+ attr_reader :author, :url
+
+ def to_s
+ " * #@extension: #@description\n Written by #@author.\n #@url\n"
+ end
+ end
+
+ #
+ # convenience methods
+ #
+ class << self
+
+ def init argv0 = $0
+ init_internal argv0
+ end
+
+ def append_search_path str
+ add_to_search_path str, 1
+ self
+ end
+
+ def prepend_search_path str
+ add_to_search_path str, 0
+ self
+ end
+
+ alias_method :<<, :append_search_path
+ alias_method :push, :append_search_path
+ alias_method :unshift, :prepend_search_path
+
+ def ls path = ""
+ enumerate path
+ end
+ end
+
+ #
+ # File - PhysicsFS abstract file - can be drawn from various sources
+ #
+ class File
+ def write_str str
+ write str, 1, str.length
+ end
+
+ def cat
+ prev_pos = tell
+ seek 0
+ r = read length, 1
+ seek prev_pos
+ r
+ end
+
+ alias_method :size, :length
+ end
+
+ #
+ # RWops - general stdio like operations on file-like creatures
+ #
+ class RWops
+ SEEK_SET = 0
+ SEEK_CUR = 1
+ SEEK_END = 2
+
+ # tell current position of RWopted entity
+ def tell
+ seek 0, SEEK_CUR
+ end
+
+ # length of RWops abstracted entity
+ def length
+ cur = tell
+ r = seek 0, SEEK_END
+ seek cur, SEEK_SET
+ r
+ end
+
+ alias_method :size, :length
+
+ #
+ # create rwops from PhysicsFS file object
+ #
+ def self.from_physfs file
+ file.to_rwops
+ end
+ end
+end
+
+# physfs.rb ends here #
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/physfsrwops.c Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,192 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
+ * General Public License: http://www.gnu.org/licenses/lgpl.txt
+ *
+ * SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus@clutteredmind.org).
+ */
+
+#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
+#include "physfsrwops.h"
+
+static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
+{
+ PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
+ int pos = 0;
+
+ if (whence == SEEK_SET)
+ {
+ pos = offset;
+ } /* if */
+
+ else if (whence == SEEK_CUR)
+ {
+ PHYSFS_sint64 current = PHYSFS_tell(handle);
+ if (current == -1)
+ {
+ SDL_SetError("Can't find position in file: %s",
+ PHYSFS_getLastError());
+ return(-1);
+ } /* if */
+
+ pos = (int) current;
+ if ( ((PHYSFS_sint64) pos) != current )
+ {
+ SDL_SetError("Can't fit current file position in an int!");
+ return(-1);
+ } /* if */
+
+ if (offset == 0) /* this is a "tell" call. We're done. */
+ return(pos);
+
+ pos += offset;
+ } /* else if */
+
+ else if (whence == SEEK_END)
+ {
+ PHYSFS_sint64 len = PHYSFS_fileLength(handle);
+ if (len == -1)
+ {
+ SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
+ return(-1);
+ } /* if */
+
+ pos = (int) len;
+ if ( ((PHYSFS_sint64) pos) != len )
+ {
+ SDL_SetError("Can't fit end-of-file position in an int!");
+ return(-1);
+ } /* if */
+
+ pos += offset;
+ } /* else if */
+
+ else
+ {
+ SDL_SetError("Invalid 'whence' parameter.");
+ return(-1);
+ } /* else */
+
+ if ( pos < 0 )
+ {
+ SDL_SetError("Attempt to seek past start of file.");
+ return(-1);
+ } /* if */
+
+ if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return(-1);
+ } /* if */
+
+ return(pos);
+} /* physfsrwops_seek */
+
+
+static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
+{
+ PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
+ PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
+ if (rc != maxnum)
+ {
+ if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ } /* if */
+
+ return((int) rc);
+} /* physfsrwops_read */
+
+
+static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
+{
+ PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
+ PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
+ if (rc != num)
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+
+ return((int) rc);
+} /* physfsrwops_write */
+
+
+static int physfsrwops_close(SDL_RWops *rw)
+{
+ PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
+ if (!PHYSFS_close(handle))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return(-1);
+ } /* if */
+
+ SDL_FreeRW(rw);
+ return(0);
+} /* physfsrwops_close */
+
+
+static SDL_RWops *create_rwops(PHYSFS_file *handle)
+{
+ SDL_RWops *retval = NULL;
+
+ if (handle == NULL)
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ else
+ {
+ retval = SDL_AllocRW();
+ if (retval != NULL)
+ {
+ retval->seek = physfsrwops_seek;
+ retval->read = physfsrwops_read;
+ retval->write = physfsrwops_write;
+ retval->close = physfsrwops_close;
+ retval->hidden.unknown.data1 = handle;
+ } /* if */
+ } /* else */
+
+ return(retval);
+} /* create_rwops */
+
+
+SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle)
+{
+ SDL_RWops *retval = NULL;
+ if (handle == NULL)
+ SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
+ else
+ retval = create_rwops(handle);
+
+ return(retval);
+} /* PHYSFSRWOPS_makeRWops */
+
+
+SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
+{
+ return(create_rwops(PHYSFS_openRead(fname)));
+} /* PHYSFSRWOPS_openRead */
+
+
+SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
+{
+ return(create_rwops(PHYSFS_openWrite(fname)));
+} /* PHYSFSRWOPS_openWrite */
+
+
+SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
+{
+ return(create_rwops(PHYSFS_openAppend(fname)));
+} /* PHYSFSRWOPS_openAppend */
+
+
+/* end of physfsrwops.c ... */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/physfsrwops.h Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,87 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
+ * General Public License: http://www.gnu.org/licenses/lgpl.txt
+ *
+ * SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus@clutteredmind.org).
+ */
+
+#ifndef _INCLUDE_PHYSFSRWOPS_H_
+#define _INCLUDE_PHYSFSRWOPS_H_
+
+#include "physfs.h"
+#include "SDL.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Open a platform-independent filename for reading, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+__EXPORT__ SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
+
+/**
+ * Open a platform-independent filename for writing, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+__EXPORT__ SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
+
+/**
+ * Open a platform-independent filename for appending, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+__EXPORT__ SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
+
+/**
+ * Make a SDL_RWops from an existing PhysicsFS file handle. You should
+ * dispose of any references to the handle after successful creation of
+ * the RWops. The actual PhysicsFS handle will be destroyed when the
+ * RWops is closed.
+ *
+ * @param handle a valid PhysicsFS file handle.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+__EXPORT__ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* include-once blocker */
+
+/* end of physfsrwops.h ... */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_physfs.c Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,462 @@
+/*
+ * PhysicsFS - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#include "physfs.h"
+#include "ruby.h"
+
+#include "rb_physfs.h"
+#include "rb_physfs_file.h"
+
+VALUE modulePhysfs;
+
+/*
+ * PhysicsFS::init str
+ *
+ * initialize PhysicsFS
+ */
+VALUE physfs_init (VALUE self, VALUE str)
+{
+ int result = PHYSFS_init (STR2CSTR(str));
+
+ if (result)
+ return Qtrue;
+
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::deinit
+ */
+VALUE physfs_deinit (VALUE self)
+{
+ if (PHYSFS_deinit ())
+ return Qtrue;
+
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::version
+ *
+ * return PhysicsFS::Version object
+ */
+VALUE physfs_version (VALUE self)
+{
+ char evalStr[200];
+ PHYSFS_Version ver;
+
+ PHYSFS_getLinkedVersion (&ver);
+
+ sprintf (evalStr, "PhysicsFS::Version.new %d, %d, %d",
+ ver.major, ver.minor, ver.patch);
+ return rb_eval_string (evalStr);
+}
+
+/*
+ * PhysicsFS::supported_archives
+ *
+ * return Array of PhysicsFS::ArchiveInfo objects
+ */
+VALUE physfs_supported_archives (VALUE self)
+{
+ const PHYSFS_ArchiveInfo **info = PHYSFS_supportedArchiveTypes();
+ VALUE klass = rb_const_get (modulePhysfs, rb_intern ("ArchiveInfo"));
+ VALUE ary = rb_ary_new ();
+ VALUE params[4];
+
+ while ( *info != 0 )
+ {
+ params[0] = rb_str_new2 ((*info)->extension);
+ params[1] = rb_str_new2 ((*info)->description);
+ params[2] = rb_str_new2 ((*info)->author);
+ params[3] = rb_str_new2 ((*info)->url);
+
+ rb_ary_push (ary, rb_class_new_instance (4, params, klass));
+ info++;
+ }
+
+ return ary;
+}
+
+/*
+ * PhysicsFS::last_error
+ *
+ * return string representation of last PhysicsFS error
+ */
+VALUE physfs_last_error (VALUE self)
+{
+ const char *last_error = PHYSFS_getLastError ();
+
+ if (last_error == 0)
+ last_error = "";
+
+ return rb_str_new2 (last_error);
+}
+
+/*
+ * PhysicsFS::dir_separator
+ *
+ * return platform directory separator
+ */
+VALUE physfs_dir_separator (VALUE self)
+{
+ return rb_str_new2 (PHYSFS_getDirSeparator ());
+}
+
+/*
+ * PhysicsFS::permit_symlinks boolValue
+ *
+ * turn symlinks support on/off
+ */
+VALUE physfs_permit_symlinks (VALUE self, VALUE allow)
+{
+ int p = 1;
+
+ if (allow == Qfalse || allow == Qnil)
+ p = 0;
+
+ PHYSFS_permitSymbolicLinks (p);
+ return Qtrue;
+}
+
+/*
+ * PhysicsFS::cdrom_dirs
+ *
+ * return Array of strings containing available CDs
+ */
+VALUE physfs_cdrom_dirs (VALUE self)
+{
+ char **cds = PHYSFS_getCdRomDirs();
+ char **i;
+ VALUE ary = rb_ary_new ();
+
+ for (i = cds; *i != 0; i++)
+ rb_ary_push (ary, rb_str_new2 (*i));
+
+ PHYSFS_freeList (cds);
+ return ary;
+}
+
+/*
+ * PhysicsFS::base_dir
+ *
+ * return base directory
+ */
+VALUE physfs_base_dir (VALUE self)
+{
+ const char *base_dir = PHYSFS_getBaseDir ();
+ if (base_dir == 0)
+ base_dir = "";
+
+ return rb_str_new2 (base_dir);
+}
+
+/*
+ * PhysicsFS::user_dir
+ *
+ * return user directory
+ */
+VALUE physfs_user_dir (VALUE self)
+{
+ const char *user_dir = PHYSFS_getBaseDir ();
+ if (user_dir == 0)
+ user_dir = "";
+
+ return rb_str_new2 (user_dir);
+}
+
+/*
+ * PhysicsFS::write_dir
+ *
+ * return write directory
+ */
+VALUE physfs_write_dir (VALUE self)
+{
+ const char *write_dir = PHYSFS_getWriteDir ();
+ if (write_dir == 0)
+ return Qnil;
+
+ return rb_str_new2 (write_dir);
+}
+
+/*
+ * PhysicsFS::write_dir= str
+ *
+ * set write directory to *str*
+ */
+VALUE physfs_set_write_dir (VALUE self, VALUE str)
+{
+ int result = PHYSFS_setWriteDir (STR2CSTR(str));
+
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::add_to_search_path str, append
+ *
+ * if append > 0 - append str to search path, otherwise prepend it
+ */
+VALUE physfs_add_search_path (VALUE self, VALUE str, VALUE append)
+{
+ int result = PHYSFS_addToSearchPath (STR2CSTR(str), FIX2INT(append));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::remove_from_search_path str
+ *
+ * removes str from search path
+ */
+VALUE physfs_remove_search_path (VALUE self, VALUE str)
+{
+ int result = PHYSFS_removeFromSearchPath (STR2CSTR(str));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::search_path
+ *
+ * return current search_path - as array of strings
+ */
+VALUE physfs_search_path (VALUE self)
+{
+ char **path = PHYSFS_getSearchPath ();
+ char **i;
+ VALUE ary = rb_ary_new ();
+
+ for (i = path ; *i != 0; i++)
+ rb_ary_push (ary, rb_str_new2 (*i));
+
+ PHYSFS_freeList (path);
+ return ary;
+}
+
+//
+VALUE physfs_setSaneConfig(VALUE self, VALUE org, VALUE app, VALUE ext,
+ VALUE includeCdroms, VALUE archivesFirst)
+{
+ int res = PHYSFS_setSaneConfig (STR2CSTR(org), STR2CSTR(app), STR2CSTR(ext),
+ RTEST(includeCdroms), RTEST(archivesFirst));
+ if (res)
+ return Qtrue;
+
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::mkdir newdir
+ *
+ * create new directory
+ */
+VALUE physfs_mkdir (VALUE self, VALUE newdir)
+{
+ int result = PHYSFS_mkdir (STR2CSTR(newdir));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::delete name
+ *
+ * delete file with name
+ */
+VALUE physfs_delete (VALUE self, VALUE name)
+{
+ int result = PHYSFS_delete (STR2CSTR(name));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::real_dir name
+ *
+ * return real directory (in search path) of a name
+ */
+VALUE physfs_real_dir (VALUE self, VALUE name)
+{
+ const char *path = PHYSFS_getRealDir (STR2CSTR(name));
+ if (path == 0)
+ return Qnil;
+
+ return rb_str_new2 (path);
+}
+
+/*
+ * PhysicsFS::enumerate dir
+ *
+ * list a dir from a search path
+ */
+VALUE physfs_enumerate (VALUE self, VALUE dir)
+{
+ char **files = PHYSFS_enumerateFiles (STR2CSTR(dir));
+ char **i;
+ VALUE ary = rb_ary_new ();
+
+ for (i = files; *i != 0; i++)
+ rb_ary_push (ary, rb_str_new2 (*i));
+
+ PHYSFS_freeList (files);
+ return ary;
+}
+
+/*
+ * PhysicsFS::exists? name
+ *
+ * does a file with name exist?
+ */
+VALUE physfs_exists (VALUE self, VALUE name)
+{
+ int result = PHYSFS_exists (STR2CSTR(name));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::is_directory? name
+ *
+ * return true if name is directory
+ */
+VALUE physfs_is_directory (VALUE self, VALUE name)
+{
+ int result = PHYSFS_isDirectory (STR2CSTR(name));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::is_symlink? name
+ *
+ * return true if name is symlink
+ */
+VALUE physfs_is_symlink (VALUE self, VALUE name)
+{
+ int result = PHYSFS_isSymbolicLink (STR2CSTR(name));
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::last_mod_time name
+ *
+ * return last modification time of a file
+ */
+VALUE physfs_last_mod_time (VALUE self, VALUE name)
+{
+ int result = PHYSFS_getLastModTime (STR2CSTR(name));
+
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::open_read name
+ *
+ * return +PhysicsFS::File+ ready for reading
+ */
+VALUE physfs_open_read (VALUE self, VALUE name)
+{
+ PHYSFS_file *file = PHYSFS_openRead (STR2CSTR(name));
+ return physfs_file_new (file);
+}
+
+/*
+ * PhysicsFS::open_write name
+ *
+ * return PhysicsFS::File ready for writing
+ */
+VALUE physfs_open_write (VALUE self, VALUE name)
+{
+ PHYSFS_file *file = PHYSFS_openWrite (STR2CSTR(name));
+ return physfs_file_new (file);
+}
+
+/*
+ * PhysicsFS::open_append name
+ *
+ * return PhysicsFS::File ready for appending
+ */
+VALUE physfs_open_append (VALUE self, VALUE name)
+{
+ PHYSFS_file *file = PHYSFS_openAppend (STR2CSTR(name));
+ return physfs_file_new (file);
+}
+
+void Init_physfs_so (void)
+{
+ modulePhysfs = rb_define_module ("PhysicsFS");
+
+ rb_define_singleton_method (modulePhysfs, "init_internal", physfs_init, 1);
+ rb_define_singleton_method (modulePhysfs, "deinit", physfs_deinit, 0);
+ rb_define_singleton_method (modulePhysfs, "version", physfs_version, 0);
+ rb_define_singleton_method (modulePhysfs, "supported_archives",
+ physfs_supported_archives, 0);
+ rb_define_singleton_method (modulePhysfs, "last_error",
+ physfs_last_error, 0);
+ rb_define_singleton_method (modulePhysfs, "dir_separator",
+ physfs_dir_separator, 0);
+ rb_define_singleton_method (modulePhysfs, "permit_symlinks",
+ physfs_permit_symlinks, 1);
+ rb_define_singleton_method (modulePhysfs, "cdrom_dirs",
+ physfs_cdrom_dirs, 0);
+ rb_define_singleton_method (modulePhysfs, "base_dir", physfs_base_dir, 0);
+ rb_define_singleton_method (modulePhysfs, "user_dir", physfs_user_dir, 0);
+
+ rb_define_singleton_method (modulePhysfs, "write_dir", physfs_write_dir, 0);
+ rb_define_singleton_method (modulePhysfs, "write_dir=",
+ physfs_set_write_dir, 1);
+
+ rb_define_singleton_method (modulePhysfs, "add_to_search_path",
+ physfs_add_search_path, 2);
+ rb_define_singleton_method (modulePhysfs, "remove_from_search_path",
+ physfs_remove_search_path, 1);
+ rb_define_singleton_method (modulePhysfs, "search_path",
+ physfs_search_path, 0);
+
+ rb_define_singleton_method (modulePhysfs, "set_sane_config",
+ physfs_setSaneConfig, 5);
+
+ rb_define_singleton_method (modulePhysfs, "mkdir", physfs_mkdir, 1);
+ rb_define_singleton_method (modulePhysfs, "delete", physfs_delete, 1);
+ rb_define_singleton_method (modulePhysfs, "real_dir",
+ physfs_real_dir, 1);
+ rb_define_singleton_method (modulePhysfs, "enumerate", physfs_enumerate, 1);
+ rb_define_singleton_method (modulePhysfs, "exists?", physfs_exists, 1);
+ rb_define_singleton_method (modulePhysfs, "is_directory?",
+ physfs_is_directory, 1);
+ rb_define_singleton_method (modulePhysfs, "is_symlink?",
+ physfs_is_symlink, 1);
+ rb_define_singleton_method (modulePhysfs, "last_mod_time",
+ physfs_last_mod_time, 1);
+
+ rb_define_singleton_method (modulePhysfs, "open_read",
+ physfs_open_read, 1);
+ rb_define_singleton_method (modulePhysfs, "open_write",
+ physfs_open_write, 1);
+ rb_define_singleton_method (modulePhysfs, "open_append",
+ physfs_open_append, 1);
+
+ init_physfs_file ();
+ init_sdl_rwops ();
+}
+
+/*
+// Local Variables:
+// mode: C
+// c-indentation-style: "stroustrup"
+// indent-tabs-mode: nil
+// End:
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_physfs.h Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,13 @@
+/*
+ * PhysicsFS - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#ifndef __RB__PHYSFS__H__
+#define __RB__PHYSFS__H__
+
+extern VALUE modulePhysfs;
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_physfs_file.c Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,226 @@
+/*
+ * PhysicsFS File abstraction - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#include "physfs.h"
+#include "ruby.h"
+
+#include "rb_physfs.h"
+#include "rb_physfs_file.h"
+#include "physfsrwops.h"
+
+VALUE classPhysfsFile;
+
+/*
+ * construct new PhysicsFS::File object
+ */
+VALUE physfs_file_new (PHYSFS_file *file)
+{
+ if (file == 0)
+ return Qnil;
+
+ return Data_Wrap_Struct (classPhysfsFile, 0, 0, file);
+}
+
+/*
+ * PhysicsFS::File#close
+ *
+ * Close the file. It's illegal to use the object after its closure.
+ */
+VALUE physfs_file_close (VALUE self)
+{
+ int result;
+ PHYSFS_file *file;
+ Data_Get_Struct (self, PHYSFS_file, file);
+
+ if (file == 0)
+ return Qfalse;
+
+ result = PHYSFS_close (file);
+ DATA_PTR(self) = 0;
+
+ if (result)
+ return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::File#read obj_size, num_objects
+ *
+ * Read *objCount* objects which are *objSize* each.
+ * return String instance containing raw data or nil if failure.
+ * #length of string will reflect real number of objects read.
+ */
+VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount)
+{
+ int objRead;
+ void *buffer;
+ VALUE result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil; //wasted file - no read possible
+
+ buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
+ if (buffer == 0)
+ return Qnil;
+
+ objRead = PHYSFS_read (file, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
+ if (objRead == -1)
+ {
+ free (buffer);
+ return Qnil;
+ }
+
+ result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
+ free (buffer);
+ return result;
+}
+
+/*
+ * PhysicsFS::File#write buffer, obj_size, num_objects
+ *
+ * return nil on failure or number of objects written.
+ */
+VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount)
+{
+ int result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ result = PHYSFS_write (file, STR2CSTR(buf),
+ FIX2UINT(objSize), FIX2UINT(objCount));
+ if (result == -1)
+ return Qnil;
+
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::File#eof?
+ */
+VALUE physfs_file_eof (VALUE self)
+{
+ int result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ result = PHYSFS_eof (file);
+
+ if (result)
+ return Qtrue;
+
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::File#tell
+ *
+ * tells current position in file
+ */
+VALUE physfs_file_tell (VALUE self)
+{
+ int result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ result = PHYSFS_tell (file);
+
+ if (result == -1)
+ return Qnil;
+
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::File#seek pos
+ *
+ * seek to pos in file
+ */
+VALUE physfs_file_seek (VALUE self, VALUE pos)
+{
+ int result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ result = PHYSFS_seek (file, FIX2LONG(pos));
+
+ if (result)
+ return Qtrue;
+
+ return Qfalse;
+}
+
+/*
+ * PhysicsFS::File#length
+ */
+VALUE physfs_file_length (VALUE self)
+{
+ int result;
+ PHYSFS_file *file;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ result = PHYSFS_fileLength (file);
+
+ if (result == -1)
+ return Qnil;
+
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::File#to_rwops
+ *
+ * File object is converted to RWops object.
+ * File object becomes unusable after that - every operation
+ * should be done through new-born RWops object.
+ */
+VALUE physfs_file_to_rwops (VALUE self)
+{
+ PHYSFS_file *file;
+ SDL_RWops *rwops;
+
+ Data_Get_Struct (self, PHYSFS_file, file);
+ if (file == 0)
+ return Qnil;
+
+ rwops = PHYSFSRWOPS_makeRWops (file);
+ if (rwops == 0)
+ return Qnil;
+
+ DATA_PTR(self) = 0; // oh, gosh, we've sacrificed ourselves!
+ return sdl_rwops_new (rwops);
+}
+
+void init_physfs_file (void)
+{
+ classPhysfsFile = rb_define_class_under (modulePhysfs, "File", rb_cObject);
+
+ rb_define_method (classPhysfsFile, "close", physfs_file_close, 0);
+ rb_define_method (classPhysfsFile, "eof?", physfs_file_eof, 0);
+ rb_define_method (classPhysfsFile, "tell", physfs_file_tell, 0);
+ rb_define_method (classPhysfsFile, "seek", physfs_file_seek, 1);
+ rb_define_method (classPhysfsFile, "length", physfs_file_length, 0);
+ rb_define_method (classPhysfsFile, "read", physfs_file_read, 2);
+ rb_define_method (classPhysfsFile, "write", physfs_file_write, 3);
+ rb_define_method (classPhysfsFile, "to_rwops", physfs_file_to_rwops, 0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_physfs_file.h Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,24 @@
+/*
+ * PhysicsFS File abstraction - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#ifndef __RB__PHYSFS__FILE__H__
+#define __RB__PHYSFS__FILE__H__
+
+extern VALUE classPhysfsFile;
+
+VALUE physfs_file_new (PHYSFS_file *file);
+VALUE physfs_file_close (VALUE self);
+VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount);
+VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount);
+VALUE physfs_file_eof (VALUE self);
+VALUE physfs_file_tell (VALUE self);
+VALUE physfs_file_seek (VALUE self, VALUE pos);
+VALUE physfs_file_length (VALUE self);
+
+void init_physfs_file (void);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_sdl_rwops.c Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,162 @@
+/*
+ * SDL_RWops - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#include "SDL_rwops.h"
+#include "ruby.h"
+
+#include "rb_physfs.h"
+#include "rb_sdl_rwops.h"
+
+VALUE classRWops;
+
+/*
+ * RWops constructor
+ */
+VALUE sdl_rwops_new (SDL_RWops *ops)
+{
+ VALUE result;
+
+ if (ops == 0)
+ return Qnil;
+
+ result = Data_Wrap_Struct (classRWops, 0, SDL_FreeRW, ops);
+ return result;
+}
+
+/*
+ * PhysicsFS::RWops::from_file name, mode
+ *
+ * create RWops object from file
+ */
+VALUE sdl_rwops_from_file (VALUE self, VALUE name, VALUE mode)
+{
+ SDL_RWops *ops = SDL_RWFromFile(STR2CSTR(name), STR2CSTR(mode));
+ return sdl_rwops_new (ops);
+}
+
+/*
+ * PhysicsFS::RWops::from_memory string
+ *
+ * create RWops object from memory
+ */
+VALUE sdl_rwops_from_mem (VALUE self, VALUE str)
+{
+ int len = RSTRING(str)->len;
+ void *mem = STR2CSTR(str);
+ SDL_RWops *ops = SDL_RWFromMem(mem, len);
+
+ return sdl_rwops_new (ops);
+}
+
+/*
+ * PhysicsFS::RWops#seek offset, whence
+ *
+ * position RWops object
+ */
+VALUE sdl_rwops_seek (VALUE self, VALUE offset, VALUE whence)
+{
+ int result;
+ SDL_RWops *ops;
+
+ Data_Get_Struct (self, SDL_RWops, ops);
+ if (ops == 0)
+ return Qnil;
+
+ result = SDL_RWseek(ops, FIX2INT(offset), FIX2INT(whence));
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::RWops#close
+ *
+ * close RWops. No use of the object is possible after that.
+ */
+VALUE sdl_rwops_close (VALUE self)
+{
+ int result;
+ SDL_RWops *ops;
+
+ Data_Get_Struct (self, SDL_RWops, ops);
+ if (ops == 0)
+ return Qnil;
+
+ result = SDL_RWclose (ops);
+ DATA_PTR(self) = 0;
+
+ return INT2FIX(result);
+}
+
+/*
+ * PhysicsFS::RWops#read
+ *
+ * read from RWops object objCount objSize'd entities.
+ * return string containing raw data or nil
+ */
+VALUE sdl_rwops_read (VALUE self, VALUE objSize, VALUE objCount)
+{
+ int objRead;
+ void *buffer;
+ VALUE result;
+ SDL_RWops *ops;
+
+ Data_Get_Struct (self, SDL_RWops, ops);
+ if (ops == 0)
+ return Qnil;
+
+ buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
+ if (buffer == 0)
+ return Qnil;
+
+ objRead = SDL_RWread (ops, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
+ if (objRead == -1)
+ {
+ free (buffer);
+ return Qnil;
+ }
+
+ result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
+ free (buffer);
+ return result;
+}
+
+/*
+ * PhysicsFS::RWops#write buffer, size, n
+ *
+ * write raw string containing n objects size length each.
+ * return number of objects written or nil
+ */
+VALUE sdl_rwops_write (VALUE self, VALUE buffer, VALUE size, VALUE n)
+{
+ int result;
+ SDL_RWops *ops;
+
+ Data_Get_Struct (self, SDL_RWops, ops);
+ if (ops == 0)
+ return Qnil;
+
+ result = SDL_RWwrite (ops, STR2CSTR(buffer), FIX2INT(size), FIX2INT(n));
+
+ if (result == -1)
+ return Qnil;
+
+ return INT2FIX(result);
+}
+
+void init_sdl_rwops (void)
+{
+ classRWops = rb_define_class_under (modulePhysfs, "RWops", rb_cObject);
+
+ rb_define_method (classRWops, "seek", sdl_rwops_seek, 2);
+ rb_define_method (classRWops, "read", sdl_rwops_read, 2);
+ rb_define_method (classRWops, "write", sdl_rwops_write, 3);
+ rb_define_method (classRWops, "close", sdl_rwops_close, 0);
+
+ rb_define_singleton_method (classRWops, "from_file",
+ sdl_rwops_from_file, 2);
+ rb_define_singleton_method (classRWops, "from_memory",
+ sdl_rwops_from_mem, 1);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/rb_sdl_rwops.h Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,16 @@
+/*
+ * SDL_RWops - ruby interface
+ *
+ * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
+ * License:: LGPL
+ */
+
+#ifndef __RB__SDL__RWOPS__H__
+#define __RB__SDL__RWOPS__H__
+
+extern VALUE classRWops;
+
+VALUE sdl_rwops_new (SDL_RWops *ops);
+void init_sdl_rwops (void);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/physfs_rb/physfs/test/test_physfs.rb Mon Jul 21 03:46:50 2003 +0000
@@ -0,0 +1,358 @@
+#
+# PhysicsFS test program - mimics real physfs_test
+#
+require 'readline'
+require 'physfs'
+
+def die msg
+ puts "#{msg} - reason: #{PhysicsFS.last_error}"
+end
+
+#
+# parse line to command and args
+#
+def parse line
+ return false if line.nil?
+
+ if line.strip =~ /^(.*?) (?: (?:\s+(.*)) | $)/x
+ run $1, $2
+ else
+ false
+ end
+end
+
+#
+# parse command args
+#
+def parse_args args
+ args.strip!
+
+ dquoted = /^ " (.*?) "/x
+ squoted = /^ ' (.*?) '/x
+ unquoted = /^([^\s\'\"]+)/
+
+ regexps = [dquoted, squoted, unquoted]
+
+ result = []
+ while args != ""
+ regexps.each do |r|
+ if args =~ r
+ result << $1
+ args.sub! r, ""
+ args.sub!(/\s+/, "")
+ break
+ end
+ end
+ end
+ result
+end
+
+def usage cmd, prefix = "usage: "
+ print prefix
+ args = Commands::HELP[cmd]
+ if args
+ print cmd
+ args.scan(/\w+/).each {|x|
+ print " <#{x}>"
+ }
+ puts
+ else
+ puts %|#{cmd} (no arguments)|
+ end
+end
+
+# commands go below
+module Commands
+ HELP = {
+ "init" => "argv0",
+ "addarchive" => "archiveLocation append",
+ "removearchive" => "archiveLocation",
+ "enumerate" => "dirToEnumerate",
+ "ls" => "dirToEnumerate",
+ "setwritedir" => "newWriteDir",
+ "permitsymlinks" => "1or0",
+ "setsaneconfig" => "org appName arcExt includeCdRoms archivesFirst",
+ "mkdir" => "dirToMk",
+ "delete" => "dirToDelete",
+ "getrealdir" => "fileToFind",
+ "exists" => "fileToCheck",
+ "isdir" => "fileToCheck",
+ "issymlink" => "fileToCheck",
+ "cat" => "fileToCat",
+ "filelength" => "fileToCheck",
+ "append" => "fileToAppend",
+ "write" => "fileToCreateOrTrash",
+ "getlastmodtime" => "fileToExamine"
+ }
+
+ def quit_cmd
+ exit
+ end
+
+ alias q_cmd quit_cmd
+
+ def help_cmd
+ commands = ::Commands.instance_methods.grep(/_cmd$/).sort
+ puts "Commands:"
+ commands.each do |c|
+ usage c.sub("_cmd", ""), " - "
+ end
+
+ true
+ end
+
+ def e val
+ if val
+ puts "Successful."
+ else
+ puts "Failure. reason: #{PhysicsFS.last_error}"
+ end
+ true
+ end
+
+ def init_cmd arg
+ e PhysicsFS.init(arg)
+ end
+
+ def deinit_cmd
+ e PhysicsFS.deinit
+ end
+
+ def addarchive_cmd archive, append
+ e PhysicsFS.add_to_search_path(archive, append)
+ end
+
+ def removearchive_cmd archive
+ e PhysicsFS.remove_from_search_path archive
+ end
+
+ def enumerate_cmd path
+ entries = PhysicsFS.enumerate(path)
+ entries.each {|x|
+ puts x
+ }
+ true
+ end
+
+ alias ls_cmd enumerate_cmd
+
+ def getlasterror_cmd
+ puts "Last error is [#{PhysicsFS.last_error}]"
+ true
+ end
+
+ def getdirsep_cmd
+ puts "Directory separator is [#{PhysicsFS.dir_separator}]"
+ true
+ end
+
+ def getcdromdirs_cmd
+ dirs = PhysicsFS.cdrom_dirs
+ dirs.each {|x|
+ puts x
+ }
+ puts " total [#{dirs.length}] drives."
+ true
+ end
+
+ def getsearchpath_cmd
+ spath = PhysicsFS.search_path
+ spath.each {|x|
+ puts x
+ }
+ puts "total [#{spath.length}] directories."
+ true
+ end
+
+ def getbasedir_cmd
+ dir = PhysicsFS.base_dir
+ puts dir if dir
+ true
+ end
+
+ def getuserdir_cmd
+ puts PhysicsFS.user_dir
+ true
+ end
+
+ def getwritedir_cmd
+ dir = PhysicsFS.write_dir
+ if dir
+ puts "Write directory is [#{dir}]."
+ else
+ puts "No write directory defined."
+ end
+ true
+ end
+
+ def setwritedir_cmd dir
+ e(PhysicsFS.write_dir = dir)
+ end
+
+ def permitsymlinks_cmd val
+ if val.to_i == 1
+ PhysicsFS.permit_symlinks true
+ puts "Symlinks are now permitted"
+ else
+ PhysicsFS.permit_symlinks false
+ puts "Symlinks are now forbidden"
+ end
+ true
+ end
+
+ def setsaneconfig_cmd org, appname, ext, includeCdroms, archivesFirst
+ includeCdroms = includeCdroms.to_i == 1
+ archiveFirst = archivesFirst == 1
+ e PhysicsFS.set_sane_config(org, appname, ext, includeCdroms, archivesFirst)
+ end
+
+ def mkdir_cmd dir
+ e PhysicsFS.mkdir(dir)
+ end
+
+ def delete_cmd dir
+ e PhysicsFS.delete(dir)
+ end
+
+ def getrealdir_cmd file
+ dir = PhysicsFS.real_dir file
+ if dir
+ puts "Found at [#{dir}]"
+ else
+ puts "Not found."
+ end
+ true
+ end
+
+ def exists_cmd file
+ if PhysicsFS.exists? file
+ puts "File exists"
+ else
+ puts "File does not exist"
+ end
+ true
+ end
+
+ def isdir_cmd file
+ if PhysicsFS.is_directory? file
+ puts "File is a directory"
+ else
+ puts "File is NOT a directory"
+ end
+ true
+ end
+
+ def issymlink_cmd file
+ if PhysicsFS.is_symlink? file
+ puts "File is a symlink"
+ else
+ puts "File is NOT a symlink"
+ end
+ true
+ end
+
+ def cat_cmd filename
+ file = PhysicsFS.open_read filename
+ if file.nil?
+ puts "failed to open. reason: #{PhysicsFS.last_error}"
+ return true
+ end
+
+ puts file.cat
+ true
+ end
+
+ def filelength_cmd filename
+ file = PhysicsFS.open_read filename
+ if file.nil?
+ puts "failed to open. reason: #{PhysicsFS.last_error}"
+ return true
+ end
+
+ puts file.length
+ file.close
+ true
+ end
+
+ WRITE_STR = "Rubyfied PhysicsFS works just fine.\n\n"
+
+ def append_cmd filename
+ file = PhysicsFS.open_append filename
+ if file.nil?
+ puts "failed to open. reason: #{PhysicsFS.last_error}"
+ return true
+ end
+
+ file.write WRITE_STR, 1, WRITE_STR.length
+ file.close
+ true
+ end
+
+ def write_cmd filename
+ file = PhysicsFS.open_write filename
+ if file.nil?
+ puts "failed to open. reason: #{PhysicsFS.last_error}"
+ return true
+ end
+
+ file.write_str WRITE_STR
+ file.close
+ true
+ end
+
+ def getlastmodtime_cmd filename
+ t = PhysicsFS.last_mod_time filename
+ if t == -1
+ puts "failed to determin. reason: #{PhysicsFS.last_error}"
+ else
+ puts "Last modified: #{Time.at(t)}"
+ end
+ true
+ end
+end
+
+include Commands
+
+def run command, args
+ if args
+ args = parse_args args
+ else
+ args = []
+ end
+
+ begin
+ cmd = method "#{command}_cmd"
+ if args.length == cmd.arity
+ return cmd.call *args
+ else
+ usage command
+ true
+ end
+ rescue NameError
+ puts 'Unknown command. Enter "help" for instructions.'
+ true
+ end
+end
+
+if __FILE__ == $0
+
+ PhysicsFS.init($0) or die "PhysicsFS init failed"
+
+ puts "PhysicsFS version: #{PhysicsFS.version}"
+ puts
+
+ puts "Supported archives: "
+ puts PhysicsFS.supported_archives
+ puts
+
+ puts 'Enter commands. Enter "help" for instructions.'
+
+ loop {
+ line = Readline::readline "physfs_rb> ", true
+ break unless parse line
+ }
+end
+
+
+
+