Remove SOL body flags
[neverball] / share / fs.c
index 1918f3c..fd75cbf 100644 (file)
@@ -7,6 +7,7 @@
 #include "fs.h"
 #include "dir.h"
 #include "array.h"
+#include "common.h"
 
 /*
  * This file implements the virtual file system layer.  Most file
@@ -25,7 +26,13 @@ struct fs_file
 
 int fs_init(const char *argv0)
 {
-    return PHYSFS_init(argv0);
+    if (PHYSFS_init(argv0))
+    {
+        PHYSFS_permitSymbolicLinks(1);
+        return 1;
+    }
+
+    return 0;
 }
 
 int fs_quit(void)
@@ -33,6 +40,11 @@ int fs_quit(void)
     return PHYSFS_deinit();
 }
 
+const char *fs_error(void)
+{
+    return PHYSFS_getLastError();
+}
+
 /* -------------------------------------------------------------------------- */
 
 const char *fs_base_dir(void)
@@ -50,6 +62,11 @@ int fs_set_write_dir(const char *path)
     return PHYSFS_setWriteDir(path);
 }
 
+const char *fs_get_write_dir(void)
+{
+    return PHYSFS_getWriteDir();
+}
+
 /* -------------------------------------------------------------------------- */
 
 Array fs_dir_scan(const char *path, int (*filter)(struct dir_item *))
@@ -182,6 +199,11 @@ int fs_eof(fs_file fh)
     return PHYSFS_eof(fh->handle);
 }
 
+int fs_length(fs_file fh)
+{
+    return PHYSFS_fileLength(fh->handle);
+}
+
 /* -------------------------------------------------------------------------- */
 
 /*
@@ -225,32 +247,24 @@ int fs_add_path_with_archives(const char *path)
 
 /* -------------------------------------------------------------------------- */
 
-static void copy_file(fs_file src, fs_file dst)
-{
-    char buff[256];
-    int  size;
-
-    while ((size = fs_read(buff, 1, sizeof (buff), src)) > 0)
-        fs_write(buff, 1, size, dst);
-}
-
 int fs_rename(const char *src, const char *dst)
 {
-    fs_file fin, fout;
-    int copied = 0;
+    const char *write_dir;
+    char *real_src, *real_dst;
+    int rc = 0;
 
-    if ((fin = fs_open(src, "r")))
+    if ((write_dir = fs_get_write_dir()))
     {
-        if ((fout = fs_open(dst, "w")))
-        {
-            copy_file(fin, fout);
-            copied = 1;
-            fs_close(fout);
-        }
-        fs_close(fin);
+        real_src = concat_string(write_dir, "/", src, NULL);
+        real_dst = concat_string(write_dir, "/", dst, NULL);
+
+        rc = file_rename(real_src, real_dst);
+
+        free(real_src);
+        free(real_dst);
     }
 
-    return copied && fs_remove(src);
+    return rc;
 }
 
 /* -------------------------------------------------------------------------- */
@@ -287,8 +301,10 @@ int fs_puts(const char *src, fs_file fh)
 char *fs_gets(char *dst, int count, fs_file fh)
 {
     char *s = dst;
-    char *cr = NULL;
-    int c = 0;
+    int c;
+
+    assert(dst);
+    assert(count > 0);
 
     if (fs_eof(fh))
         return NULL;
@@ -299,30 +315,28 @@ char *fs_gets(char *dst, int count, fs_file fh)
 
         *s = c;
 
-        /* Normalize possible CRLF and break. */
+        /* Keep a newline and break. */
 
         if (*s == '\n')
         {
-            if (cr + 1 == s)
-                *cr = '\n';
-            else
-                s++;
-
+            s++;
             break;
         }
 
-        /* Note carriage return. */
+        /* Ignore carriage returns. */
 
         if (*s == '\r')
-            cr = s;
+        {
+            count++;
+            s--;
+        }
 
         s++;
     }
 
-    if (count > 0)
-        *s = '\0';
+    *s = '\0';
 
-    return c < 0 ? NULL : dst;
+    return dst;
 }
 
 /* -------------------------------------------------------------------------- */
@@ -420,3 +434,33 @@ int fs_printf(fs_file fh, const char *fmt, ...)
 }
 
 /* -------------------------------------------------------------------------- */
+
+void *fs_load(const char *path, int *datalen)
+{
+    fs_file fh;
+    void *data;
+
+    data = NULL;
+
+    if ((fh = fs_open(path, "r")))
+    {
+        if ((*datalen = fs_length(fh)) > 0)
+        {
+            if ((data = malloc(*datalen)))
+            {
+                if (fs_read(data, *datalen, 1, fh) != 1)
+                {
+                    free(data);
+                    data = NULL;
+                    *datalen = 0;
+                }
+            }
+        }
+
+        fs_close(fh);
+    }
+
+    return data;
+}
+
+/* -------------------------------------------------------------------------- */