aboutsummaryrefslogtreecommitdiff
path: root/src/stable/file.h
blob: dfdc1a48c84ece4e9179004c4c469317dfbfb26c (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
/*
 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef BU_FILE_H
#define BU_FILE_H

#include <stdint.h>
#include <sys/types.h>

#include "bu/stream.h"
#include "bu/string.h"
#include "bu/exceptionbase.h"

struct stat;

namespace Bu
{
    subExceptionDecl( FileException );

    /**
     * A file stream.
     *@ingroup Streams
     */
    class File : public Bu::Stream
    {
    public:
        File( const Bu::String &sName, int iFlags );
        File( int fd );
        virtual ~File();

        virtual void close();
        virtual Bu::size read( void *pBuf, Bu::size nBytes );
        virtual Bu::size write( const void *pBuf, Bu::size nBytes );
        using Stream::write;

        virtual Bu::size tell();
        virtual void seek( Bu::size offset );
        virtual void setPos( Bu::size pos );
        virtual void setPosEnd( Bu::size pos );
        virtual bool isEos();
        virtual bool isOpen();

        virtual void flush();

        virtual bool canRead();
        virtual bool canWrite();

        virtual bool isReadable();
        virtual bool isWritable();
        virtual bool isSeekable();

        virtual bool isBlocking();
        virtual void setBlocking( bool bBlocking=true );

        /**
         * Tells you if advisory locks are supported.
         */
        bool canLock() const;

        /**
         * Acquires an advisory lock on the file.  On posix/linux this is done
         * via flock.
         *@param bExclusive Set to true to acquire an exclusive lock (i.e. a
         * write lock).  If this is false then a shared lock (i.e. read lock) is
         * acquired.  A file cannot have both an exclusive and shared lock.
         */
        void lock( bool bExclusive=true );

        /**
         * Release the held advisory lock.
         */
        void unlock();

        enum {
            // Flags
            Read        = 0x01, ///< Open file for reading
            Write       = 0x02, ///< Open file for writing
            Create      = 0x04, ///< Create file if it doesn't exist
            Truncate    = 0x08, ///< Truncate file if it does exist
            Append      = 0x10, ///< Always append on every write
            NonBlock    = 0x20, ///< Open file in non-blocking mode
            Exclusive   = 0x44, ///< Create file, if it exists then fail

            // Helpful mixes
            ReadWrite   = 0x03, ///< Open for reading and writing
            WriteNew    = 0x0E  ///< Create a file (or truncate) for writing.
                                /// Same as Write|Create|Truncate
        };

        virtual void setSize( Bu::size iSize );

        virtual size getSize() const;
        virtual size getBlockSize() const;
        virtual Bu::String getLocation() const;

        void stat( struct ::stat *pStat );

        /**
         * Create a temp file and return its handle.  The file is opened 
         * Read/Write.
         *@param sName (Bu::String) Give in the form: "/tmp/tmpfileXXXXXXXX"
         *      It will alter your (sName) setting the 'X's to random
         *      characters.
         *@returns (Bu::File) A file object representing your temp file.
         */
        static Bu::File tempFile( Bu::String &sName );

#ifndef WIN32
        /**
         * Change the file access permissions.
         *@param t (mode_t) The new file access permissions.
         */
        void chmod( mode_t t );
#endif

    private:
        int getPosixFlags( int iFlags );

    private:
        int fd;
        bool bEos;
        Bu::String sLocation;
    };
}

#endif