[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49810] branches/asset-browser/source/ blender/blenlib: filebrowser:

Andrea Weikert elubie at gmx.net
Sat Aug 11 16:59:07 CEST 2012


Revision: 49810
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49810
Author:   elubie
Date:     2012-08-11 14:59:07 +0000 (Sat, 11 Aug 2012)
Log Message:
-----------
filebrowser:
* new directory read function (not used yet) to be later used with new contentlist (will be committed later)

Modified Paths:
--------------
    branches/asset-browser/source/blender/blenlib/BLI_directory.h
    branches/asset-browser/source/blender/blenlib/intern/directory.c

Modified: branches/asset-browser/source/blender/blenlib/BLI_directory.h
===================================================================
--- branches/asset-browser/source/blender/blenlib/BLI_directory.h	2012-08-11 14:40:09 UTC (rev 49809)
+++ branches/asset-browser/source/blender/blenlib/BLI_directory.h	2012-08-11 14:59:07 UTC (rev 49810)
@@ -37,6 +37,29 @@
 extern "C" {
 #endif
 
+#include "MEM_sys_types.h"
+
+#if defined(WIN32) && !defined(FREE_WINDOWS)
+typedef unsigned int mode_t;
+#endif
+
+struct direntry_filelist {
+	mode_t  type;
+	time_t  mtime;
+	int64_t size;
+	char   *relname;
+	char   *path;
+	char    str_size[16];
+	char    str_mode1[4];
+	char    str_mode2[4];
+	char    str_mode3[4];
+	char    str_owner[16];
+	char    str_time[8];
+	char    str_date[16];
+};
+
+struct ContentList;
+
 /* Directories */
 
 /* returns 1 if the given path is a directory, 0 otherwise */
@@ -56,8 +79,30 @@
 
 /* --- directory reading ---  */
 
-/* allocates memory that needs to be freed once struct direntry **files is no longer needed 
-   use BLI_dir_dispose for this! */
+
+/** callback function that requests allocation of num_entries in the user supplied data structure to hold the directory 
+ *  @return the number of successfully allocated entries 
+ */
+typedef int (*dir_allocFunc)(struct ContentList *dirlist, size_t num_entries);
+
+/** callback function that passes the data for one entry to the data structure */
+typedef void (*dir_set_entryFunc)(struct ContentList *dirlist, void *entry, int entry_nr);
+
+/** callback function that requests sorting of the user defined data structure for the directory entries */
+typedef void (dir_sortFunc)(struct ContentList *dirlist, int col, short ascending);
+
+/** read the contents of a directory given by the path 
+ * The user of this function must supply a valid pointer to a data structure for holding the
+ * directory entries. 
+ * @param path - the path of the directory to read
+ * @param dirlist - user defined structure to hold the entries
+ * @param f_alloc - user supplied function to allocate the requested number of entries.
+ * @param f_set_entry - user supplied callback to set one entry in the data structure for the directory
+ * @param f_sort_dir - user supplied callback to sort the entries
+ */
+void BLI_dir_contents_ng(const char *path, struct ContentList *dirlist, dir_allocFunc f_alloc, dir_set_entryFunc f_set_entry, dir_sortFunc f_sort_dir);
+
+/* DEPRECATED - old functions */
 void BLI_dir_contents(const char *dirname, struct direntry **files, int *num_files);
 void BLI_dir_dispose(struct direntry *filelist, unsigned int num_files);
 

Modified: branches/asset-browser/source/blender/blenlib/intern/directory.c
===================================================================
--- branches/asset-browser/source/blender/blenlib/intern/directory.c	2012-08-11 14:40:09 UTC (rev 49809)
+++ branches/asset-browser/source/blender/blenlib/intern/directory.c	2012-08-11 14:59:07 UTC (rev 49810)
@@ -424,3 +424,177 @@
 	}
 	MEM_freeN(files);
 }
