Home | History | Annotate | Download | only in base
      1 #ifndef IMAGE_IO_BASE_DATA_SOURCE_H_  // NOLINT
      2 #define IMAGE_IO_BASE_DATA_SOURCE_H_  // NOLINT
      3 
      4 #include <memory>
      5 
      6 #include "image_io/base/data_destination.h"
      7 #include "image_io/base/data_range.h"
      8 #include "image_io/base/data_segment.h"
      9 #include "image_io/base/types.h"
     10 
     11 namespace photos_editing_formats {
     12 namespace image_io {
     13 
     14 /// DataSource is the abstract base class for implementations that can provide
     15 /// data from a file or memory buffer or some other container. A data source
     16 /// supports both a pull model for obtaining data, via the GetDataSegment()
     17 /// function, and a push model via a collaborating DataDestination and the
     18 /// TransferData() function.
     19 ///
     20 /// Pushing with a DataSource can be a convenient alternative to using a
     21 /// DataDestination directly when there is a large amount of data that is
     22 /// located in a file, or some type of memory structure that be "wrapped" in
     23 /// a DataSource. The push model provides the most efficient (i.e., least
     24 /// copying of bytes) way to move data from one place to another. For usage of
     25 /// this library on mobile devices with limited memory, this mode of operation
     26 /// is the most attractive. Unfortunately, the push model typically assumes the
     27 /// code knows what portion of bytes to push. The discovery of that portion is
     28 /// most often easier to accomplish with a pull model.
     29 ///
     30 /// The pull model, while needed for efficient implementation of objects that
     31 /// scan the contents of a data source, does represent a challenge when managing
     32 /// the lifetime of the DataSegment instances returned by the GetDataSegment()
     33 /// function - depending on the implementation of the DataSource, the segment it
     34 /// returns might represent the entire array of data, or it might represent just
     35 /// a portion of it that was read from a file. In the first case, the DataSource
     36 /// would probably want to keep ownership of the DataSegment, while in the other
     37 /// case, the DataSource might very well want to pass ownership on to the caller
     38 /// of GetDataSegment(). This problem is solved by allowing sharing of the
     39 /// ownership of the DataSegment via a std::shared_ptr.
     40 ///
     41 /// The push model implemented does not have these complications, so the
     42 /// DataDestination class's Transfer() function takes a simple const reference
     43 /// to a DataSegment, with the ownership firmly held by the DataSource.
     44 class DataSource {
     45  public:
     46   /// The result of a TransferData() operation.
     47   enum TransferDataResult {
     48     /// An error occurred while calling DataDestination::Transfer(), or the
     49     /// data destination was a nullptr.
     50     kTransferDataError,
     51 
     52     /// The DataDestination::Transfer() function was not called because the
     53     /// DataRange was empty or the DataSource was not able to supply any data
     54     /// in the range.
     55     kTransferDataNone,
     56 
     57     /// The data transfer was successful.
     58     kTransferDataSuccess
     59   };
     60 
     61   virtual ~DataSource() = default;
     62 
     63   /// Requests the data source to return a DataSegment with a range starting at
     64   /// the given begin location and extending best_size bytes in length if
     65   /// possible. (If not possible, a shorter range of data may be returned. A
     66   /// larger range may also be returned, depending on the DataSource).
     67   /// If a non-null data segment returned, its DataRange is guarenteed to have
     68   /// at least some overlap with the requested range.
     69   /// @param begin The begin location of the requested data segment.
     70   /// @param min_size The min size of the requested data segment. The size of
     71   ///     the data segment returned may be larger depending on the data source.
     72   /// @return The data segment, or a nullptr if the range of data did not exist
     73   ///     in the data source.
     74   virtual std::shared_ptr<DataSegment> GetDataSegment(size_t begin,
     75                                                       size_t min_size) = 0;
     76 
     77   /// Some data sources may need to be reset if they are accessed via repeated
     78   /// calls to GetDataSegment() all the way to the end of the array of bytes.
     79   /// (For example a file-based DataSource might have eof bits that need to be
     80   /// cleared before re-reading data). This function does that kind of thing.
     81   virtual void Reset() = 0;
     82 
     83   /// Requests the data source to transfer data in the given range to the given
     84   /// DataDestination. Callers must call the data destination's StartTransfer()
     85   /// function before calling this function, and call its FinishTransfer()
     86   /// after this call. This function will call the data destination's Transfer()
     87   /// function zero or more times.
     88   /// @param data_range The range of data to transfer from this data source to
     89   ///     the destination.
     90   /// @param best_size The "best" size of the requested data segment to be sent
     91   ///     to the data destination. The size of the data segment that is sent to
     92   ///     the data destination may be larger than this value, depending on the
     93   ///     data source, or it may be smaller if the requested data range extends
     94   ///     past the end of the data source's range.
     95   /// @param data_destination The receiver of the data.
     96   virtual TransferDataResult TransferData(
     97       const DataRange& data_range, size_t best_size,
     98       DataDestination* data_destination) = 0;
     99 };
    100 
    101 }  // namespace image_io
    102 }  // namespace photos_editing_formats
    103 
    104 #endif // IMAGE_IO_BASE_DATA_SOURCE_H_  // NOLINT
    105