diff options
Diffstat (limited to 'XMPFiles/source/FormatSupport/IFF/ChunkController.h')
-rw-r--r-- | XMPFiles/source/FormatSupport/IFF/ChunkController.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/XMPFiles/source/FormatSupport/IFF/ChunkController.h b/XMPFiles/source/FormatSupport/IFF/ChunkController.h new file mode 100644 index 0000000..933da36 --- /dev/null +++ b/XMPFiles/source/FormatSupport/IFF/ChunkController.h @@ -0,0 +1,246 @@ +// ================================================================================================= +// 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. +// ================================================================================================= + +#ifndef _ChunkController_h_ +#define _ChunkController_h_ + +#include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. + +#include "public/include/XMP_Const.h" +#include "public/include/XMP_IO.hpp" + +#include "source/XMP_LibUtils.hpp" + +#include "XMPFiles/source/FormatSupport/IFF/ChunkPath.h" +#include "XMPFiles/source/FormatSupport/IFF/IChunkBehavior.h" + +class IEndian; + +namespace IFF_RIFF +{ +/** + The class ChunkController is supposed to act as an controller between the IRIFFHandler and the actual chunks (Chunk instances). + It controls the parsing and writing of the passed stream. +*/ + +class IChunkData; +class IChunkContainer; +class Chunk; + +class ChunkController +{ + public: + /** + * Constructor: + * Creates an IEndian based instance for further usage. + * + * @param IChunkBehavior* chunkBehavior : for AVI the IChunkBehavior instance would be an instance of a IChunkBehavior class, that knows + * about the 1,2,4 GB border, padding byte special cases, AVIX stuff and so on. That knowledge would + * be used during writeFile() + * In the case of WAVE it would be an instance of WAVEBehavior that would know how to get the 64bit + * size values for RF64 if required. That knowledge would be used during parseFile() + * @param XMP_Bool bigEndian set True if file chunk data is big endian (e.g. AIFF). + * Must explicitely be set, so that handlers do not accidentaly use the wrong endianess + */ + ChunkController( IChunkBehavior* chunkBehavior, XMP_Bool bigEndian ); + + ~ChunkController(); + + /** + * Adds the given path to the array of "Chunk's of interest", + * + * @param path List of Paths that should be parsed + * example AVI: [ RIFF:AVI/LIST:INFO , RIFF:AVIX/LIST:INFO, RIFF:AVI/LIST:TDAT ] + */ + void addChunkPath( const ChunkPath& path ); + + /** + * construct the tree, parse children for list of interesting Chunks + * All requested leaf chunks are cached, the parent chunks are created but not cached + * and the rest is skipped. + * + * @param stream the open [file] stream with file pointer at the beginning of the file + * + */ + void parseFile( XMP_IO* stream, XMP_OptionBits* options = NULL ); + + /** + * Create a new empty chunk + * + * @param id Chunk identifier + * @param type Chunk type [optional] + * @return New IChunkData with passed id/type + */ + IChunkData* createChunk( XMP_Uns32 id, XMP_Uns32 type = kType_NONE ); + + /** + * Insert a new chunk. The position of this new chunk within the hierarchy + * is determined internally by the behavior. + * Throws an exception if a chunk cannot be inserted into the tree + * + * @param chunk The chunk to insert into the tree + */ + void insertChunk( IChunkData* chunk ); + + /** + * Delete a chunk or remove/delete it from the tree. + * If the chunk exists within the chunk hierarchy the chunk gets removed from the tree and deleted. + * If it is not in the tree, then it is only destroyed. + * + * @param chunk Chunk to remove/delete + */ + void removeChunk( IChunkData* chunk ); + + /** + * Called by the handler to write back the changes to the file. + * 1. fix the file tree (ChunkBehavior#fixHierarchy), + * offsets are corrected, no overlapping chunks; + * if rearranging fails, the file is not touched + * 2. write the changed chunks to the file + * + * @param stream the open [file] stream for writing, the file pointer must be at the beginning + */ + void writeFile( XMP_IO* stream ); + + /** + * Returns the first (or last) Chunk that matches the passed path. + * + * @param path the path of the Chunk to return + * @param last in case of duplicates return the last one + * @return Returns Chunk or NULL + */ + IChunkData* getChunk( const ChunkPath& path, XMP_Bool last = false ) const; + + /** + * Returns all chunks that match completely to the passed path. + * E.g. if FORM:AIFF/LIST is given, it would return all LIST chunks in FORM:AIFF + * + * @param path the path of the Chunk to return + * @return list of found chunks or empty list + */ + const std::vector<IChunkData*>& getChunks( const ChunkPath& path ); + + /** + * returns the number of the bytes after the last valid IFF chunk + */ + inline XMP_Int64 getTrailingGarbageSize() { return mTrailingGarbageSize; }; + + /** + * returns the file size + */ + inline XMP_Int64 getFileSize() { return mFileSize; }; + + /** + * Return an array containing the types of the top level nodes + * Top level nodes are the ones beneath ROOT + */ + const std::vector<XMP_Uns32> getTopLevelTypes(); + + /** + * dumps the tree structure + * + */ + std::string dumpTree( ); + + protected: + /** + * Standard Constructor: + * Hidden on purpose. Must not be used! + * A Controller must have a behavior! + */ + ChunkController() { XMP_Throw("Ctor hidden", kXMPErr_InternalFailure); } + + /** + * The function Parses all the sibling chunks. For every chunk it either caches the chunk, + * skips it, or calls the function recusivly for the children chunks + * + * @param stream the file stream + * @param currentPath the path/id of the Chunk to return + * @param options handler options + * @param parent pointer to the parent chunk + */ + void parseChunks( XMP_IO* stream, ChunkPath& currentPath, XMP_OptionBits* options = NULL, Chunk* parent = NULL ); + + /** + * The function parses all the sibling chunks. For every chunk it either caches the chunk, + * skips it, or calls the function recusivly for the children chunks + * + * @param ChunkPath& currentPath: the path/id of the Chunk to return + */ + ChunkPath::MatchResult compareChunkPaths( const ChunkPath& currentPath ); + + /** + * Find a chunk described by path in the hierarchy of chunks starting at the passed chunk. + * The position of chunk in the hierarchy is described by the parameter currentPath. + * This method is supposed to be recursively. + */ + Chunk* findChunk( const ChunkPath& path, ChunkPath& currentPath, const Chunk& chunk, XMP_Bool last = false ) const; + + /** + * Find all chunks described by path in the hierarchy of chunks starting at the passed chunk. + * The position of chunks in the hierarchy is described by the parameter currentPath. + * Found chunks that match to the path are stored in the member mSearchResults. + * This method is supposed to be recursively. + */ + void findChunks( const ChunkPath& path, ChunkPath& currentPath, const Chunk& chunk ); + + /** + * Cleanup function called from destructor and in case of an exception + */ + void cleanupTree(); + + /** + * return true if the passed in Chunk is part of the Chunk tree + * + * @param chunk the chunk that shall be checked. + */ + bool isInTree( Chunk* chunk ); + + + // Members + + /** + * Endian class. Either BigEndian oder LittleEndian. Based on the file format. + */ + const IEndian* mEndian; + + /** + * Chunk behaviour class. Has file format specific function for getting the size and + * rearranging the chunk tree. + */ + IChunkBehavior* mChunkBehavior; + + /** The list of chunks wich should be cached. */ + std::vector<ChunkPath> mChunkPaths; + + /** Iterator for the list of chunk paths */ + typedef std::vector<ChunkPath>::iterator PathIterator; + + /** The overall filesize after parsing the file stream */ + XMP_Uns64 mFileSize; + + /** The root of the Chunk Tree (top level list) */ + IChunkContainer* mRoot; + + /** Offset of trailing garbage characters */ + XMP_Uns64 mTrailingGarbageOffset; + + /** Size of trailing garbage characters */ + XMP_Uns64 mTrailingGarbageSize; + + /** search results of method getChunks(...) */ + ChunkPath mSearchPath; + + /** Cached search results */ + std::vector<IChunkData*> mSearchResults; +}; // ChunkController + +} // namespace + +#endif |