+
+
+static void filelist_assign_from_stat(struct direntry_filelist *file, const char *path)
+{
+	char buf[1024];
+#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
+	struct _stat64 s;
+#elif defined(__MINGW32__)
+	struct _stati64 s;
+#else
+	struct  stat s;
+#endif
+
+	BLI_join_dirfile(buf, 1024, path, file->relname);
+
+#ifdef WIN32
+	{
+		wchar_t * name_16 = alloc_utf16_from_8(buf, 0);
+#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500)
+		_wstat64(name_16, &s);
+#elif defined(__MINGW32__)
+		_stati64(name_16, &s);
+#endif
+		free(name_16);
+	}
+
+#else
+	stat(buf,&s);
+#endif
+
+	file->type = s.st_mode;
+	file->mtime = s.st_mtime;
+	file->size = s.st_size;
+
+#ifdef WIN32
+	strcpy(file->str_owner, "user");
+#else
+	{
+		struct passwd *pwuser;
+		pwuser = getpwuid(file->s.st_uid);
+		if (pwuser) {
+			BLI_strncpy(file->str_owner, pwuser->pw_name, sizeof(file->owner));
+		}
+		else {
+			BLI_snprintf(file->str_owner, sizeof(file->owner), "%d", file->s.st_uid);
+		}
+	}
+#endif
+
+
+}
+
+static void filelist_format_values(struct direntry_filelist *file)
+{
+	static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+	unsigned short mode = file->type;
+	time_t mtime = file->mtime;
+	int64_t size = file->size;
+	struct tm *tm;
+	time_t zero = 0;
+#ifdef WIN32
+	__int64 st_size;
+#else
+	off_t st_size;
+#endif
+
+#ifdef WIN32
+	BLI_strncpy(file->str_mode1, types[0], sizeof(file->str_mode1));
+	BLI_strncpy(file->str_mode2, types[0], sizeof(file->str_mode2));
+	BLI_strncpy(file->str_mode3, types[0], sizeof(file->str_mode3));
+#else
+	BLI_strncpy(file->str_mode1, types[(mode & 0700) >> 6], sizeof(file->str_mode1));
+	BLI_strncpy(file->str_mode2, types[(mode & 0070) >> 3], sizeof(file->str_mode2));
+	BLI_strncpy(file->str_mode3, types[(mode & 0007)], sizeof(file->str_mode3));
+	
+	if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2] == '-')) file->mode2[2] = 'l';
+
+	if (mode & (S_ISUID | S_ISGID)) {
+		if (file->mode1[2] == 'x') file->mode1[2] = 's';
+		else file->mode1[2] = 'S';
+
+		if (file->mode2[2] == 'x') file->mode2[2] = 's';
+	}
+
+	if (mode & S_ISVTX) {
+		if (file->mode3[2] == 'x') file->mode3[2] = 't';
+		else file->mode3[2] = 'T';
+	}
+#endif
+
+	tm = localtime(&file->mtime);
+
+	// prevent impossible dates in windows
+	if (tm == NULL) tm = localtime(&zero);
+	strftime(file->str_time, sizeof(file->str_time), "%H:%M", tm);
+	strftime(file->str_date, sizeof(file->str_date), "%d-%b-%y", tm);
+
+	/*
+	 * Seems st_size is signed 32-bit value in *nix and Windows.  This
+	 * will buy us some time until files get bigger than 4GB or until
+	 * everyone starts using __USE_FILE_OFFSET64 or equivalent.
+	 */
+	st_size = file->size;
+
+	if (st_size > 1024 * 1024 * 1024) {
+		BLI_snprintf(file->str_size, sizeof(file->str_size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024));
+	}
+	else if (st_size > 1024 * 1024) {
+		BLI_snprintf(file->str_size, sizeof(file->str_size), "%.1f MB", ((double)st_size) / (1024 * 1024));
+	}
+	else if (st_size > 1024) {
+		BLI_snprintf(file->str_size, sizeof(file->str_size), "%d KB", (int)(st_size / 1024));
+	}
+	else {
+		BLI_snprintf(file->str_size, sizeof(file->str_size), "%d B", (int)st_size);
+	}
+
+}
+
+void BLI_dir_contents_ng(const char *path, struct ContentList *dirlist, dir_allocFunc f_alloc, dir_set_entryFunc f_set_entry, dir_sortFunc f_sort_dir)
+{
+	DIR *dir;
+	struct ListBase dirbase={NULL, NULL};
+	struct dirent *fname;
+	struct dirlink *dlink;
+	struct direntry_filelist *file;
+	int numfiles = 0;
+	int totfiles = 0;
+	int actfile = 0;
+
+	if ((dir = (DIR *)opendir(path))) {
+		while ((fname = (struct dirent *) readdir(dir)) != NULL) {
+			dlink = (struct dirlink *)MEM_callocN(sizeof(struct dirlink), "dirlink");
+			if (dlink) {
+				dlink->name = BLI_strdup(fname->d_name);
+				BLI_addhead(&dirbase, dlink);
+				numfiles++;
+			}
+		}
+		closedir(dir);
+	}
+
+	if (numfiles <=0) return;
+
+	totfiles = f_alloc(dirlist, numfiles);
+
+	if (totfiles <= 0) {
+		dlink = (struct dirlink *) dirbase.first;
+		while (dlink) {
+			MEM_freeN(dlink->name);
+			dlink = dlink->next;
+		}
+		BLI_freelistN(&dirbase);
+		return;
+	}
+
+	dlink = (struct dirlink *) dirbase.first;
+	actfile=0;
+	while (dlink) {
+		file = (struct direntry_filelist *)MEM_callocN(sizeof(struct direntry_filelist), "directory file");
+
+		file->relname = dlink->name;
+		file->path = BLI_strdupcat(path, dlink->name);
+
+		filelist_assign_from_stat(file, path);
+		filelist_format_values(file);
+
+		f_set_entry(dirlist, file, actfile++);
+		dlink = dlink->next;
+	}
+	BLI_freelistN(&dirbase);
+
+	f_sort_dir(dirlist, 0, 1);
+}




More information about the Bf-blender-cvs mailing list