Forráskód Böngészése

libobs/util: Add function to generate formatted filenames

(Note: This commit also modifies the UI)

Being able to generate file names based upon a specification is useful
for more than just the UI; it can also be useful for things such as the
replay buffer where file names need to be generated on the fly.
jp9000 9 éve
szülő
commit
b277000f97
3 módosított fájl, 127 hozzáadás és 73 törlés
  1. 3 73
      UI/obs-app.cpp
  2. 121 0
      libobs/util/platform.c
  3. 3 0
      libobs/util/platform.h

+ 3 - 73
UI/obs-app.cpp

@@ -1110,79 +1110,9 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace)
 string GenerateSpecifiedFilename(const char *extension, bool noSpace,
 		const char *format)
 {
-	time_t now = time(0);
-	struct tm *cur_time;
-	cur_time = localtime(&now);
-
-	const size_t spec_count = 23;
-	const char *spec[][2] = {
-		{"%CCYY", "%Y"},
-		{"%YY",   "%y"},
-		{"%MM",   "%m"},
-		{"%DD",   "%d"},
-		{"%hh",   "%H"},
-		{"%mm",   "%M"},
-		{"%ss",   "%S"},
-		{"%%",    "%%"},
-
-		{"%a",    ""},
-		{"%A",    ""},
-		{"%b",    ""},
-		{"%B",    ""},
-		{"%d",    ""},
-		{"%H",    ""},
-		{"%I",    ""},
-		{"%m",    ""},
-		{"%M",    ""},
-		{"%p",    ""},
-		{"%S",    ""},
-		{"%y",    ""},
-		{"%Y",    ""},
-		{"%z",    ""},
-		{"%Z",    ""},
-	};
-
-	char convert[128] = {};
-	string sf = format;
-	string c;
-	size_t pos = 0, len;
-
-	while (pos < sf.length()) {
-		len = 0;
-		for (size_t i = 0; i < spec_count && len == 0; i++) {
-
-			if (sf.find(spec[i][0], pos) == pos) {
-				if (strlen(spec[i][1]))
-					strftime(convert, sizeof(convert),
-							spec[i][1], cur_time);
-				else
-					strftime(convert, sizeof(convert),
-							spec[i][0], cur_time);
-
-				len = strlen(spec[i][0]);
-
-				c = convert;
-				if (c.length() && c.find_first_not_of(' ') !=
-						std::string::npos)
-					sf.replace(pos, len, convert);
-			}
-		}
-
-		if (len)
-			pos += strlen(convert);
-		else if (!len && sf.at(pos) == '%')
-			sf.erase(pos,1);
-		else
-			pos++;
-	}
-
-	if (noSpace)
-		replace(sf.begin(), sf.end(), ' ', '_');
-
-	sf += '.';
-	sf += extension;
-
-	return (sf.length() < 256) ? sf : sf.substr(0, 255);
+	BPtr<char> filename = os_generate_formatted_filename(extension,
+			!noSpace, format);
+	return string(filename);
 }
 
 vector<pair<string, string>> GetLocaleNames()

+ 121 - 0
libobs/util/platform.c

@@ -16,6 +16,7 @@
 
 #define _FILE_OFFSET_BITS 64
 
+#include <time.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <locale.h>
@@ -657,3 +658,123 @@ const char *os_get_path_extension(const char *path)
 
 	return path + pos;
 }
+
+static inline bool valid_string(const char *str)
+{
+	while (str && *str) {
+		if (*(str++) != ' ')
+			return true;
+	}
+
+	return false;
+}
+
+static void replace_text(struct dstr *str, size_t pos, size_t len,
+		const char *new_text)
+{
+	struct dstr front = {0};
+	struct dstr back = {0};
+
+	dstr_left(&front, str, pos);
+	dstr_right(&back, str, pos + len);
+	dstr_copy_dstr(str, &front);
+	dstr_cat(str, new_text);
+	dstr_cat_dstr(str, &back);
+	dstr_free(&front);
+	dstr_free(&back);
+}
+
+static void erase_ch(struct dstr *str, size_t pos)
+{
+	struct dstr new_str = {0};
+	dstr_left(&new_str, str, pos);
+	dstr_cat(&new_str, str->array + pos + 1);
+	dstr_free(str);
+	*str = new_str;
+}
+
+char *os_generate_formatted_filename(const char *extension, bool space,
+		const char *format)
+{
+	time_t now = time(0);
+	struct tm *cur_time;
+	cur_time = localtime(&now);
+
+	const size_t spec_count = 23;
+	static const char *spec[][2] = {
+		{"%CCYY", "%Y"},
+		{"%YY",   "%y"},
+		{"%MM",   "%m"},
+		{"%DD",   "%d"},
+		{"%hh",   "%H"},
+		{"%mm",   "%M"},
+		{"%ss",   "%S"},
+		{"%%",    "%%"},
+
+		{"%a",    ""},
+		{"%A",    ""},
+		{"%b",    ""},
+		{"%B",    ""},
+		{"%d",    ""},
+		{"%H",    ""},
+		{"%I",    ""},
+		{"%m",    ""},
+		{"%M",    ""},
+		{"%p",    ""},
+		{"%S",    ""},
+		{"%y",    ""},
+		{"%Y",    ""},
+		{"%z",    ""},
+		{"%Z",    ""},
+	};
+
+	char convert[128] = {0};
+	struct dstr sf;
+	struct dstr c = {0};
+	size_t pos = 0;
+
+	dstr_init_copy(&sf, format);
+
+	while (pos < sf.len) {
+		for (size_t i = 0; i < spec_count && !convert[0]; i++) {
+			size_t len = strlen(spec[i][0]);
+
+			const char *cmp = sf.array + pos;
+
+			if (astrcmp_n(cmp, spec[i][0], len) == 0) {
+				if (strlen(spec[i][1]))
+					strftime(convert, sizeof(convert),
+							spec[i][1], cur_time);
+				else
+					strftime(convert, sizeof(convert),
+							spec[i][0], cur_time);
+
+
+				dstr_copy(&c, convert);
+				if (c.len && valid_string(c.array))
+					replace_text(&sf, pos, len, convert);
+			}
+		}
+
+		if (convert[0]) {
+			pos += strlen(convert);
+			convert[0] = 0;
+		} else if (!convert[0] && sf.array[pos] == '%') {
+			erase_ch(&sf, pos);
+		} else {
+			pos++;
+		}
+	}
+
+	if (!space)
+		dstr_replace(&sf, " ", "_");
+
+	dstr_cat_ch(&sf, '.');
+	dstr_cat(&sf, extension);
+	dstr_free(&c);
+
+	if (sf.len > 255)
+		dstr_mid(&sf, &sf, 0, 255);
+
+	return sf.array;
+}

+ 3 - 0
libobs/util/platform.h

@@ -162,6 +162,9 @@ EXPORT int os_mkdirs(const char *path);
 EXPORT int os_rename(const char *old_path, const char *new_path);
 EXPORT int os_copyfile(const char *file_in, const char *file_out);
 
+EXPORT char *os_generate_formatted_filename(const char *extension, bool space,
+		const char *format);
+
 struct os_inhibit_info;
 typedef struct os_inhibit_info os_inhibit_t;