1 #ifndef IMAGE_IO_EXTRAS_BASE64_DECODER_DATA_DESTINATION_H_  // NOLINT
2 #define IMAGE_IO_EXTRAS_BASE64_DECODER_DATA_DESTINATION_H_  // NOLINT
3 #define IMAGE_IO_noumenon_base64_h
4 
5 #include <vector>
6 
7 #include "image_io/base/data_destination.h"
8 #include "image_io/base/message_handler.h"
9 
10 namespace photos_editing_formats {
11 namespace image_io {
12 
13 /// Base64DecoderDataDestination is typically used in a chain of DataDestination
14 /// instances. For example, it can be used to decode base64 encoded JPEG data in
15 /// APP1/XMP data segments.
16 class Base64DecoderDataDestination : public DataDestination {
17  public:
18   /// @param next_destination The next DataDestination in the chain which will
19   /// be sent the decoded bytes received by the Transfer() function.
20   /// @param message_handler An optional message handler to write messages to.
Base64DecoderDataDestination(DataDestination * next_destination,MessageHandler * message_handler)21   Base64DecoderDataDestination(DataDestination* next_destination,
22                                MessageHandler* message_handler)
23       : next_destination_(next_destination),
24         message_handler_(message_handler),
25         next_decoded_location_(0),
26         has_error_(false) {}
27 
28   /// @return True if there was an error in the decoding process.
HasError()29   bool HasError() const { return has_error_; }
30 
31   void StartTransfer() override;
32   TransferStatus Transfer(const DataRange& transfer_range,
33                           const DataSegment& data_segment) override;
34   void FinishTransfer() override;
35 
36   /// @return The number of bytes written not to this decoder destination, but
37   /// to the next destination. Returns zero if the next destination is null.
GetBytesTransferred()38   size_t GetBytesTransferred() const override {
39     return next_destination_ ? next_destination_->GetBytesTransferred() : 0;
40   }
41 
42  private:
43   /// The destination that the decoded data is sent to.
44   DataDestination* next_destination_;
45 
46   /// An optional message handler to write messages to.
47   MessageHandler* message_handler_;
48 
49   /// If the transfer_range parameter of the Transfer function does not have a
50   /// length that is a multiple of 4, then the leftover bytes are placed in this
51   /// vector and are prepended to the data in the next call to Transfer.
52   std::vector<Byte> leftover_bytes_;
53 
54   /// The DataRanges supplied to the Transfer function can't be sent down the
55   /// chain to the next destination because the number of bytes differ (by 4/3).
56   /// This value records the number of bytes decoded so far, and the beginning
57   /// of the DataRange sent to the destination's Transfer function.
58   size_t next_decoded_location_;
59 
60   /// A true value indicates that an error occurred in the decoding process.
61   bool has_error_;
62 };
63 
64 }  // namespace image_io
65 }  // namespace photos_editing_formats
66 
67 #endif // IMAGE_IO_EXTRAS_BASE64_DECODER_DATA_DESTINATION_H_  // NOLINT
68