1254721Semaste//===-- File.h --------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef liblldb_File_h_
11254721Semaste#define liblldb_File_h_
12254721Semaste#if defined(__cplusplus)
13254721Semaste
14254721Semaste#include <stdio.h>
15254721Semaste
16254721Semaste#include "lldb/lldb-private.h"
17254721Semaste
18254721Semastenamespace lldb_private {
19254721Semaste
20254721Semaste//----------------------------------------------------------------------
21254721Semaste/// @class File File.h "lldb/Host/File.h"
22254721Semaste/// @brief A file class.
23254721Semaste///
24254721Semaste/// A file class that divides abstracts the LLDB core from host file
25254721Semaste/// functionality.
26254721Semaste//----------------------------------------------------------------------
27254721Semasteclass File
28254721Semaste{
29254721Semastepublic:
30254721Semaste    static int kInvalidDescriptor;
31254721Semaste    static FILE * kInvalidStream;
32254721Semaste
33254721Semaste    enum OpenOptions
34254721Semaste    {
35254721Semaste        eOpenOptionRead                 = (1u << 0),    // Open file for reading
36254721Semaste        eOpenOptionWrite                = (1u << 1),    // Open file for writing
37254721Semaste        eOpenOptionAppend               = (1u << 2),    // Don't truncate file when opening, append to end of file
38254721Semaste        eOpenOptionTruncate             = (1u << 3),    // Truncate file when opening
39254721Semaste        eOpenOptionNonBlocking          = (1u << 4),    // File reads
40254721Semaste        eOpenOptionCanCreate            = (1u << 5),    // Create file if doesn't already exist
41254721Semaste        eOpenOptionCanCreateNewOnly     = (1u << 6)     // Can create file only if it doesn't already exist
42254721Semaste    };
43254721Semaste
44254721Semaste    enum Permissions
45254721Semaste    {
46254721Semaste        ePermissionsUserRead        = (1u << 0),
47254721Semaste        ePermissionsUserWrite       = (1u << 1),
48254721Semaste        ePermissionsUserExecute     = (1u << 2),
49254721Semaste        ePermissionsGroupRead       = (1u << 3),
50254721Semaste        ePermissionsGroupWrite      = (1u << 4),
51254721Semaste        ePermissionsGroupExecute    = (1u << 5),
52254721Semaste        ePermissionsWorldRead       = (1u << 6),
53254721Semaste        ePermissionsWorldWrite      = (1u << 7),
54254721Semaste        ePermissionsWorldExecute    = (1u << 8),
55254721Semaste
56254721Semaste        ePermissionsUserRW      = (ePermissionsUserRead    | ePermissionsUserWrite    | 0                        ),
57254721Semaste        ePermissionsUserRX      = (ePermissionsUserRead    | 0                        | ePermissionsUserExecute  ),
58254721Semaste        ePermissionsUserRWX     = (ePermissionsUserRead    | ePermissionsUserWrite    | ePermissionsUserExecute  ),
59254721Semaste
60254721Semaste        ePermissionsGroupRW     = (ePermissionsGroupRead   | ePermissionsGroupWrite   | 0                        ),
61254721Semaste        ePermissionsGroupRX     = (ePermissionsGroupRead   | 0                        | ePermissionsGroupExecute ),
62254721Semaste        ePermissionsGroupRWX    = (ePermissionsGroupRead   | ePermissionsGroupWrite   | ePermissionsGroupExecute ),
63254721Semaste
64254721Semaste        ePermissionsWorldRW     = (ePermissionsWorldRead   | ePermissionsWorldWrite   | 0                        ),
65254721Semaste        ePermissionsWorldRX     = (ePermissionsWorldRead   | 0                        | ePermissionsWorldExecute ),
66254721Semaste        ePermissionsWorldRWX    = (ePermissionsWorldRead   | ePermissionsWorldWrite   | ePermissionsWorldExecute ),
67254721Semaste
68254721Semaste        ePermissionsEveryoneR   = (ePermissionsUserRead    | ePermissionsGroupRead    | ePermissionsWorldRead    ),
69254721Semaste        ePermissionsEveryoneW   = (ePermissionsUserWrite   | ePermissionsGroupWrite   | ePermissionsWorldWrite   ),
70254721Semaste        ePermissionsEveryoneX   = (ePermissionsUserExecute | ePermissionsGroupExecute | ePermissionsWorldExecute ),
71254721Semaste
72254721Semaste        ePermissionsEveryoneRW  = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | 0                        ),
73254721Semaste        ePermissionsEveryoneRX  = (ePermissionsEveryoneR   | 0                        | ePermissionsEveryoneX    ),
74254721Semaste        ePermissionsEveryoneRWX = (ePermissionsEveryoneR   | ePermissionsEveryoneW    | ePermissionsEveryoneX    ),
75254721Semaste        ePermissionsDefault     = (ePermissionsUserRW      | ePermissionsGroupRead)
76254721Semaste    };
77254721Semaste
78254721Semaste    File() :
79254721Semaste        m_descriptor (kInvalidDescriptor),
80254721Semaste        m_stream (kInvalidStream),
81254721Semaste        m_options (0),
82254721Semaste        m_owned (false)
83254721Semaste    {
84254721Semaste    }
85254721Semaste
86254721Semaste    File (FILE *fh, bool transfer_ownership) :
87254721Semaste        m_descriptor (kInvalidDescriptor),
88254721Semaste        m_stream (fh),
89254721Semaste        m_options (0),
90254721Semaste        m_owned (transfer_ownership)
91254721Semaste    {
92254721Semaste    }
93254721Semaste
94254721Semaste    File (const File &rhs);
95254721Semaste
96254721Semaste    File &
97254721Semaste    operator= (const File &rhs);
98254721Semaste    //------------------------------------------------------------------
99254721Semaste    /// Constructor with path.
100254721Semaste    ///
101254721Semaste    /// Takes a path to a file which can be just a filename, or a full
102254721Semaste    /// path. If \a path is not NULL or empty, this function will call
103254721Semaste    /// File::Open (const char *path, uint32_t options, uint32_t permissions).
104254721Semaste    ///
105254721Semaste    /// @param[in] path
106254721Semaste    ///     The full or partial path to a file.
107254721Semaste    ///
108254721Semaste    /// @param[in] options
109254721Semaste    ///     Options to use when opening (see File::OpenOptions)
110254721Semaste    ///
111254721Semaste    /// @param[in] permissions
112254721Semaste    ///     Options to use when opening (see File::Permissions)
113254721Semaste    ///
114254721Semaste    /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
115254721Semaste    //------------------------------------------------------------------
116254721Semaste    File (const char *path,
117254721Semaste          uint32_t options,
118254721Semaste          uint32_t permissions = ePermissionsDefault);
119254721Semaste
120254721Semaste
121254721Semaste    File (int fd, bool tranfer_ownership) :
122254721Semaste        m_descriptor (fd),
123254721Semaste        m_stream (kInvalidStream),
124254721Semaste        m_options (0),
125254721Semaste        m_owned (tranfer_ownership)
126254721Semaste    {
127254721Semaste    }
128254721Semaste    //------------------------------------------------------------------
129254721Semaste    /// Destructor.
130254721Semaste    ///
131254721Semaste    /// The destructor is virtual in case this class is subclassed.
132254721Semaste    //------------------------------------------------------------------
133254721Semaste    virtual
134254721Semaste    ~File ();
135254721Semaste
136254721Semaste    bool
137254721Semaste    IsValid () const
138254721Semaste    {
139254721Semaste        return DescriptorIsValid() || StreamIsValid();
140254721Semaste    }
141254721Semaste
142254721Semaste    //------------------------------------------------------------------
143254721Semaste    /// Convert to pointer operator.
144254721Semaste    ///
145254721Semaste    /// This allows code to check a File object to see if it
146254721Semaste    /// contains anything valid using code such as:
147254721Semaste    ///
148254721Semaste    /// @code
149254721Semaste    /// File file(...);
150254721Semaste    /// if (file)
151254721Semaste    /// { ...
152254721Semaste    /// @endcode
153254721Semaste    ///
154254721Semaste    /// @return
155254721Semaste    ///     A pointer to this object if either the directory or filename
156254721Semaste    ///     is valid, NULL otherwise.
157254721Semaste    //------------------------------------------------------------------
158254721Semaste    operator
159254721Semaste    bool () const
160254721Semaste    {
161254721Semaste        return DescriptorIsValid() || StreamIsValid();
162254721Semaste    }
163254721Semaste
164254721Semaste    //------------------------------------------------------------------
165254721Semaste    /// Logical NOT operator.
166254721Semaste    ///
167254721Semaste    /// This allows code to check a File object to see if it is
168254721Semaste    /// invalid using code such as:
169254721Semaste    ///
170254721Semaste    /// @code
171254721Semaste    /// File file(...);
172254721Semaste    /// if (!file)
173254721Semaste    /// { ...
174254721Semaste    /// @endcode
175254721Semaste    ///
176254721Semaste    /// @return
177254721Semaste    ///     Returns \b true if the object has an empty directory and
178254721Semaste    ///     filename, \b false otherwise.
179254721Semaste    //------------------------------------------------------------------
180254721Semaste    bool
181254721Semaste    operator! () const
182254721Semaste    {
183254721Semaste        return !DescriptorIsValid() && !StreamIsValid();
184254721Semaste    }
185254721Semaste
186254721Semaste    //------------------------------------------------------------------
187254721Semaste    /// Get the file spec for this file.
188254721Semaste    ///
189254721Semaste    /// @return
190254721Semaste    ///     A reference to the file specification object.
191254721Semaste    //------------------------------------------------------------------
192254721Semaste    Error
193254721Semaste    GetFileSpec (FileSpec &file_spec) const;
194254721Semaste
195254721Semaste    //------------------------------------------------------------------
196254721Semaste    /// Open a file for read/writing with the specified options.
197254721Semaste    ///
198254721Semaste    /// Takes a path to a file which can be just a filename, or a full
199254721Semaste    /// path.
200254721Semaste    ///
201254721Semaste    /// @param[in] path
202254721Semaste    ///     The full or partial path to a file.
203254721Semaste    ///
204254721Semaste    /// @param[in] options
205254721Semaste    ///     Options to use when opening (see File::OpenOptions)
206254721Semaste    ///
207254721Semaste    /// @param[in] permissions
208254721Semaste    ///     Options to use when opening (see File::Permissions)
209254721Semaste    //------------------------------------------------------------------
210254721Semaste    Error
211254721Semaste    Open (const char *path,
212254721Semaste          uint32_t options,
213254721Semaste          uint32_t permissions = ePermissionsDefault);
214254721Semaste
215254721Semaste    Error
216254721Semaste    Close ();
217254721Semaste
218254721Semaste    Error
219254721Semaste    Duplicate (const File &rhs);
220254721Semaste
221254721Semaste    int
222254721Semaste    GetDescriptor() const;
223254721Semaste
224254721Semaste    void
225254721Semaste    SetDescriptor(int fd, bool transfer_ownership);
226254721Semaste
227254721Semaste    FILE *
228254721Semaste    GetStream ();
229254721Semaste
230254721Semaste    void
231254721Semaste    SetStream (FILE *fh, bool transfer_ownership);
232254721Semaste
233254721Semaste    //------------------------------------------------------------------
234254721Semaste    /// Read bytes from a file from the current file position.
235254721Semaste    ///
236254721Semaste    /// NOTE: This function is NOT thread safe. Use the read function
237254721Semaste    /// that takes an "off_t &offset" to ensure correct operation in
238254721Semaste    /// multi-threaded environments.
239254721Semaste    ///
240254721Semaste    /// @param[in] buf
241254721Semaste    ///     A buffer where to put the bytes that are read.
242254721Semaste    ///
243254721Semaste    /// @param[in/out] num_bytes
244254721Semaste    ///     The number of bytes to read form the current file position
245254721Semaste    ///     which gets modified with the number of bytes that were read.
246254721Semaste    ///
247254721Semaste    /// @return
248254721Semaste    ///     An error object that indicates success or the reason for
249254721Semaste    ///     failure.
250254721Semaste    //------------------------------------------------------------------
251254721Semaste    Error
252254721Semaste    Read (void *buf, size_t &num_bytes);
253254721Semaste
254254721Semaste    //------------------------------------------------------------------
255254721Semaste    /// Write bytes to a file at the current file position.
256254721Semaste    ///
257254721Semaste    /// NOTE: This function is NOT thread safe. Use the write function
258254721Semaste    /// that takes an "off_t &offset" to ensure correct operation in
259254721Semaste    /// multi-threaded environments.
260254721Semaste    ///
261254721Semaste    /// @param[in] buf
262254721Semaste    ///     A buffer where to put the bytes that are read.
263254721Semaste    ///
264254721Semaste    /// @param[in/out] num_bytes
265254721Semaste    ///     The number of bytes to write to the current file position
266254721Semaste    ///     which gets modified with the number of bytes that were
267254721Semaste    ///     written.
268254721Semaste    ///
269254721Semaste    /// @return
270254721Semaste    ///     An error object that indicates success or the reason for
271254721Semaste    ///     failure.
272254721Semaste    //------------------------------------------------------------------
273254721Semaste    Error
274254721Semaste    Write (const void *buf, size_t &num_bytes);
275254721Semaste
276254721Semaste    //------------------------------------------------------------------
277254721Semaste    /// Seek to an offset relative to the beginning of the file.
278254721Semaste    ///
279254721Semaste    /// NOTE: This function is NOT thread safe, other threads that
280254721Semaste    /// access this object might also change the current file position.
281254721Semaste    /// For thread safe reads and writes see the following functions:
282254721Semaste    /// @see File::Read (void *, size_t, off_t &)
283254721Semaste    /// @see File::Write (const void *, size_t, off_t &)
284254721Semaste    ///
285254721Semaste    /// @param[in] offset
286254721Semaste    ///     The offset to seek to within the file relative to the
287254721Semaste    ///     beginning of the file.
288254721Semaste    ///
289254721Semaste    /// @param[in] error_ptr
290254721Semaste    ///     A pointer to a lldb_private::Error object that will be
291254721Semaste    ///     filled in if non-NULL.
292254721Semaste    ///
293254721Semaste    /// @return
294254721Semaste    ///     The resulting seek offset, or -1 on error.
295254721Semaste    //------------------------------------------------------------------
296254721Semaste    off_t
297254721Semaste    SeekFromStart (off_t offset, Error *error_ptr = NULL);
298254721Semaste
299254721Semaste    //------------------------------------------------------------------
300254721Semaste    /// Seek to an offset relative to the current file position.
301254721Semaste    ///
302254721Semaste    /// NOTE: This function is NOT thread safe, other threads that
303254721Semaste    /// access this object might also change the current file position.
304254721Semaste    /// For thread safe reads and writes see the following functions:
305254721Semaste    /// @see File::Read (void *, size_t, off_t &)
306254721Semaste    /// @see File::Write (const void *, size_t, off_t &)
307254721Semaste    ///
308254721Semaste    /// @param[in] offset
309254721Semaste    ///     The offset to seek to within the file relative to the
310254721Semaste    ///     current file position.
311254721Semaste    ///
312254721Semaste    /// @param[in] error_ptr
313254721Semaste    ///     A pointer to a lldb_private::Error object that will be
314254721Semaste    ///     filled in if non-NULL.
315254721Semaste    ///
316254721Semaste    /// @return
317254721Semaste    ///     The resulting seek offset, or -1 on error.
318254721Semaste    //------------------------------------------------------------------
319254721Semaste    off_t
320254721Semaste    SeekFromCurrent (off_t offset, Error *error_ptr = NULL);
321254721Semaste
322254721Semaste    //------------------------------------------------------------------
323254721Semaste    /// Seek to an offset relative to the end of the file.
324254721Semaste    ///
325254721Semaste    /// NOTE: This function is NOT thread safe, other threads that
326254721Semaste    /// access this object might also change the current file position.
327254721Semaste    /// For thread safe reads and writes see the following functions:
328254721Semaste    /// @see File::Read (void *, size_t, off_t &)
329254721Semaste    /// @see File::Write (const void *, size_t, off_t &)
330254721Semaste    ///
331254721Semaste    /// @param[in/out] offset
332254721Semaste    ///     The offset to seek to within the file relative to the
333254721Semaste    ///     end of the file which gets filled in the the resulting
334254721Semaste    ///     absolute file offset.
335254721Semaste    ///
336254721Semaste    /// @param[in] error_ptr
337254721Semaste    ///     A pointer to a lldb_private::Error object that will be
338254721Semaste    ///     filled in if non-NULL.
339254721Semaste    ///
340254721Semaste    /// @return
341254721Semaste    ///     The resulting seek offset, or -1 on error.
342254721Semaste    //------------------------------------------------------------------
343254721Semaste    off_t
344254721Semaste    SeekFromEnd (off_t offset, Error *error_ptr = NULL);
345254721Semaste
346254721Semaste    //------------------------------------------------------------------
347254721Semaste    /// Read bytes from a file from the specified file offset.
348254721Semaste    ///
349254721Semaste    /// NOTE: This function is thread safe in that clients manager their
350254721Semaste    /// own file position markers and reads on other threads won't mess
351254721Semaste    /// up the current read.
352254721Semaste    ///
353254721Semaste    /// @param[in] buf
354254721Semaste    ///     A buffer where to put the bytes that are read.
355254721Semaste    ///
356254721Semaste    /// @param[in/out] num_bytes
357254721Semaste    ///     The number of bytes to read form the current file position
358254721Semaste    ///     which gets modified with the number of bytes that were read.
359254721Semaste    ///
360254721Semaste    /// @param[in/out] offset
361254721Semaste    ///     The offset within the file from which to read \a num_bytes
362254721Semaste    ///     bytes. This offset gets incremented by the number of bytes
363254721Semaste    ///     that were read.
364254721Semaste    ///
365254721Semaste    /// @return
366254721Semaste    ///     An error object that indicates success or the reason for
367254721Semaste    ///     failure.
368254721Semaste    //------------------------------------------------------------------
369254721Semaste    Error
370254721Semaste    Read (void *dst, size_t &num_bytes, off_t &offset);
371254721Semaste
372254721Semaste    //------------------------------------------------------------------
373254721Semaste    /// Read bytes from a file from the specified file offset.
374254721Semaste    ///
375254721Semaste    /// NOTE: This function is thread safe in that clients manager their
376254721Semaste    /// own file position markers and reads on other threads won't mess
377254721Semaste    /// up the current read.
378254721Semaste    ///
379254721Semaste    /// @param[in/out] num_bytes
380254721Semaste    ///     The number of bytes to read form the current file position
381254721Semaste    ///     which gets modified with the number of bytes that were read.
382254721Semaste    ///
383254721Semaste    /// @param[in/out] offset
384254721Semaste    ///     The offset within the file from which to read \a num_bytes
385254721Semaste    ///     bytes. This offset gets incremented by the number of bytes
386254721Semaste    ///     that were read.
387254721Semaste    ///
388254721Semaste    /// @param[in] null_terminate
389254721Semaste    ///     Ensure that the data that is read is terminated with a NULL
390254721Semaste    ///     character so that the data can be used as a C string.
391254721Semaste    ///
392254721Semaste    /// @param[out] data_buffer_sp
393254721Semaste    ///     A data buffer to create and fill in that will contain any
394254721Semaste    ///     data that is read from the file. This buffer will be reset
395254721Semaste    ///     if an error occurs.
396254721Semaste    ///
397254721Semaste    /// @return
398254721Semaste    ///     An error object that indicates success or the reason for
399254721Semaste    ///     failure.
400254721Semaste    //------------------------------------------------------------------
401254721Semaste    Error
402254721Semaste    Read (size_t &num_bytes,
403254721Semaste          off_t &offset,
404254721Semaste          bool null_terminate,
405254721Semaste          lldb::DataBufferSP &data_buffer_sp);
406254721Semaste
407254721Semaste    //------------------------------------------------------------------
408254721Semaste    /// Write bytes to a file at the specified file offset.
409254721Semaste    ///
410254721Semaste    /// NOTE: This function is thread safe in that clients manager their
411254721Semaste    /// own file position markers, though clients will need to implement
412254721Semaste    /// their own locking externally to avoid multiple people writing
413254721Semaste    /// to the file at the same time.
414254721Semaste    ///
415254721Semaste    /// @param[in] buf
416254721Semaste    ///     A buffer containing the bytes to write.
417254721Semaste    ///
418254721Semaste    /// @param[in/out] num_bytes
419254721Semaste    ///     The number of bytes to write to the file at offset \a offset.
420254721Semaste    ///     \a num_bytes gets modified with the number of bytes that
421254721Semaste    ///     were read.
422254721Semaste    ///
423254721Semaste    /// @param[in/out] offset
424254721Semaste    ///     The offset within the file at which to write \a num_bytes
425254721Semaste    ///     bytes. This offset gets incremented by the number of bytes
426254721Semaste    ///     that were written.
427254721Semaste    ///
428254721Semaste    /// @return
429254721Semaste    ///     An error object that indicates success or the reason for
430254721Semaste    ///     failure.
431254721Semaste    //------------------------------------------------------------------
432254721Semaste    Error
433254721Semaste    Write (const void *src, size_t &num_bytes, off_t &offset);
434254721Semaste
435254721Semaste    //------------------------------------------------------------------
436254721Semaste    /// Flush the current stream
437254721Semaste    ///
438254721Semaste    /// @return
439254721Semaste    ///     An error object that indicates success or the reason for
440254721Semaste    ///     failure.
441254721Semaste    //------------------------------------------------------------------
442254721Semaste    Error
443254721Semaste    Flush ();
444254721Semaste
445254721Semaste    //------------------------------------------------------------------
446254721Semaste    /// Sync to disk.
447254721Semaste    ///
448254721Semaste    /// @return
449254721Semaste    ///     An error object that indicates success or the reason for
450254721Semaste    ///     failure.
451254721Semaste    //------------------------------------------------------------------
452254721Semaste    Error
453254721Semaste    Sync ();
454254721Semaste
455254721Semaste    //------------------------------------------------------------------
456254721Semaste    /// Output printf formatted output to the stream.
457254721Semaste    ///
458254721Semaste    /// Print some formatted output to the stream.
459254721Semaste    ///
460254721Semaste    /// @param[in] format
461254721Semaste    ///     A printf style format string.
462254721Semaste    ///
463254721Semaste    /// @param[in] ...
464254721Semaste    ///     Variable arguments that are needed for the printf style
465254721Semaste    ///     format string \a format.
466254721Semaste    //------------------------------------------------------------------
467254721Semaste    size_t
468254721Semaste    Printf (const char *format, ...)  __attribute__ ((format (printf, 2, 3)));
469254721Semaste
470254721Semaste    size_t
471254721Semaste    PrintfVarArg(const char *format, va_list args);
472254721Semaste
473254721Semasteprotected:
474254721Semaste
475254721Semaste
476254721Semaste    bool
477254721Semaste    DescriptorIsValid () const
478254721Semaste    {
479254721Semaste        return m_descriptor >= 0;
480254721Semaste    }
481254721Semaste
482254721Semaste    bool
483254721Semaste    StreamIsValid () const
484254721Semaste    {
485254721Semaste        return m_stream != kInvalidStream;
486254721Semaste    }
487254721Semaste
488254721Semaste    //------------------------------------------------------------------
489254721Semaste    // Member variables
490254721Semaste    //------------------------------------------------------------------
491254721Semaste    int m_descriptor;
492254721Semaste    FILE *m_stream;
493254721Semaste    uint32_t m_options;
494254721Semaste    bool m_owned;
495254721Semaste};
496254721Semaste
497254721Semaste} // namespace lldb_private
498254721Semaste
499254721Semaste#endif  // #if defined(__cplusplus)
500254721Semaste#endif  // liblldb_File_h_
501