summaryrefslogtreecommitdiff
path: root/vfs_stdio.c
blob: a6fb5dbaf2d51daced2ec4da092374670d680ad5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
    DeaDBeeF - ultimate music player for GNU/Linux systems with X11
    Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
#include "deadbeef.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

static DB_functions_t *deadbeef;
typedef struct {
    DB_vfs_t *vfs;
    FILE *stream;
} STDIO_FILE;

static DB_vfs_t plugin;

static DB_FILE *
stdio_open (const char *fname) {
    if (!memcmp (fname, "file://", 7)) {
        fname += 7;
    }
    FILE *file = fopen (fname, "rb");
    if (!file) {
        return NULL;
    }
    STDIO_FILE *fp = malloc (sizeof (STDIO_FILE));
    fp->vfs = &plugin;
    fp->stream = file;
    return (DB_FILE*)fp;
}

static void
stdio_close (DB_FILE *stream) {
    assert (stream);
    fclose (((STDIO_FILE *)stream)->stream);
    free (stream);
}

static size_t
stdio_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
    assert (stream);
    assert (ptr);
    return fread (ptr, size, nmemb, ((STDIO_FILE *)stream)->stream);
}

static int
stdio_seek (DB_FILE *stream, int64_t offset, int whence) {
    assert (stream);
    return fseek (((STDIO_FILE *)stream)->stream, offset, whence);
}

static int64_t
stdio_tell (DB_FILE *stream) {
    assert (stream);
    return ftell (((STDIO_FILE *)stream)->stream);
}

static void
stdio_rewind (DB_FILE *stream) {
    assert (stream);
    rewind (((STDIO_FILE *)stream)->stream);
}

static int64_t
stdio_getlength (DB_FILE *stream) {
    assert (stream);
    STDIO_FILE *f = (STDIO_FILE *)stream;
    size_t pos = ftell (f->stream);
    fseek (f->stream, 0, SEEK_END);
    size_t sz = ftell (f->stream);
    fseek (f->stream, pos, SEEK_SET);
    return sz;
}

const char *
stdio_get_content_type (DB_FILE *stream) {
    return NULL;
}

// standard stdio vfs
static DB_vfs_t plugin = {
    DB_PLUGIN_SET_API_VERSION
    .plugin.version_major = 0,
    .plugin.version_minor = 1,
    .plugin.type = DB_PLUGIN_VFS,
    .plugin.name = "stdio vfs",
    .plugin.descr = "Standard IO plugin",
    .plugin.author = "Alexey Yakovenko",
    .plugin.email = "waker@users.sourceforge.net",
    .plugin.website = "http://deadbeef.sf.net",
    .open = stdio_open,
    .close = stdio_close,
    .read = stdio_read,
    .seek = stdio_seek,
    .tell = stdio_tell,
    .rewind = stdio_rewind,
    .getlength = stdio_getlength,
    .get_content_type = stdio_get_content_type,
    .scheme_names = NULL // this is NULL because that's a fallback vfs, used when no other matching vfs plugin found
};

DB_plugin_t *
stdio_load (DB_functions_t *api) {
    deadbeef = api;
    return DB_PLUGIN (&plugin);
}