aboutsummaryrefslogtreecommitdiff
path: root/common/fmplayer_file_gio.c
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-03-27 23:32:18 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-03-27 23:32:18 +0900
commit0073f2b8befc6163f2970cb7a01e75fffc95994e (patch)
treeaab8d559720269e65b5ad05c07d98a865ff14e57 /common/fmplayer_file_gio.c
parente2ee18347d45e4620a8279afb8b0bc4a809441ef (diff)
refactor common file loading functions
Diffstat (limited to 'common/fmplayer_file_gio.c')
-rw-r--r--common/fmplayer_file_gio.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/common/fmplayer_file_gio.c b/common/fmplayer_file_gio.c
new file mode 100644
index 0000000..053e4ae
--- /dev/null
+++ b/common/fmplayer_file_gio.c
@@ -0,0 +1,120 @@
+#include "common/fmplayer_file.h"
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void *fileread(GFile *f, size_t maxsize, size_t *filesize, enum fmplayer_file_error *error) {
+ GFileInfo *finfo = 0;
+ GFileInputStream *fstream = 0;
+ void *buf = 0;
+ finfo = g_file_query_info(f, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, 0, 0);
+ if (!finfo) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ gsize filelen;
+ {
+ goffset sfilelen = g_file_info_get_size(finfo);
+ if (sfilelen < 0) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ filelen = sfilelen;
+ }
+ if (maxsize && (filelen > maxsize)) {
+ if (error) *error = FMPLAYER_FILE_ERR_BADFILE_SIZE;
+ goto err;
+ }
+ fstream = g_file_read(f, 0, 0);
+ if (!fstream) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ buf = malloc(filelen);
+ if (!buf) {
+ if (error) *error = FMPLAYER_FILE_ERR_NOMEM;
+ goto err;
+ }
+ gsize fileread;
+ g_input_stream_read_all(G_INPUT_STREAM(fstream), buf, filelen, &fileread, 0, 0);
+ if (fileread != filelen) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ *filesize = filelen;
+ g_object_unref(G_OBJECT(fstream));
+ g_object_unref(G_OBJECT(finfo));
+ return buf;
+err:
+ free(buf);
+ if (fstream) g_object_unref(G_OBJECT(fstream));
+ if (finfo) g_object_unref(G_OBJECT(finfo));
+ return 0;
+}
+
+void *fmplayer_fileread(const void *pathptr, const char *pcmname, const char *extension,
+ size_t maxsize, size_t *filesize, enum fmplayer_file_error *error) {
+ GFile *file = 0, *dir = 0;
+ GFileEnumerator *direnum = 0;
+ char *pcmnamebuf = 0;
+ const char *uri = pathptr;
+ file = g_file_new_for_uri(uri);
+ if (!pcmname) {
+ void *buf = fileread(file, maxsize, filesize, error);
+ g_object_unref(G_OBJECT(file));
+ return buf;
+ }
+ if (extension) {
+ size_t namebuflen = strlen(pcmname) + strlen(extension) + 1;
+ pcmnamebuf = malloc(namebuflen);
+ if (!pcmnamebuf) goto err;
+ strcpy(pcmnamebuf, pcmname);
+ strcat(pcmnamebuf, extension);
+ pcmname = pcmnamebuf;
+ }
+
+ dir = g_file_get_parent(file);
+ if (!dir) {
+ if (error) *error = FMPLAYER_FILE_ERR_NOMEM;
+ goto err;
+ }
+ direnum = g_file_enumerate_children(dir,
+ G_FILE_ATTRIBUTE_STANDARD_NAME,
+ G_FILE_QUERY_INFO_NONE,
+ 0, 0);
+ if (!direnum) {
+ if (error) *error = FMPLAYER_FILE_ERR_NOMEM;
+ goto err;
+ }
+ for (;;) {
+ GFileInfo *info;
+ GFile *pcmfile;
+ if (!g_file_enumerator_iterate(direnum, &info, &pcmfile, 0, 0)) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ if (!info || !pcmfile) {
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+ goto err;
+ }
+ if (!strcasecmp(g_file_info_get_name(info), pcmname)) {
+ void *buf = fileread(pcmfile, maxsize, filesize, error);
+ g_object_unref(G_OBJECT(direnum));
+ g_object_unref(G_OBJECT(dir));
+ g_object_unref(G_OBJECT(file));
+ free(pcmnamebuf);
+ return buf;
+ }
+ }
+ if (error) *error = FMPLAYER_FILE_ERR_FILEIO;
+err:
+ if (direnum) g_object_unref(G_OBJECT(direnum));
+ if (dir) g_object_unref(G_OBJECT(dir));
+ g_object_unref(G_OBJECT(file));
+ free(pcmnamebuf);
+ return 0;
+}
+
+void *fmplayer_path_dup(const void *path) {
+ return strdup(path);
+}