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