1 /*
2 * vfs.h
3 * Copyright 2006-2013 Ariadne Conill, Daniel Barkalow, Ralf Ertzinger,
4 * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions, and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions, and the following disclaimer in the documentation
14 * provided with the distribution.
15 *
16 * This software is provided "as is" and without any warranty, express or
17 * implied. In no event shall the authors be liable for any damages arising from
18 * the use of this software.
19 */
20 /**
21 * @file vfs.h
22 * Main API header for accessing Audacious VFS functionality.
23 * Provides functions for VFS transport registration and
24 * file access.
25 */
26
27 #ifndef LIBAUDCORE_VFS_H
28 #define LIBAUDCORE_VFS_H
29
30 #include <stdint.h>
31
32 #include <libaudcore/export.h>
33 #include <libaudcore/index.h>
34 #include <libaudcore/objects.h>
35
36 enum VFSFileTest
37 {
38 VFS_IS_REGULAR = (1 << 0),
39 VFS_IS_SYMLINK = (1 << 1),
40 VFS_IS_DIR = (1 << 2),
41 VFS_IS_EXECUTABLE = (1 << 3),
42 VFS_EXISTS = (1 << 4),
43 VFS_NO_ACCESS = (1 << 5)
44 };
45
46 enum VFSReadOptions
47 {
48 VFS_APPEND_NULL = (1 << 0),
49 VFS_IGNORE_MISSING = (1 << 1)
50 };
51
52 enum VFSSeekType
53 {
54 VFS_SEEK_SET = 0,
55 VFS_SEEK_CUR = 1,
56 VFS_SEEK_END = 2
57 };
58
59 #ifdef WANT_VFS_STDIO_COMPAT
60
61 #include <stdio.h>
62
from_vfs_seek_type(VFSSeekType whence)63 constexpr int from_vfs_seek_type(VFSSeekType whence)
64 {
65 return (whence == VFS_SEEK_SET)
66 ? SEEK_SET
67 : (whence == VFS_SEEK_CUR)
68 ? SEEK_CUR
69 : (whence == VFS_SEEK_END) ? SEEK_END : -1;
70 }
71
to_vfs_seek_type(int whence)72 constexpr VFSSeekType to_vfs_seek_type(int whence)
73 {
74 return (whence == SEEK_SET)
75 ? VFS_SEEK_SET
76 : (whence == SEEK_CUR)
77 ? VFS_SEEK_CUR
78 : (whence == SEEK_END) ? VFS_SEEK_END : (VFSSeekType)-1;
79 }
80
81 #endif // WANT_VFS_STDIO_COMPAT
82
83 // #undef POSIX functions/macros to avoid name conflicts
84 #undef fread
85 #undef fseek
86 #undef ftell
87 #undef fsize
88 #undef feof
89 #undef fwrite
90 #undef ftruncate
91 #undef fflush
92
93 class LIBAUDCORE_PUBLIC VFSImpl
94 {
95 public:
VFSImpl()96 VFSImpl() {}
~VFSImpl()97 virtual ~VFSImpl() {}
98
99 VFSImpl(const VFSImpl &) = delete;
100 VFSImpl & operator=(const VFSImpl &) = delete;
101
102 virtual int64_t fread(void * ptr, int64_t size, int64_t nmemb) = 0;
103 virtual int fseek(int64_t offset, VFSSeekType whence) = 0;
104
105 virtual int64_t ftell() = 0;
106 virtual int64_t fsize() = 0;
107 virtual bool feof() = 0;
108
109 virtual int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb) = 0;
110 virtual int ftruncate(int64_t length) = 0;
111 virtual int fflush() = 0;
112
get_metadata(const char * field)113 virtual String get_metadata(const char * field) { return String(); }
114 };
115
116 class VFSFile
117 {
118 public:
VFSFile()119 VFSFile() {}
120
VFSFile(const char * filename,VFSImpl * impl)121 VFSFile(const char * filename, VFSImpl * impl)
122 : m_filename(filename), m_impl(impl)
123 {
124 }
125
126 VFSFile(const char * filename, const char * mode);
127
128 /* creates a temporary file (deleted when closed) */
129 static VFSFile tmpfile();
130
131 explicit operator bool() const { return (bool)m_impl; }
filename()132 const char * filename() const { return m_filename; }
error()133 const char * error() const { return m_error; }
134
135 /* basic operations */
136
137 int64_t fread(void * ptr, int64_t size, int64_t nmemb)
138 __attribute__((warn_unused_result));
139 int fseek(int64_t offset, VFSSeekType whence)
140 __attribute__((warn_unused_result));
141
142 int64_t ftell();
143 int64_t fsize();
144 bool feof();
145
146 int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb)
147 __attribute__((warn_unused_result));
148 int ftruncate(int64_t length) __attribute__((warn_unused_result));
149 int fflush() __attribute__((warn_unused_result));
150
151 /* used to read e.g. ICY metadata */
152 String get_metadata(const char * field);
153
154 /* the VFS layer buffers up to 256 KB of data at the beginning of files
155 * opened in read-only mode; this function disallows reading outside the
156 * buffered region (useful for probing the file type) */
157 void set_limit_to_buffer(bool limit);
158
159 /* utility functions */
160
161 /* reads the entire file into memory (limited to 16 MB) */
162 Index<char> read_all();
163
164 /* reads data from another open file and appends it to this one */
165 bool copy_from(VFSFile & source, int64_t size = -1);
166
167 /* overwrites the entire file with the contents of another */
168 bool replace_with(VFSFile & source);
169
170 /* tests certain attributes of a file without opening it.
171 * the 2-argument version returns true if all requested tests passed.
172 * the 3-argument version returns a bitmask indicating which tests passed.
173 */
174 static bool test_file(const char * filename, VFSFileTest test);
175 static VFSFileTest test_file(const char * filename, VFSFileTest test,
176 String & error);
177
178 /* returns a sorted list of folder entries (as full URIs) */
179 static Index<String> read_folder(const char * filename, String & error);
180
181 /* convenience functions to read/write entire files */
182 static Index<char> read_file(const char * filename, VFSReadOptions options);
183 static bool write_file(const char * filename, const void * data,
184 int64_t len);
185
186 /* returns a list of supported URI schemes */
187 static Index<const char *> supported_uri_schemes();
188
189 private:
190 String m_filename, m_error;
191 SmartPtr<VFSImpl> m_impl;
192 };
193
194 #endif /* LIBAUDCORE_VFS_H */
195