Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file defines FileStream, a basic interface for reading and writing files
      6 // synchronously or asynchronously with support for seeking to an offset.
      7 // Note that even when used asynchronously, only one operation is supported at
      8 // a time.
      9 
     10 #ifndef NET_BASE_FILE_STREAM_H_
     11 #define NET_BASE_FILE_STREAM_H_
     12 
     13 #include "base/platform_file.h"
     14 #include "base/task_runner.h"
     15 #include "net/base/completion_callback.h"
     16 #include "net/base/file_stream_whence.h"
     17 #include "net/base/net_export.h"
     18 #include "net/base/net_log.h"
     19 
     20 namespace base {
     21 class FilePath;
     22 }
     23 
     24 namespace net {
     25 
     26 class IOBuffer;
     27 
     28 class NET_EXPORT FileStream {
     29  public:
     30   // Creates a |FileStream| with a new |BoundNetLog| (based on |net_log|)
     31   // attached.  |net_log| may be NULL if no logging is needed.
     32   // Uses |task_runner| for asynchronous operations.
     33   FileStream(net::NetLog* net_log,
     34              const scoped_refptr<base::TaskRunner>& task_runner);
     35 
     36   // Same as above, but runs async tasks in base::WorkerPool.
     37   explicit FileStream(net::NetLog* net_log);
     38 
     39   // Construct a FileStream with an existing file handle and opening flags.
     40   // |file| is valid file handle.
     41   // |flags| is a bitfield of base::PlatformFileFlags when the file handle was
     42   // opened.
     43   // |net_log| is the net log pointer to use to create a |BoundNetLog|.  May be
     44   // NULL if logging is not needed.
     45   // Uses |task_runner| for asynchronous operations.
     46   // Note: the new FileStream object takes ownership of the PlatformFile and
     47   // will close it on destruction.
     48   FileStream(base::PlatformFile file,
     49              int flags,
     50              net::NetLog* net_log,
     51              const scoped_refptr<base::TaskRunner>& task_runner);
     52 
     53   // Same as above, but runs async tasks in base::WorkerPool.
     54   FileStream(base::PlatformFile file, int flags, net::NetLog* net_log);
     55 
     56   // The underlying file is closed automatically.
     57   virtual ~FileStream();
     58 
     59   // Call this method to open the FileStream asynchronously.  The remaining
     60   // methods cannot be used unless the file is opened successfully. Returns
     61   // ERR_IO_PENDING if the operation is started. If the operation cannot be
     62   // started then an error code is returned.
     63   //
     64   // Once the operation is done, |callback| will be run on the thread where
     65   // Open() was called, with the result code. open_flags is a bitfield of
     66   // base::PlatformFileFlags.
     67   //
     68   // If the file stream is not closed manually, the underlying file will be
     69   // automatically closed when FileStream is destructed in an asynchronous
     70   // manner (i.e. the file stream is closed in the background but you don't
     71   // know when).
     72   virtual int Open(const base::FilePath& path, int open_flags,
     73                    const CompletionCallback& callback);
     74 
     75   // Call this method to open the FileStream synchronously.
     76   // The remaining methods cannot be used unless this method returns OK.  If
     77   // the file cannot be opened then an error code is returned.  open_flags is
     78   // a bitfield of base::PlatformFileFlags
     79   //
     80   // If the file stream is not closed manually, the underlying file will be
     81   // automatically closed when FileStream is destructed.
     82   virtual int OpenSync(const base::FilePath& path, int open_flags);
     83 
     84   // Returns true if Open succeeded and Close has not been called.
     85   virtual bool IsOpen() const;
     86 
     87   // Adjust the position from where data is read asynchronously.
     88   // Upon success, ERR_IO_PENDING is returned and |callback| will be run
     89   // on the thread where Seek() was called with the the stream position
     90   // relative to the start of the file.  Otherwise, an error code is returned.
     91   // It is invalid to request any asynchronous operations while there is an
     92   // in-flight asynchronous operation.
     93   virtual int Seek(Whence whence, int64 offset,
     94                    const Int64CompletionCallback& callback);
     95 
     96   // Adjust the position from where data is read synchronously.
     97   // Upon success, the stream position relative to the start of the file is
     98   // returned.  Otherwise, an error code is returned.  It is not valid to
     99   // call SeekSync while a Read call has a pending completion.
    100   virtual int64 SeekSync(Whence whence, int64 offset);
    101 
    102   // Returns the number of bytes available to read from the current stream
    103   // position until the end of the file.  Otherwise, an error code is returned.
    104   virtual int64 Available();
    105 
    106   // Call this method to read data from the current stream position
    107   // asynchronously. Up to buf_len bytes will be copied into buf.  (In
    108   // other words, partial reads are allowed.)  Returns the number of bytes
    109   // copied, 0 if at end-of-file, or an error code if the operation could
    110   // not be performed.
    111   //
    112   // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
    113   // callback must be passed to this method. If the read could not
    114   // complete synchronously, then ERR_IO_PENDING is returned, and the
    115   // callback will be run on the thread where Read() was called, when the
    116   // read has completed.
    117   //
    118   // It is valid to destroy or close the file stream while there is an
    119   // asynchronous read in progress.  That will cancel the read and allow
    120   // the buffer to be freed.
    121   //
    122   // It is invalid to request any asynchronous operations while there is an
    123   // in-flight asynchronous operation.
    124   //
    125   // This method must not be called if the stream was opened WRITE_ONLY.
    126   virtual int Read(IOBuffer* buf, int buf_len,
    127                    const CompletionCallback& callback);
    128 
    129   // Call this method to read data from the current stream position
    130   // synchronously. Up to buf_len bytes will be copied into buf.  (In
    131   // other words, partial reads are allowed.)  Returns the number of bytes
    132   // copied, 0 if at end-of-file, or an error code if the operation could
    133   // not be performed.
    134   //
    135   // The file must not be opened with PLATFORM_FILE_ASYNC.
    136   // This method must not be called if the stream was opened WRITE_ONLY.
    137   virtual int ReadSync(char* buf, int buf_len);
    138 
    139   // Performs the same as ReadSync, but ensures that exactly buf_len bytes
    140   // are copied into buf.  A partial read may occur, but only as a result of
    141   // end-of-file or fatal error.  Returns the number of bytes copied into buf,
    142   // 0 if at end-of-file and no bytes have been read into buf yet,
    143   // or an error code if the operation could not be performed.
    144   virtual int ReadUntilComplete(char *buf, int buf_len);
    145 
    146   // Call this method to write data at the current stream position
    147   // asynchronously.  Up to buf_len bytes will be written from buf. (In
    148   // other words, partial writes are allowed.)  Returns the number of
    149   // bytes written, or an error code if the operation could not be
    150   // performed.
    151   //
    152   // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
    153   // callback must be passed to this method. If the write could not
    154   // complete synchronously, then ERR_IO_PENDING is returned, and the
    155   // callback will be run on the thread where Write() was called when
    156   // the write has completed.
    157   //
    158   // It is valid to destroy or close the file stream while there is an
    159   // asynchronous write in progress.  That will cancel the write and allow
    160   // the buffer to be freed.
    161   //
    162   // It is invalid to request any asynchronous operations while there is an
    163   // in-flight asynchronous operation.
    164   //
    165   // This method must not be called if the stream was opened READ_ONLY.
    166   //
    167   // Zero byte writes are not allowed.
    168   virtual int Write(IOBuffer* buf, int buf_len,
    169                     const CompletionCallback& callback);
    170 
    171   // Call this method to write data at the current stream position
    172   // synchronously.  Up to buf_len bytes will be written from buf. (In
    173   // other words, partial writes are allowed.)  Returns the number of
    174   // bytes written, or an error code if the operation could not be
    175   // performed.
    176   //
    177   // The file must not be opened with PLATFORM_FILE_ASYNC.
    178   // This method must not be called if the stream was opened READ_ONLY.
    179   //
    180   // Zero byte writes are not allowed.
    181   virtual int WriteSync(const char* buf, int buf_len);
    182 
    183   // Truncates the file to be |bytes| length. This is only valid for writable
    184   // files. After truncation the file stream is positioned at |bytes|. The new
    185   // position is returned, or a value < 0 on error.
    186   // WARNING: one may not truncate a file beyond its current length on any
    187   //   platform with this call.
    188   virtual int64 Truncate(int64 bytes);
    189 
    190   // Forces out a filesystem sync on this file to make sure that the file was
    191   // written out to disk and is not currently sitting in the buffer. This does
    192   // not have to be called, it just forces one to happen at the time of
    193   // calling.
    194   //
    195   // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
    196   // callback must be passed to this method. If the write could not
    197   // complete synchronously, then ERR_IO_PENDING is returned, and the
    198   // callback will be run on the thread where Flush() was called when
    199   // the write has completed.
    200   //
    201   // It is valid to destroy or close the file stream while there is an
    202   // asynchronous flush in progress.  That will cancel the flush and allow
    203   // the buffer to be freed.
    204   //
    205   // It is invalid to request any asynchronous operations while there is an
    206   // in-flight asynchronous operation.
    207   //
    208   // This method should not be called if the stream was opened READ_ONLY.
    209   virtual int Flush(const CompletionCallback& callback);
    210 
    211   // Forces out a filesystem sync on this file to make sure that the file was
    212   // written out to disk and is not currently sitting in the buffer. This does
    213   // not have to be called, it just forces one to happen at the time of
    214   // calling.
    215   //
    216   // Returns an error code if the operation could not be performed.
    217   //
    218   // This method should not be called if the stream was opened READ_ONLY.
    219   virtual int FlushSync();
    220 
    221   // Turns on UMA error statistics gathering.
    222   void EnableErrorStatistics();
    223 
    224   // Sets the source reference for net-internals logging.
    225   // Creates source dependency events between |owner_bound_net_log| and
    226   // |bound_net_log_|.  Each gets an event showing the dependency on the other.
    227   // If only one of those is valid, it gets an event showing that a change
    228   // of ownership happened, but without details.
    229   void SetBoundNetLogSource(const net::BoundNetLog& owner_bound_net_log);
    230 
    231   // Returns the underlying platform file for testing.
    232   base::PlatformFile GetPlatformFileForTesting();
    233 
    234  private:
    235   class Context;
    236 
    237   bool is_async() const { return !!(open_flags_ & base::PLATFORM_FILE_ASYNC); }
    238 
    239   int open_flags_;
    240   net::BoundNetLog bound_net_log_;
    241 
    242   // Context performing I/O operations. It was extracted into separate class
    243   // to perform asynchronous operations because FileStream can be destroyed
    244   // before completion of async operation. Also if async FileStream is destroyed
    245   // without explicit closing file should be closed asynchronously without
    246   // delaying FileStream's destructor. To perform all that separate object is
    247   // necessary.
    248   scoped_ptr<Context> context_;
    249 
    250   DISALLOW_COPY_AND_ASSIGN(FileStream);
    251 };
    252 
    253 }  // namespace net
    254 
    255 #endif  // NET_BASE_FILE_STREAM_H_
    256