• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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