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