1 // =================================================================================================
2 // ADOBE SYSTEMS INCORPORATED
3 // Copyright 2011 Adobe Systems Incorporated
4 // All Rights Reserved
5 //
6 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
7 // of the Adobe license agreement accompanying it.
8 // =================================================================================================
9
10 #include "FileHandlerInstance.h"
11
12 namespace XMP_PLUGIN
13 {
14
FileHandlerInstance(SessionRef object,FileHandlerSharedPtr handler,XMPFiles * _parent)15 FileHandlerInstance::FileHandlerInstance ( SessionRef object, FileHandlerSharedPtr handler, XMPFiles * _parent ):
16 XMPFileHandler( _parent ), mObject( object ), mHandler( handler )
17 {
18 this->handlerFlags = mHandler->getHandlerFlags();
19 this->stdCharForm = kXMP_Char8Bit;
20 PluginManager::addHandlerInstance( this->mObject, this );
21 }
22
~FileHandlerInstance()23 FileHandlerInstance::~FileHandlerInstance()
24 {
25 WXMP_Error error;
26 mHandler->getModule()->getPluginAPIs()->mTerminateSessionProc( this->mObject, &error );
27 PluginManager::removeHandlerInstance( this->mObject );
28 CheckError( error );
29 }
30
GetFileModDate(XMP_DateTime * modDate)31 bool FileHandlerInstance::GetFileModDate ( XMP_DateTime * modDate )
32 {
33 XMP_Bool ok;
34 WXMP_Error error;
35 GetSessionFileModDateProc wGetFileModDate = mHandler->getModule()->getPluginAPIs()->mGetFileModDateProc;
36 wGetFileModDate ( this->mObject, &ok, modDate, &error );
37 CheckError ( error );
38 return ConvertXMP_BoolToBool( ok );
39 }
40
CacheFileData()41 void FileHandlerInstance::CacheFileData()
42 {
43 if( this->containsXMP ) return;
44
45 WXMP_Error error;
46 XMP_StringPtr xmpStr = NULL;
47 mHandler->getModule()->getPluginAPIs()->mCacheFileDataProc( this->mObject, this->parent->ioRef, &xmpStr, &error );
48
49 if( error.mErrorID != kXMPErr_NoError )
50 {
51 if ( xmpStr != 0 ) free( (void*) xmpStr );
52 if ( error.mErrorID == kXMPErr_FilePermission )
53 throw XMP_Error( kXMPErr_FilePermission, error.mErrorMsg );
54 else
55 throw XMP_Error( kXMPErr_InternalFailure, error.mErrorMsg );
56 }
57
58 if( xmpStr != NULL )
59 {
60 this->xmpPacket.assign( xmpStr );
61 free( (void*) xmpStr ); // It should be freed as documentation of mCacheFileDataProc says so.
62 this->containsXMP = true;
63 }
64 else
65 this->containsXMP = false;
66 }
67
ProcessXMP()68 void FileHandlerInstance::ProcessXMP()
69 {
70 if( this->processedXMP ) return;
71 this->processedXMP = true;
72
73 SXMPUtils::RemoveProperties ( &this->xmpObj, 0, 0, kXMPUtil_DoAllProperties );
74 if ( this->xmpPacket.size() != 0 )
75 this->xmpObj.ParseFromBuffer ( this->xmpPacket.c_str(), (XMP_StringLen)this->xmpPacket.size() );
76
77 WXMP_Error error;
78 if ( mHandler->getModule()->getPluginAPIs()->mVersion >= 4 && mHandler->getModule()->getPluginAPIs()->mImportToXMPStringWithPacketProc )
79 {
80 XMP_StringPtr xmpStr = this->xmpPacket.c_str();
81 XMP_StringPtr oldPacketPtr = NULL;
82 XMP_PacketInfo packetInfo;
83 mHandler->getModule()->getPluginAPIs()->mImportToXMPStringWithPacketProc( this->mObject, &xmpStr, &error, &oldPacketPtr, &packetInfo );
84
85 if( xmpStr != NULL && xmpStr != this->xmpPacket.c_str() )
86 {
87 XMP_StringLen newLen = static_cast<XMP_StringLen>(strlen( xmpStr ));
88 this->xmpObj.Erase();
89 this->xmpObj.ParseFromBuffer( xmpStr, newLen, 0 );
90
91 // Note: Freeing memory would not create any problem as plugin would have allocated memory using Host library function
92 free( ( void * ) xmpStr );
93 this->containsXMP = true;
94 }
95
96 if( oldPacketPtr != NULL )
97 {
98 this->xmpPacket.resize( strlen( oldPacketPtr ) );
99 this->xmpPacket.assign( oldPacketPtr );
100 this->packetInfo = packetInfo;
101
102 // Note: Freeing memory would not create any problem as plugin would have allocated memory using Host library function
103 free( ( void * ) oldPacketPtr );
104 this->containsXMP = true;
105 }
106 }
107 else if( mHandler->getModule()->getPluginAPIs()->mVersion >= 2 && mHandler->getModule()->getPluginAPIs()->mImportToXMPStringProc )
108 {
109 XMP_StringPtr xmpStr = this->xmpPacket.c_str();
110 mHandler->getModule()->getPluginAPIs()->mImportToXMPStringProc( this->mObject, &xmpStr, &error );
111
112 if( xmpStr != NULL && xmpStr != this->xmpPacket.c_str() )
113 {
114 XMP_StringLen newLen = static_cast<XMP_StringLen>(strlen( xmpStr ));
115 this->xmpObj.Erase();
116 this->xmpObj.ParseFromBuffer( xmpStr, newLen, 0 );
117
118 // Note: Freeing memory would not create any problem as plugin would have allocated memory using Host library function
119 free( ( void * ) xmpStr );
120 this->containsXMP = true;
121 }
122 }
123 else
124 {
125 if( mHandler->getModule()->getPluginAPIs()->mImportToXMPProc )
126 mHandler->getModule()->getPluginAPIs()->mImportToXMPProc( this->mObject, this->xmpObj.GetInternalRef(), &error );
127 this->containsXMP = true;
128 }
129 CheckError( error );
130 }
131
UpdateFile(bool doSafeUpdate)132 void FileHandlerInstance::UpdateFile ( bool doSafeUpdate )
133 {
134 bool optimizeFileLayout = XMP_OptionIsSet ( this->parent->openFlags, kXMPFiles_OptimizeFileLayout );
135 this->needsUpdate |= optimizeFileLayout;
136 if( !this->needsUpdate ) return;
137 WXMP_Error error;
138
139 if ( xmpPacket.size() != 0 )
140 {
141 if( mHandler->getModule()->getPluginAPIs()->mExportFromXMPStringProc )
142 {
143 std::string xmp;
144 this->xmpObj.SerializeToBuffer( &xmp, kXMP_NoOptions, 0 );
145 XMP_StringPtr xmpStr = xmp.c_str();
146 mHandler->getModule()->getPluginAPIs()->mExportFromXMPStringProc( this->mObject, xmpStr, &error );
147 if ( xmpStr != xmp.c_str() )
148 this->xmpObj.SerializeToBuffer ( &this->xmpPacket, mHandler->getSerializeOption() );
149 }
150 else
151 {
152 if( mHandler->getModule()->getPluginAPIs()->mExportFromXMPProc )
153 {
154 mHandler->getModule()->getPluginAPIs()->mExportFromXMPProc( this->mObject, this->xmpObj.GetInternalRef(), &error );
155 this->xmpObj.SerializeToBuffer ( &this->xmpPacket, mHandler->getSerializeOption() );
156 }
157 }
158 CheckError( error );
159
160
161 }
162 mHandler->getModule()->getPluginAPIs()->mUpdateFileProc( this->mObject, this->parent->ioRef, doSafeUpdate, this->xmpPacket.c_str(), &error );
163 CheckError( error );
164 this->needsUpdate = false;
165 }
166
WriteTempFile(XMP_IO * tempRef)167 void FileHandlerInstance::WriteTempFile( XMP_IO* tempRef )
168 {
169 WXMP_Error error;
170 if( mHandler->getModule()->getPluginAPIs()->mExportFromXMPProc )
171 mHandler->getModule()->getPluginAPIs()->mExportFromXMPProc( this->mObject, this->xmpObj.GetInternalRef(), &error );
172 CheckError( error );
173
174 this->xmpObj.SerializeToBuffer ( &this->xmpPacket, mHandler->getSerializeOption() );
175
176 mHandler->getModule()->getPluginAPIs()->mWriteTempFileProc( this->mObject, this->parent->ioRef, tempRef, this->xmpPacket.c_str(), &error );
177 CheckError( error );
178 }
179
SetStringVector(StringVectorRef clientPtr,XMP_StringPtr * arrayPtr,XMP_Uns32 stringCount)180 static void SetStringVector ( StringVectorRef clientPtr, XMP_StringPtr * arrayPtr, XMP_Uns32 stringCount )
181 {
182 std::vector<std::string>* clientVec = (std::vector<std::string>*) clientPtr;
183 clientVec->clear();
184 for ( XMP_Uns32 i = 0; i < stringCount; ++i ) {
185 std::string nextValue ( arrayPtr[i] );
186 clientVec->push_back ( nextValue );
187 }
188 }
189
FillMetadataFiles(std::vector<std::string> * metadataFiles)190 void FileHandlerInstance::FillMetadataFiles( std::vector<std::string> * metadataFiles )
191 {
192 WXMP_Error error;
193 FillMetadataFilesProc wFillMetadataFilesProc = mHandler->getModule()->getPluginAPIs()->mFillMetadataFilesProc;
194 if ( wFillMetadataFilesProc ) {
195 wFillMetadataFilesProc( this->mObject, metadataFiles, SetStringVector, &error);
196 CheckError( error );
197 } else {
198 XMP_Throw ( "This version of plugin does not support FillMetadataFiles API", kXMPErr_Unimplemented );
199 }
200 }
201
FillAssociatedResources(std::vector<std::string> * resourceList)202 void FileHandlerInstance::FillAssociatedResources( std::vector<std::string> * resourceList )
203 {
204 WXMP_Error error;
205 FillAssociatedResourcesProc wFillAssociatedResourcesProc = mHandler->getModule()->getPluginAPIs()->mFillAssociatedResourcesProc;
206 if ( wFillAssociatedResourcesProc ) {
207 wFillAssociatedResourcesProc( this->mObject, resourceList, SetStringVector, &error);
208 CheckError( error );
209 } else {
210 XMP_Throw ( "This version of plugin does not support FillAssociatedResources API", kXMPErr_Unimplemented );
211 }
212 }
213
IsMetadataWritable()214 bool FileHandlerInstance::IsMetadataWritable( )
215 {
216 WXMP_Error error;
217 XMP_Bool result = kXMP_Bool_False;
218 IsMetadataWritableProc wIsMetadataWritableProc = mHandler->getModule()->getPluginAPIs()->mIsMetadataWritableProc;
219 if ( wIsMetadataWritableProc ) {
220 wIsMetadataWritableProc( this->mObject, &result, &error);
221 CheckError( error );
222 } else {
223 XMP_Throw ( "This version of plugin does not support IsMetadataWritable API", kXMPErr_Unimplemented );
224 }
225 return ConvertXMP_BoolToBool( result );
226 }
227
SetErrorCallback(ErrorCallbackBox errorCallbackBox)228 void FileHandlerInstance::SetErrorCallback ( ErrorCallbackBox errorCallbackBox )
229 {
230 WXMP_Error error;
231 SetErrorCallbackproc wSetErrorCallbackproc = mHandler->getModule()->getPluginAPIs()->mSetErrorCallbackproc ;
232 if( wSetErrorCallbackproc ) {
233 wSetErrorCallbackproc( this->mObject, errorCallbackBox, &error );
234 CheckError( error );
235 } else {
236 XMP_Throw ( "This version of plugin does not support IsMetadataWritable API", kXMPErr_Unimplemented );
237 }
238 }
239
SetProgressCallback(XMP_ProgressTracker::CallbackInfo * progCBInfoPtr)240 void FileHandlerInstance::SetProgressCallback ( XMP_ProgressTracker::CallbackInfo * progCBInfoPtr )
241 {
242 WXMP_Error error;
243 SetProgressCallbackproc wSetProgressCallbackproc = mHandler->getModule()->getPluginAPIs()->mSetProgressCallbackproc ;
244 if( wSetProgressCallbackproc ) {
245 wSetProgressCallbackproc( this->mObject, progCBInfoPtr, &error );
246 CheckError( error );
247 } else {
248 XMP_Throw ( "This version of plugin does not support IsMetadataWritable API", kXMPErr_Unimplemented );
249 }
250 }
251
252 } //namespace XMP_PLUGIN
253