1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#ifndef __Basic_Handler_hpp__
#define __Basic_Handler_hpp__ 1
// =================================================================================================
// Copyright Adobe
// Copyright 2004 Adobe
// 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 "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 "XMPFiles/source/XMPFiles_Impl.hpp"
// =================================================================================================
/// \file Basic_Handler.hpp
///
/// \brief Base class for handlers that support a simple file model allowing insertion and expansion
/// of XMP, but probably not reconciliation with other forms of metadata. Reconciliation would have
/// to be done within the I/O model presented here.
///
/// \note Any specific derived handler might not be able to do insertion, but all must support
/// expansion. If a handler can't do either it should be derived from Trivial_Handler. Common code
/// must check the actual canInject flag where appropriate.
///
/// The model for a basic handler divides the file into 6 portions:
///
/// \li The front of the file. This portion can be arbitrarily large. Files over 4GB are supported.
/// Adding or expanding the XMP must not require expanding this portion of the file. The XMP offset
/// or length might be written into reserved space in this section though.
///
/// \li A prefix for the XMP section. The prefix and suffix for the XMP "section" are the format
/// specific portions that surround the raw XMP packet. They must be generated on the fly, even when
/// updating existing XMP with or without expansion. Their length must not depend on the XMP packet.
///
/// \li The XMP packet, as created by SXMPMeta::SerializeToBuffer. The size must be less than 2GB.
///
/// \li A suffix for the XMP section.
///
/// \li Trailing file content. This portion can be arbitarily large. It must be possible to remove
/// the XMP, move this portion of the file forward, then reinsert the XMP after this portion. This
/// is actually how the XMP is expanded. There must not be any embedded file offsets in this part,
/// this content must not change if the XMP changes size.
///
/// \li The back of the file. This portion must have modest size, and/or be generated on the fly.
/// When inserting XMP, part of this may be buffered in RAM (hence the modest size requirement), the
/// XMP section is written, then this portion is rewritten. There must not be any embedded file
/// offsets in this part, this content must not change if the XMP changes size.
///
/// \note There is no general promise here about crash-safe I/O. An update to an existing file might
/// have invalid partial state, for example while moving the trailing content portion forward if the
/// XMP increases in size or even rewriting existing XMP in-place. Crash-safe updates are managed at
/// a higher level of XMPFiles, using a temporary file and final swap of file content.
///
// =================================================================================================
static const XMP_OptionBits kBasic_HandlerFlags = (kXMPFiles_CanInjectXMP |
kXMPFiles_CanExpand |
kXMPFiles_CanRewrite |
kXMPFiles_PrefersInPlace |
kXMPFiles_AllowsOnlyXMP |
kXMPFiles_ReturnsRawPacket |
kXMPFiles_AllowsSafeUpdate);
class Basic_MetaHandler : public XMPFileHandler
{
public:
Basic_MetaHandler() :
xmpFileOffset(0), xmpFileSize(0), xmpPrefixSize(0), xmpSuffixSize(0), trailingContentSize(0) {};
~Basic_MetaHandler();
virtual void CacheFileData() = 0; // Sets offset for insertion if no XMP yet.
void UpdateFile ( bool doSafeUpdate );
void WriteTempFile ( XMP_IO* tempRef );
protected:
// Write a cached or fixed prefix or suffix for the XMP. The file is passed because it could be
// either the original file or a safe-update temp file.
virtual void WriteXMPPrefix ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
virtual void WriteXMPSuffix ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
// Note that the XMP is being removed or inserted. The file is passed because it could be either
// the original file or a safe-update temp file.
virtual void NoteXMPRemoval ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
virtual void NoteXMPInsertion ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
// Capture or restore the tail portion of the file. The file is passed because it could be either
// the original file or a safe-update temp file.
virtual void CaptureFileEnding ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
virtual void RestoreFileEnding ( XMP_IO* fileRef ) = 0; // ! Must have override in actual handlers!
// Move the trailing content portion forward. Excludes "back" of the file. The file is passed
// because it could be either the original file or a safe-update temp file.
void ShuffleTrailingContent ( XMP_IO* fileRef ); // Has a common implementation.
XMP_Uns64 xmpFileOffset; // The offset of the XMP in the file.
XMP_Uns32 xmpFileSize; // The size of the XMP in the file.
// ! The packetInfo offset and length are updated by PutXMP, before the file is updated!
XMP_Uns32 xmpPrefixSize; // The size of the existing header for the XMP section.
XMP_Uns32 xmpSuffixSize; // The size of the existing trailer for the XMP section.
XMP_Uns64 trailingContentSize; // The size of the existing trailing content. Excludes "back" of the file.
}; // Basic_MetaHandler
// =================================================================================================
#endif /* __Basic_Handler_hpp__ */
|