ucx update
[uwplayer.git] / application / utils.c
index 35b0ab5..a383a2e 100644 (file)
 
 #include "utils.h"
 
-#include <ucx/string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <cx/string.h>
 
 
 char* util_concat_path(const char *url_base, const char *p) {
-    sstr_t base = sstr((char*)url_base);
-    sstr_t path;
+    cxstring base = cx_str(url_base);
+    cxstring path;
     if(p) {
-        path = sstr((char*)p);
+        path = cx_str(p);
     } else {
-        path = sstrn("", 0);
+        path = cx_strn("", 0);
     }
     
     int add_separator = 0;
@@ -45,12 +53,122 @@ char* util_concat_path(const char *url_base, const char *p) {
         }
     }
     
-    sstr_t url;
+    cxmutstr url;
     if(add_separator) {
-        url = sstrcat(3, base, sstr("/"), path);
+        url = cx_strcat(3, base, cx_strn("/", 1), path);
     } else {
-        url = sstrcat(2, base, path);
+        url = cx_strcat(2, base, path);
     }
     
     return url.ptr;
 }
+
+const char* util_resource_name(const char *url) {
+    cxstring urlstr = cx_str(url);
+    if(urlstr.ptr[urlstr.length-1] == '/') {
+        urlstr.length--;
+    }
+    cxstring resname = cx_strrchr(urlstr, '/');
+    if(resname.length > 1) {
+        return resname.ptr+1;
+    } else {
+        return url;
+    }
+}
+
+char* util_parent_path(const char *path) {
+    const char *name = util_resource_name(path);
+    size_t namelen = strlen(name);
+    size_t pathlen = strlen(path);
+    size_t parentlen = pathlen - namelen;
+    char *parent = malloc(parentlen + 1);
+    memcpy(parent, path, parentlen);
+    parent[parentlen] = '\0';
+    return parent;
+}
+
+#define FIND_NEXT_MAX_FILES 2000
+
+typedef int (*cmpfnc)(const void *, const void *);
+
+int fcmp(const void *d1, const void *d2) {
+    const char **f1 = (const char **)d1;
+    const char **f2 = (const char **)d2;
+    int r = strcmp(*f1, *f2);
+    return r;
+}
+
+char* util_find_next_file(char *current_file) {
+    char *current_folder = util_parent_path(current_file);
+    const char *current_file_name = util_resource_name(current_file);
+    DIR *dir = opendir(current_folder);
+    if(!dir) {
+        fprintf(stderr, "Error: Cannot open directory '%s': %s\n", current_folder, strerror(errno));
+        free(current_folder);
+        return NULL;
+    }
+    
+    size_t nfiles = 0;
+    size_t falloc = 64;
+    char **files = calloc(falloc, sizeof(char*));
+    
+    int abort = 0;
+    struct dirent *ent;
+    while((ent = readdir(dir))) {
+        if(ent->d_name[0] == '.') {
+            // skip '.', '..' and dot-files
+            continue;
+        }
+        
+        // stat
+        char *abs_path = util_concat_path(current_folder, ent->d_name);
+        struct stat s;
+        int r = stat(abs_path, &s);
+        free(abs_path);
+        if(r) {
+            continue;
+        }
+        
+        // we only want regular files
+        if(!S_ISREG(s.st_mode)) {
+            continue;
+        }
+        
+        // add file
+        if(nfiles >= falloc) {
+            falloc *= 2;
+            if(falloc > FIND_NEXT_MAX_FILES) {
+                abort = 1;
+                break;
+            }
+            files = realloc(files, falloc * sizeof(char*));
+        }
+        files[nfiles] = strdup(ent->d_name);
+        
+        nfiles++;
+    }
+    
+    char *result = NULL;
+    if(!abort) {
+        qsort(files, nfiles, sizeof(char*), fcmp);
+        // search array for current file and return the successor
+        for(int i=0;i<nfiles;i++) {
+            char *c = files[i];
+            if(!strcmp(files[i], current_file_name)) {
+                if(i + 1 < nfiles) {
+                    result = util_concat_path(current_folder, files[i+1]);
+                    break;
+                }
+            }
+        }
+    }
+    
+    closedir(dir);
+    for(int i=0;i<nfiles;i++) {
+        free(files[i]);
+    }
+    free(files);
+    free(current_folder);
+    
+    return result;
+}