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