summaryrefslogtreecommitdiff
path: root/src/libaudcore/vfs.h
blob: c6a0a162b307d593150affd058db2aa1ea16dbb7 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * vfs.h
 * Copyright 2006-2013 William Pitcock, Daniel Barkalow, Ralf Ertzinger,
 *                     Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions, and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions, and the following disclaimer in the documentation
 *    provided with the distribution.
 *
 * This software is provided "as is" and without any warranty, express or
 * implied. In no event shall the authors be liable for any damages arising from
 * the use of this software.
 */
/**
 * @file vfs.h
 * Main API header for accessing Audacious VFS functionality.
 * Provides functions for VFS transport registration and
 * file access.
 */

#ifndef LIBAUDCORE_VFS_H
#define LIBAUDCORE_VFS_H

#include <stdint.h>

#include <libaudcore/index.h>
#include <libaudcore/objects.h>

enum VFSFileTest {
    VFS_IS_REGULAR    = (1 << 0),
    VFS_IS_SYMLINK    = (1 << 1),
    VFS_IS_DIR        = (1 << 2),
    VFS_IS_EXECUTABLE = (1 << 3),
    VFS_EXISTS        = (1 << 4)
};

enum VFSSeekType {
    VFS_SEEK_SET = 0,
    VFS_SEEK_CUR = 1,
    VFS_SEEK_END = 2
};

#ifdef WANT_VFS_STDIO_COMPAT

#include <stdio.h>

constexpr int from_vfs_seek_type (VFSSeekType whence)
{
    return (whence == VFS_SEEK_SET) ? SEEK_SET :
           (whence == VFS_SEEK_CUR) ? SEEK_CUR :
           (whence == VFS_SEEK_END) ? SEEK_END : -1;
}

constexpr VFSSeekType to_vfs_seek_type (int whence)
{
    return (whence == SEEK_SET) ? VFS_SEEK_SET :
           (whence == SEEK_CUR) ? VFS_SEEK_CUR :
           (whence == SEEK_END) ? VFS_SEEK_END : (VFSSeekType) -1;
}

#endif // WANT_VFS_STDIO_COMPAT

class VFSImpl
{
public:
    VFSImpl () {}
    virtual ~VFSImpl () {}

    VFSImpl (const VFSImpl &) = delete;
    VFSImpl & operator= (const VFSImpl &) = delete;

    virtual int64_t fread (void * ptr, int64_t size, int64_t nmemb) = 0;
    virtual int fseek (int64_t offset, VFSSeekType whence) = 0;

    virtual int64_t ftell () = 0;
    virtual int64_t fsize () = 0;
    virtual bool feof () = 0;

    virtual int64_t fwrite (const void * ptr, int64_t size, int64_t nmemb) = 0;
    virtual int ftruncate (int64_t length) = 0;
    virtual int fflush () = 0;

    virtual String get_metadata (const char * field) { return String (); }
};

class VFSFile
{
public:
    VFSFile () {}

    VFSFile (const char * filename, VFSImpl * impl) :
        m_filename (filename),
        m_impl (impl) {}

    VFSFile (const char * filename, const char * mode);

    explicit operator bool () const
        { return (bool) m_impl; }
    const char * filename () const
        { return m_filename; }
    const char * error () const
        { return m_error; }

    /* basic operations */

    int64_t fread (void * ptr, int64_t size, int64_t nmemb) __attribute__ ((warn_unused_result));
    int fseek (int64_t offset, VFSSeekType whence) __attribute__ ((warn_unused_result));

    int64_t ftell ();
    int64_t fsize ();
    bool feof ();

    int64_t fwrite (const void * ptr, int64_t size, int64_t nmemb) __attribute__ ((warn_unused_result));
    int ftruncate (int64_t length) __attribute__ ((warn_unused_result));
    int fflush () __attribute__ ((warn_unused_result));

    String get_metadata (const char * field);

    void set_limit_to_buffer (bool limit);  // added in 3.7

    /* utility functions */

    Index<char> read_all ();

    static bool test_file (const char * path, VFSFileTest test);

private:
    String m_filename, m_error;
    SmartPtr<VFSImpl> m_impl;
};

#endif /* LIBAUDCORE_VFS_H */