Home | History | Annotate | Download | only in Host
      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 
     18 namespace 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 //----------------------------------------------------------------------
     27 class File
     28 {
     29 public:
     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 
    473 protected:
    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