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] offset
286    ///     The offset to seek to within the file relative to the
287    ///     beginning of the file.
288    ///
289    /// @param[in] error_ptr
290    ///     A pointer to a lldb_private::Error object that will be
291    ///     filled in if non-NULL.
292    ///
293    /// @return
294    ///     The resulting seek offset, or -1 on error.
295    //------------------------------------------------------------------
296    off_t
297    SeekFromStart (off_t offset, Error *error_ptr = NULL);
298
299    //------------------------------------------------------------------
300    /// Seek to an offset relative to the current file position.
301    ///
302    /// NOTE: This function is NOT thread safe, other threads that
303    /// access this object might also change the current file position.
304    /// For thread safe reads and writes see the following functions:
305    /// @see File::Read (void *, size_t, off_t &)
306    /// @see File::Write (const void *, size_t, off_t &)
307    ///
308    /// @param[in] offset
309    ///     The offset to seek to within the file relative to the
310    ///     current file position.
311    ///
312    /// @param[in] error_ptr
313    ///     A pointer to a lldb_private::Error object that will be
314    ///     filled in if non-NULL.
315    ///
316    /// @return
317    ///     The resulting seek offset, or -1 on error.
318    //------------------------------------------------------------------
319    off_t
320    SeekFromCurrent (off_t offset, Error *error_ptr = NULL);
321
322    //------------------------------------------------------------------
323    /// Seek to an offset relative to the end of the file.
324    ///
325    /// NOTE: This function is NOT thread safe, other threads that
326    /// access this object might also change the current file position.
327    /// For thread safe reads and writes see the following functions:
328    /// @see File::Read (void *, size_t, off_t &)
329    /// @see File::Write (const void *, size_t, off_t &)
330    ///
331    /// @param[in/out] offset
332    ///     The offset to seek to within the file relative to the
333    ///     end of the file which gets filled in the the resulting
334    ///     absolute file offset.
335    ///
336    /// @param[in] error_ptr
337    ///     A pointer to a lldb_private::Error object that will be
338    ///     filled in if non-NULL.
339    ///
340    /// @return
341    ///     The resulting seek offset, or -1 on error.
342    //------------------------------------------------------------------
343    off_t
344    SeekFromEnd (off_t offset, Error *error_ptr = NULL);
345
346    //------------------------------------------------------------------
347    /// Read bytes from a file from the specified file offset.
348    ///
349    /// NOTE: This function is thread safe in that clients manager their
350    /// own file position markers and reads on other threads won't mess
351    /// up the current read.
352    ///
353    /// @param[in] buf
354    ///     A buffer where to put the bytes that are read.
355    ///
356    /// @param[in/out] num_bytes
357    ///     The number of bytes to read form the current file position
358    ///     which gets modified with the number of bytes that were read.
359    ///
360    /// @param[in/out] offset
361    ///     The offset within the file from which to read \a num_bytes
362    ///     bytes. This offset gets incremented by the number of bytes
363    ///     that were read.
364    ///
365    /// @return
366    ///     An error object that indicates success or the reason for
367    ///     failure.
368    //------------------------------------------------------------------
369    Error
370    Read (void *dst, size_t &num_bytes, off_t &offset);
371
372    //------------------------------------------------------------------
373    /// Read bytes from a file from the specified file offset.
374    ///
375    /// NOTE: This function is thread safe in that clients manager their
376    /// own file position markers and reads on other threads won't mess
377    /// up the current read.
378    ///
379    /// @param[in/out] num_bytes
380    ///     The number of bytes to read form the current file position
381    ///     which gets modified with the number of bytes that were read.
382    ///
383    /// @param[in/out] offset
384    ///     The offset within the file from which to read \a num_bytes
385    ///     bytes. This offset gets incremented by the number of bytes
386    ///     that were read.
387    ///
388    /// @param[in] null_terminate
389    ///     Ensure that the data that is read is terminated with a NULL
390    ///     character so that the data can be used as a C string.
391    ///
392    /// @param[out] data_buffer_sp
393    ///     A data buffer to create and fill in that will contain any
394    ///     data that is read from the file. This buffer will be reset
395    ///     if an error occurs.
396    ///
397    /// @return
398    ///     An error object that indicates success or the reason for
399    ///     failure.
400    //------------------------------------------------------------------
401    Error
402    Read (size_t &num_bytes,
403          off_t &offset,
404          bool null_terminate,
405          lldb::DataBufferSP &data_buffer_sp);
406
407    //------------------------------------------------------------------
408    /// Write bytes to a file at the specified file offset.
409    ///
410    /// NOTE: This function is thread safe in that clients manager their
411    /// own file position markers, though clients will need to implement
412    /// their own locking externally to avoid multiple people writing
413    /// to the file at the same time.
414    ///
415    /// @param[in] buf
416    ///     A buffer containing the bytes to write.
417    ///
418    /// @param[in/out] num_bytes
419    ///     The number of bytes to write to the file at offset \a offset.
420    ///     \a num_bytes gets modified with the number of bytes that
421    ///     were read.
422    ///
423    /// @param[in/out] offset
424    ///     The offset within the file at which to write \a num_bytes
425    ///     bytes. This offset gets incremented by the number of bytes
426    ///     that were written.
427    ///
428    /// @return
429    ///     An error object that indicates success or the reason for
430    ///     failure.
431    //------------------------------------------------------------------
432    Error
433    Write (const void *src, size_t &num_bytes, off_t &offset);
434
435    //------------------------------------------------------------------
436    /// Flush the current stream
437    ///
438    /// @return
439    ///     An error object that indicates success or the reason for
440    ///     failure.
441    //------------------------------------------------------------------
442    Error
443    Flush ();
444
445    //------------------------------------------------------------------
446    /// Sync to disk.
447    ///
448    /// @return
449    ///     An error object that indicates success or the reason for
450    ///     failure.
451    //------------------------------------------------------------------
452    Error
453    Sync ();
454
455    //------------------------------------------------------------------
456    /// Output printf formatted output to the stream.
457    ///
458    /// Print some formatted output to the stream.
459    ///
460    /// @param[in] format
461    ///     A printf style format string.
462    ///
463    /// @param[in] ...
464    ///     Variable arguments that are needed for the printf style
465    ///     format string \a format.
466    //------------------------------------------------------------------
467    size_t
468    Printf (const char *format, ...)  __attribute__ ((format (printf, 2, 3)));
469
470    size_t
471    PrintfVarArg(const char *format, va_list args);
472
473protected:
474
475
476    bool
477    DescriptorIsValid () const
478    {
479        return m_descriptor >= 0;
480    }
481
482    bool
483    StreamIsValid () const
484    {
485        return m_stream != kInvalidStream;
486    }
487
488    //------------------------------------------------------------------
489    // Member variables
490    //------------------------------------------------------------------
491    int m_descriptor;
492    FILE *m_stream;
493    uint32_t m_options;
494    bool m_owned;
495};
496
497} // namespace lldb_private
498
499#endif  // #if defined(__cplusplus)
500#endif  // liblldb_File_h_
501