#ifndef __XMP_IO_hpp__ #define __XMP_IO_hpp__ 1 // ================================================================================================= // ADOBE SYSTEMS INCORPORATED // Copyright 2010 Adobe Systems Incorporated // All Rights Reserved // // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms // of the Adobe license agreement accompanying it. // ================================================================================================= #include "XMP_Environment.h" // ! XMP_Environment.h must be the first included header. #include "XMP_Const.h" // ================================================================================================= /// \class XMP_IO XMP_IO.hpp /// \brief Abstract base class for client-managed I/O with \c TXMPFiles. /// /// \c XMP_IO is an abstract base class for client-managed I/O with \c TXMPFiles. This allows a /// client to use the embedded metadata processing logic of \c TXMPFiles in cases where a string /// file path cannot be provided, or where it is impractical to allow \c TXMPFiles to separately /// open the file and do its own I/O. Although described in terms of files, any form of storage may /// be used as long as the functions operate as defined. /// /// This is not a general purpose I/O class. It contains only the necessary functions needed by the /// internals of \c TXMPFiles. It is intended to be used as an adaptor for an existing I/O mechanism /// that the client wants \c TXMPFiles to use. /// /// To use \c XMP_IO, a client creates a derived class then uses the form of \c TCMPFiles::OpenFile /// that takes an \c XMP_IO parameter instead of a string file path. The derived \c XMP_IO object /// must be ready for use when \c TCMPFiles::OpenFile is called. /// /// There are no Open or Close functions in \c XMP_IO, they are specific to each implementation. The /// derived \c XMP_IO object must be open and ready for use before being passed to \c /// TXMP_Files::OpenFile, and remain open and ready for use until \c TXMP_Files::CloseFile returns, /// or some other fatal error occurs. The client has final responsibility for closing and /// terminating the derived \c XMP_IO object. // ================================================================================================= class XMP_IO { public: // --------------------------------------------------------------------------------------------- /// @brief Read into a buffer, returning the number of bytes read. /// /// Read into a buffer, returning the number of bytes read. Returns the actual number of bytes /// read. Throws an exception if requireSuccess is true and not enough data is available. /// Throwing \c XMPError is recommended. The buffer content and I/O position after a throw are /// undefined. /// /// @param buffer A pointer to the buffer. /// @param count The length of the buffer in bytes. /// @param readAll True if reading less than the requested amount is a failure. /// /// @return Returns the number of bytes read. enum { kReadAll = true }; virtual XMP_Uns32 Read ( void* buffer, XMP_Uns32 count, bool readAll = false ) = 0; inline XMP_Uns32 ReadAll ( void* buffer, XMP_Uns32 bytes ) { return this->Read ( buffer, bytes, kReadAll ); }; // --------------------------------------------------------------------------------------------- /// @brief Write from a buffer. /// /// Write from a buffer, overwriting existing data and extending the file as necesary. All data /// must be written or an exception thrown. Throwing \c XMPError is recommended. /// /// @param buffer A pointer to the buffer. /// @param count The length of the buffer in bytes. virtual void Write ( const void* buffer, XMP_Uns32 count ) = 0; // --------------------------------------------------------------------------------------------- /// @brief Set the I/O position, returning the new absolute offset in bytes. /// /// Set the I/O position, returning the new absolute offset in bytes. The offset parameter may /// be positive or negative. A seek beyond EOF is allowed when writing and extends the file, it /// is equivalent to seeking to EOF then writing the needed amount of undefined data. A /// read-only seek beyond EOF throws an exception. Throwing \c XMPError is recommended. /// /// @param offset The offset relative to the mode. /// @param mode The mode, or origin, of the seek. /// /// @return The new absolute offset in bytes. virtual XMP_Int64 Seek ( XMP_Int64 offset, SeekMode mode ) = 0; inline XMP_Int64 Offset() { return this->Seek ( 0, kXMP_SeekFromCurrent ); }; inline XMP_Int64 Rewind() { return this->Seek ( 0, kXMP_SeekFromStart ); }; // Always returns 0. inline XMP_Int64 ToEOF() { return this->Seek ( 0, kXMP_SeekFromEnd ); }; // --------------------------------------------------------------------------------------------- /// @brief Return the length of the file in bytes. /// /// Return the length of the file in bytes. The I/O position is unchanged. /// /// @return The length of the file in bytes. virtual XMP_Int64 Length() = 0; // --------------------------------------------------------------------------------------------- /// @brief Truncate the file to the given length. /// /// Truncate the file to the given length. The I/O position after truncation is unchanged if /// still valid, otherwise it is set to the new EOF. Throws an exception if the new length is /// longer than the file's current length. Throwing \c XMPError is recommended. /// /// @param length The new length for the file, must be less than or equal to the current length. virtual void Truncate ( XMP_Int64 length ) = 0; // --------------------------------------------------------------------------------------------- /// @brief Create an associated temp file for use in a safe-save style operation. /// /// Create an associated temp file, for example in the same directory and with a related name. /// Returns an already existing temp with no other action. The temp must be opened for /// read-write access. It will be used in a safe-save style operation, using some of the /// original file plus new portions to write the temp, then replacing the original from the temp /// when done. Throws an exception if the owning object is opened for read-only access, or if /// the temp file cannot be created. Throwing \c XMPError is recommended. /// /// The temp file is normally closed and deleted, and the temporary \c XMP_IO object deleted, by /// a call to \c AbsorbTemp or \c DeleteTemp. It must be closed and deleted by the derived \c /// XMP_IO object's destructor if necessary. /// /// \c DeriveTemp may be called on a temporary \c XMP_IO object. /// /// @return A pointer to the associated temporary \c XMP_IO object. virtual XMP_IO* DeriveTemp() = 0; // --------------------------------------------------------------------------------------------- /// @brief Replace the owning file's content with that of the temp. /// /// Used at the end of a safe-save style operation to replace the original content with that /// from the associated temp file. The temp file must be closed and deleted after the content /// swap. The temporary \c XMP_IO object is deleted. Throws an exception if the temp file cannot /// be absorbed. Throwing \c XMPError is recommended. virtual void AbsorbTemp() = 0; // --------------------------------------------------------------------------------------------- /// @brief Delete a temp file, leaving the original alone. /// /// Used for a failed safe-save style operation. The temp file is closed and deleted without /// being absorbed, and the temporary \c XMP_IO object is deleted. Does nothing if no temp /// exists. virtual void DeleteTemp() = 0; // --------------------------------------------------------------------------------------------- XMP_IO() {}; virtual ~XMP_IO() {}; private: // --------------------------------------------------------------------------------------------- /// Copy construction and assignment are not public. That would require the implementation to /// share state across multiple XMP_IO objects. XMP_IO ( const XMP_IO & original ); void operator= ( const XMP_IO& in ) { *this = in; /* Avoid Win compile warnings. */ }; }; #endif // __XMP_IO_hpp__