File.h revision 419144b064166f0d18b06cad4d52fe66e7ca058f
1//===-- File.h --------------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_File_h_
11#define liblldb_File_h_
12#if defined(__cplusplus)
13
14#include <stdio.h>
15
16#include "lldb/lldb-private.h"
17
18namespace lldb_private {
19
20//----------------------------------------------------------------------
21/// @class File File.h "lldb/Host/File.h"
22/// @brief A file class.
23///
24/// A file class that divides abstracts the LLDB core from host file
25/// functionality.
26//----------------------------------------------------------------------
27class File
28{
29public:
30    static int kInvalidDescriptor;
31    static FILE * kInvalidStream;
32
33    enum OpenOptions
34    {
35        eOpenOptionRead                 = (1u << 0),    // Open file for reading
36        eOpenOptionWrite                = (1u << 1),    // Open file for writing
37        eOpenOptionAppend               = (1u << 2),    // Don't truncate file when opening, append to end of file
38        eOpenOptionNonBlocking          = (1u << 3),    // File reads
39        eOpenOptionCanCreate            = (1u << 4),    // Create file if doesn't already exist
40        eOpenOptionCanCreateNewOnly     = (1u << 5)    // Can create file only if it doesn't already exist
41    };
42
43    enum Permissions
44    {
45        ePermissionsUserRead        = (1u << 0),
46        ePermissionsUserWrite       = (1u << 1),
47        ePermissionsUserExecute     = (1u << 2),
48        ePermissionsGroupRead       = (1u << 3),
49        ePermissionsGroupWrite      = (1u << 4),
50        ePermissionsGroupExecute    = (1u << 5),
51        ePermissionsWorldRead       = (1u << 6),
52        ePermissionsWorldWrite      = (1u << 7),
53        ePermissionsWorldExecute    = (1u << 8),
54
55        ePermissionsUserRW      = (ePermissionsUserRead    | ePermissionsUserWrite    | 0                        ),
56        ePermissionsUserRX      = (ePermissionsUserRead    | 0                        | ePermissionsUserExecute  ),
57        ePermissionsUserRWX     = (ePermissionsUserRead    | ePermissionsUserWrite    | ePermissionsUserExecute  ),
58
59        ePermissionsGroupRW     = (ePermissionsGroupRead   | ePermissionsGroupWrite   | 0                        ),
60        ePermissionsGroupRX     = (ePermissionsGroupRead   | 0                        | ePermissionsGroupExecute ),
61        ePermissionsGroupRWX    = (ePermissionsGroupRead   | ePermissionsGroupWrite   | ePermissionsGroupExecute ),
62
63        ePermissionsWorldRW     = (ePermissionsWorldRead   | ePermissionsWorldWrite   | 0                        ),
64        ePermissionsWorldRX     = (ePermissionsWorldRead   | 0                        | ePermissionsWorldExecute ),
65        ePermissionsWorldRWX    = (ePermissionsWorldRead   | ePermissionsWorldWrite   | ePermissionsWorldExecute ),
66
67        ePermissionsEveryoneR   = (ePermissionsUserRead    | ePermissionsGroupRead    | ePermissionsWorldRead    ),
68        ePermissionsEveryoneW   = (ePermissionsUserWrite   | ePermissionsGroupWrite   | ePermissionsWorldWrite   ),
69        ePermissionsEveryoneX   = (ePermissionsUserExecute | ePermissionsGroupExecute | ePermissionsWorldExecute ),
70
71        ePermissionsEveryoneRW  = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | 0                        ),
72        ePermissionsEveryoneRX  = (ePermissionsEveryoneR   | 0                        | ePermissionsEveryoneX    ),
73        ePermissionsEveryoneRWX = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | ePermissionsEveryoneX    ),
74        ePermissionsDefault     = (ePermissionsUserRW      | ePermissionsGroupRead)
75    };
76
77    File() :
78        m_descriptor (kInvalidDescriptor),
79        m_stream (kInvalidStream),
80        m_options (0),
81        m_owned (false)
82    {
83    }
84
85    File (FILE *fh, bool transfer_ownership) :
86        m_descriptor (kInvalidDescriptor),
87        m_stream (fh),
88        m_options (0),
89        m_owned (transfer_ownership)
90    {
91    }
92
93    File (const File &rhs);
94
95    File &
96    operator= (const File &rhs);
97    //------------------------------------------------------------------
98    /// Constructor with path.
99    ///
100    /// Takes a path to a file which can be just a filename, or a full
101    /// path. If \a path is not NULL or empty, this function will call
102    /// File::Open (const char *path, uint32_t options, uint32_t permissions).
103    ///
104    /// @param[in] path
105    ///     The full or partial path to a file.
106    ///
107    /// @param[in] options
108    ///     Options to use when opening (see File::OpenOptions)
109    ///
110    /// @param[in] permissions
111    ///     Options to use when opening (see File::Permissions)
112    ///
113    /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
114    //------------------------------------------------------------------
115    File (const char *path,
116          uint32_t options,
117          uint32_t permissions = ePermissionsDefault);
118
119
120    File (int fd, bool tranfer_ownership) :
121        m_descriptor (fd),
122        m_stream (kInvalidStream),
123        m_options (0),
124        m_owned (tranfer_ownership)
125    {
126    }
127    //------------------------------------------------------------------
128    /// Destructor.
129    ///
130    /// The destructor is virtual in case this class is subclassed.
131    //------------------------------------------------------------------
132    virtual
133    ~File ();
134
135    bool
136    IsValid () const
137    {
138        return DescriptorIsValid() || StreamIsValid();
139    }
140
141    //------------------------------------------------------------------
142    /// Convert to pointer operator.
143    ///
144    /// This allows code to check a File object to see if it
145    /// contains anything valid using code such as:
146    ///
147    /// @code
148    /// File file(...);
149    /// if (file)
150    /// { ...
151    /// @endcode
152    ///
153    /// @return
154    ///     A pointer to this object if either the directory or filename
155    ///     is valid, NULL otherwise.
156    //------------------------------------------------------------------
157    operator
158    bool () const
159    {
160        return DescriptorIsValid() || StreamIsValid();
161    }
162
163    //------------------------------------------------------------------
164    /// Logical NOT operator.
165    ///
166    /// This allows code to check a File object to see if it is
167    /// invalid using code such as:
168    ///
169    /// @code
170    /// File file(...);
171    /// if (!file)
172    /// { ...
173    /// @endcode
174    ///
175    /// @return
176    ///     Returns \b true if the object has an empty directory and
177    ///     filename, \b false otherwise.
178    //------------------------------------------------------------------
179    bool
180    operator! () const
181    {
182        return !DescriptorIsValid() && !StreamIsValid();
183    }
184
185    //------------------------------------------------------------------
186    /// Get the file spec for this file.
187    ///
188    /// @return
189    ///     A reference to the file specification object.
190    //------------------------------------------------------------------
191    Error
192    GetFileSpec (FileSpec &file_spec) const;
193
194    //------------------------------------------------------------------
195    /// Open a file for read/writing with the specified options.
196    ///
197    /// Takes a path to a file which can be just a filename, or a full
198    /// path.
199    ///
200    /// @param[in] path
201    ///     The full or partial path to a file.
202    ///
203    /// @param[in] options
204    ///     Options to use when opening (see File::OpenOptions)
205    ///
206    /// @param[in] permissions
207    ///     Options to use when opening (see File::Permissions)
208    //------------------------------------------------------------------
209    Error
210    Open (const char *path,
211          uint32_t options,
212          uint32_t permissions = ePermissionsDefault);
213
214    Error
215    Close ();
216
217    Error
218    Duplicate (const File &rhs);
219
220    int
221    GetDescriptor() const;
222
223    void
224    SetDescriptor(int fd, bool transfer_ownership);
225
226    FILE *
227    GetStream ();
228
229    void
230    SetStream (FILE *fh, bool transfer_ownership);
231
232    //------------------------------------------------------------------
233    /// Read bytes from a file from the current file position.
234    ///
235    /// NOTE: This function is NOT thread safe. Use the read function
236    /// that takes an "off_t &offset" to ensure correct operation in
237    /// multi-threaded environments.
238    ///
239    /// @param[in] buf
240    ///     A buffer where to put the bytes that are read.
241    ///
242    /// @param[in/out] num_bytes
243    ///     The number of bytes to read form the current file position
244    ///     which gets modified with the number of bytes that were read.
245    ///
246    /// @return
247    ///     An error object that indicates success or the reason for
248    ///     failure.
249    //------------------------------------------------------------------
250    Error
251    Read (void *buf, size_t &num_bytes);
252
253    //------------------------------------------------------------------
254    /// Write bytes to a file at the current file position.
255    ///
256    /// NOTE: This function is NOT thread safe. Use the write function
257    /// that takes an "off_t &offset" to ensure correct operation in
258    /// multi-threaded environments.
259    ///
260    /// @param[in] buf
261    ///     A buffer where to put the bytes that are read.
262    ///
263    /// @param[in/out] num_bytes
264    ///     The number of bytes to write to the current file position
265    ///     which gets modified with the number of bytes that were
266    ///     written.
267    ///
268    /// @return
269    ///     An error object that indicates success or the reason for
270    ///     failure.
271    //------------------------------------------------------------------
272    Error
273    Write (const void *buf, size_t &num_bytes);
274
275    //------------------------------------------------------------------
276    /// Seek to an offset relative to the beginning of the file.
277    ///
278    /// NOTE: This function is NOT thread safe, other threads that
279    /// access this object might also change the current file position.
280    /// For thread safe reads and writes see the following functions:
281    /// @see File::Read (void *, size_t, off_t &)
282    /// @see File::Write (const void *, size_t, off_t &)
283    ///
284    /// @param[in/out] offset
285    ///     The offset to seek to within the file relative to the
286    ///     beginning of the file which gets filled in the the resulting
287    ///     absolute file offset.
288    ///
289    /// @return
290    ///     An error object that indicates success or the reason for
291    ///     failure.
292    //------------------------------------------------------------------
293    Error
294    SeekFromStart (off_t& offset);
295
296    //------------------------------------------------------------------
297    /// Seek to an offset relative to the current file position.
298    ///
299    /// NOTE: This function is NOT thread safe, other threads that
300    /// access this object might also change the current file position.
301    /// For thread safe reads and writes see the following functions:
302    /// @see File::Read (void *, size_t, off_t &)
303    /// @see File::Write (const void *, size_t, off_t &)
304    ///
305    /// @param[in/out] offset
306    ///     The offset to seek to within the file relative to the
307    ///     current file position. On return this parameter gets filled
308    ///     in the the resulting absolute file offset.
309    ///
310    /// @return
311    ///     An error object that indicates success or the reason for
312    ///     failure.
313    //------------------------------------------------------------------
314    Error
315    SeekFromCurrent (off_t& offset);
316
317    //------------------------------------------------------------------
318    /// Seek to an offset relative to the end of the file.
319    ///
320    /// NOTE: This function is NOT thread safe, other threads that
321    /// access this object might also change the current file position.
322    /// For thread safe reads and writes see the following functions:
323    /// @see File::Read (void *, size_t, off_t &)
324    /// @see File::Write (const void *, size_t, off_t &)
325    ///
326    /// @param[in/out] offset
327    ///     The offset to seek to within the file relative to the
328    ///     end of the file which gets filled in the the resulting
329    ///     absolute file offset.
330    ///
331    /// @return
332    ///     An error object that indicates success or the reason for
333    ///     failure.
334    //------------------------------------------------------------------
335    Error
336    SeekFromEnd (off_t& offset);
337
338    //------------------------------------------------------------------
339    /// Read bytes from a file from the specified file offset.
340    ///
341    /// NOTE: This function is thread safe in that clients manager their
342    /// own file position markers and reads on other threads won't mess
343    /// up the current read.
344    ///
345    /// @param[in] buf
346    ///     A buffer where to put the bytes that are read.
347    ///
348    /// @param[in/out] num_bytes
349    ///     The number of bytes to read form the current file position
350    ///     which gets modified with the number of bytes that were read.
351    ///
352    /// @param[in/out] offset
353    ///     The offset within the file from which to read \a num_bytes
354    ///     bytes. This offset gets incremented by the number of bytes
355    ///     that were read.
356    ///
357    /// @return
358    ///     An error object that indicates success or the reason for
359    ///     failure.
360    //------------------------------------------------------------------
361    Error
362    Read (void *dst, size_t &num_bytes, off_t &offset);
363
364    //------------------------------------------------------------------
365    /// Write bytes to a file at the specified file offset.
366    ///
367    /// NOTE: This function is thread safe in that clients manager their
368    /// own file position markers, though clients will need to implement
369    /// their own locking externally to avoid multiple people writing
370    /// to the file at the same time.
371    ///
372    /// @param[in] buf
373    ///     A buffer containing the bytes to write.
374    ///
375    /// @param[in/out] num_bytes
376    ///     The number of bytes to write to the file at offset \a offset.
377    ///     \a num_bytes gets modified with the number of bytes that
378    ///     were read.
379    ///
380    /// @param[in/out] offset
381    ///     The offset within the file at which to write \a num_bytes
382    ///     bytes. This offset gets incremented by the number of bytes
383    ///     that were written.
384    ///
385    /// @return
386    ///     An error object that indicates success or the reason for
387    ///     failure.
388    //------------------------------------------------------------------
389    Error
390    Write (const void *src, size_t &num_bytes, off_t &offset);
391
392    //------------------------------------------------------------------
393    /// Flush the current stream
394    ///
395    /// @return
396    ///     An error object that indicates success or the reason for
397    ///     failure.
398    //------------------------------------------------------------------
399    Error
400    Flush ();
401
402    //------------------------------------------------------------------
403    /// Sync to disk.
404    ///
405    /// @return
406    ///     An error object that indicates success or the reason for
407    ///     failure.
408    //------------------------------------------------------------------
409    Error
410    Sync ();
411
412    //------------------------------------------------------------------
413    /// Output printf formatted output to the stream.
414    ///
415    /// Print some formatted output to the stream.
416    ///
417    /// @param[in] format
418    ///     A printf style format string.
419    ///
420    /// @param[in] ...
421    ///     Variable arguments that are needed for the printf style
422    ///     format string \a format.
423    //------------------------------------------------------------------
424    int
425    Printf (const char *format, ...);
426
427    int
428    PrintfVarArg(const char *format, va_list args);
429
430protected:
431
432
433    bool
434    DescriptorIsValid () const
435    {
436        return m_descriptor >= 0;
437    }
438
439    bool
440    StreamIsValid () const
441    {
442        return m_stream != kInvalidStream;
443    }
444
445    //------------------------------------------------------------------
446    // Member variables
447    //------------------------------------------------------------------
448    int m_descriptor;
449    FILE *m_stream;
450    uint32_t m_options;
451    bool m_owned;
452};
453
454} // namespace lldb_private
455
456#endif  // #if defined(__cplusplus)
457#endif  // liblldb_File_h_
458