void WXMPFiles_IncrementRefCount_1 ( XMPFilesRef xmpFilesRef ) { WXMP_Result * wResult = &voidResult; // ! Needed to "fool" the EnterWrapper macro. XMP_ENTER_WRAPPER ( "WXMPFiles_IncrementRefCount_1" ) XMPFiles * thiz = (XMPFiles*)xmpFilesRef; ++thiz->clientRefs; XMP_Assert ( thiz->clientRefs > 0 ); XMP_EXIT_WRAPPER_NO_THROW }
void XMP_ProgressTracker::WorkComplete () { if ( this->totalWork == 0.0 ) this->totalWork = 1.0; // Force non-zero fraction done. this->workDone = this->totalWork; XMP_Assert ( this->workDone > 0.0 ); // Needed in NotifyClient for start/stop case. this->NotifyClient ( this->cbInfo.sendStartStop ); this->workInProgress = false; } // XMP_ProgressTracker::WorkComplete
XMP_ProgressTracker::XMP_ProgressTracker ( const CallbackInfo & _cbInfo ) { this->Clear(); if ( _cbInfo.clientProc == 0 ) return; XMP_Assert ( _cbInfo.wrapperProc != 0 ); this->cbInfo = _cbInfo; if ( this->cbInfo.interval < 0.0 ) this->cbInfo.interval = 1.0; } // XMP_ProgressTracker::XMP_ProgressTracker
void WXMPMeta_CTor_1 ( WXMP_Result * wResult ) { XMP_ENTER_WRAPPER ( "WXMPMeta_CTor_1" ) XMPMeta * xmpObj = new XMPMeta(); ++xmpObj->clientRefs; XMP_Assert ( xmpObj->clientRefs == 1 ); wResult->ptrResult = XMPMetaRef ( xmpObj ); XMP_EXIT_WRAPPER }
void WXMPMeta_CTor_1 ( WXMP_Result * wResult ) { XMP_ENTER_Static ( "WXMPMeta_CTor_1" ) // No lib object yet, use the static entry. XMPMeta * xmpObj = new XMPMeta(); ++xmpObj->clientRefs; XMP_Assert ( xmpObj->clientRefs == 1 ); wResult->ptrResult = XMPMetaRef ( xmpObj ); XMP_EXIT }
static void StartElementHandler ( void * userData, XMP_StringPtr name, XMP_StringPtr* attrs ) { XMP_Assert ( attrs != 0 ); ExpatAdapter * thiz = (ExpatAdapter*)userData; size_t attrCount = 0; for ( XMP_StringPtr* a = attrs; *a != 0; ++a ) ++attrCount; if ( (attrCount & 1) != 0 ) XMP_Throw ( "Expat attribute info has odd length", kXMPErr_ExternalFailure ); attrCount = attrCount/2; // They are name/value pairs. #if XMP_DebugBuild & DumpXMLParseEvents if ( thiz->parseLog != 0 ) { PrintIndent ( thiz->parseLog, thiz->elemNesting ); fprintf ( thiz->parseLog, "StartElement: %s, %d attrs", name, attrCount ); for ( XMP_StringPtr* attr = attrs; *attr != 0; attr += 2 ) { XMP_StringPtr attrName = *attr; XMP_StringPtr attrValue = *(attr+1); fprintf ( thiz->parseLog, ", %s = \"%s\"", attrName, attrValue ); } fprintf ( thiz->parseLog, "\n" ); } #endif XML_Node * parentNode = thiz->parseStack.back(); XML_Node * elemNode = new XML_Node ( parentNode, "", kElemNode ); SetQualName ( name, elemNode ); for ( XMP_StringPtr* attr = attrs; *attr != 0; attr += 2 ) { XMP_StringPtr attrName = *attr; XMP_StringPtr attrValue = *(attr+1); XML_Node * attrNode = new XML_Node ( elemNode, "", kAttrNode ); SetQualName ( attrName, attrNode ); attrNode->value = attrValue; if ( attrNode->name == "xml:lang" ) NormalizeLangValue ( &attrNode->value ); elemNode->attrs.push_back ( attrNode ); } parentNode->content.push_back ( elemNode ); thiz->parseStack.push_back ( elemNode ); if ( elemNode->name == "rdf:RDF" ) { thiz->rootNode = elemNode; ++thiz->rootCount; } #if XMP_DebugBuild ++thiz->elemNesting; #endif } // StartElementHandler
void XMPFiles_IO::Truncate ( XMP_Int64 length ) { XMP_FILESIO_START XMP_Assert ( this->fileRef != Host_IO::noFileRef ); XMP_Assert ( this->currOffset == Host_IO::Offset ( this->fileRef ) ); XMP_Assert ( this->currLength == Host_IO::Length ( this->fileRef ) ); if ( this->readOnly ) XMP_Throw ( "New_XMPFiles_IO, truncate not permitted on read only file", kXMPErr_FilePermission ); XMP_Enforce ( length <= this->currLength ); Host_IO::SetEOF ( this->fileRef, length ); this->currLength = length; if ( this->currOffset > this->currLength ) this->currOffset = this->currLength; // ! Seek to the expected offset, some versions of Host_IO::SetEOF implicitly seek to EOF. Host_IO::Seek ( this->fileRef, this->currOffset, kXMP_SeekFromStart ); XMP_Assert ( this->currOffset == Host_IO::Offset ( this->fileRef ) ); XMP_FILESIO_END1 ( kXMPErrSev_FileFatal ) } // XMPFiles_IO::Truncate
XMP_Uns32 XMPFiles_IO::Read ( void * buffer, XMP_Uns32 count, bool readAll /* = false */ ) { XMP_FILESIO_START XMP_Assert ( this->fileRef != Host_IO::noFileRef ); XMP_Assert ( this->currOffset == Host_IO::Offset ( this->fileRef ) ); XMP_Assert ( this->currLength == Host_IO::Length ( this->fileRef ) ); XMP_Assert ( this->currOffset <= this->currLength ); if ( count > (this->currLength - this->currOffset) ) { if ( readAll ) XMP_Throw ( "XMPFiles_IO::Read, not enough data", kXMPErr_EnforceFailure ); count = (XMP_Uns32) (this->currLength - this->currOffset); } XMP_Uns32 amountRead = Host_IO::Read ( this->fileRef, buffer, count ); XMP_Enforce ( amountRead == count ); this->currOffset += amountRead; return amountRead; XMP_FILESIO_END1 ( kXMPErrSev_FileFatal ) return 0; } // XMPFiles_IO::Read
bool XMP_NamespaceTable::Define ( XMP_StringPtr _uri, XMP_StringPtr _suggPrefix, XMP_StringPtr * prefixPtr, XMP_StringLen * prefixLen ) { XMP_AutoLock tableLock ( &this->lock, kXMP_WriteLock ); bool prefixMatches = false; XMP_Assert ( (_uri != 0) && (*_uri != 0) && (_suggPrefix != 0) && (*_suggPrefix != 0) ); XMP_VarString uri ( _uri ); XMP_VarString suggPrefix ( _suggPrefix ); if ( suggPrefix[suggPrefix.size()-1] != ':' ) suggPrefix += ':'; VerifySimpleXMLName ( _suggPrefix, _suggPrefix+suggPrefix.size()-1 ); // Exclude the colon. XMP_StringMapPos uriPos = this->uriToPrefixMap.find ( uri ); if ( uriPos == this->uriToPrefixMap.end() ) { // The URI is not yet registered, make sure we use a unique prefix. XMP_VarString uniqPrefix ( suggPrefix ); int suffix = 0; char buffer [32]; // AUDIT: Plenty of room for the "_%d_" suffix. while ( true ) { if ( this->prefixToURIMap.find ( uniqPrefix ) == this->prefixToURIMap.end() ) break; ++suffix; snprintf ( buffer, sizeof(buffer), "_%d_:", suffix ); // AUDIT: Using sizeof for snprintf length is safe. uniqPrefix = suggPrefix; uniqPrefix.erase ( uniqPrefix.size()-1 ); // ! Remove the trailing ':'. uniqPrefix += buffer; } // Add the new namespace to both maps. XMP_StringPair newNS ( uri, uniqPrefix ); uriPos = this->uriToPrefixMap.insert ( this->uriToPrefixMap.end(), newNS ); newNS.first.swap ( newNS.second ); (void) this->prefixToURIMap.insert ( this->prefixToURIMap.end(), newNS ); } // Return the actual prefix and see if it matches the suggested prefix. if ( prefixPtr != 0 ) *prefixPtr = uriPos->second.c_str(); if ( prefixLen != 0 ) *prefixLen = (XMP_StringLen)uriPos->second.size(); prefixMatches = ( uriPos->second == suggPrefix ); return prefixMatches; } // XMP_NamespaceTable::Define
void XMPFiles_IO::AbsorbTemp() { XMP_FILESIO_START XMP_Assert ( this->fileRef != Host_IO::noFileRef ); XMPFiles_IO * temp = this->derivedTemp; if ( temp == 0 ) { XMP_Throw ( "XMPFiles_IO::AbsorbTemp, no temp to absorb", kXMPErr_InternalFailure ); } XMP_Assert ( temp->isTemp ); this->Close(); temp->Close(); Host_IO::SwapData ( this->filePath.c_str(), temp->filePath.c_str() ); this->DeleteTemp(); this->fileRef = Host_IO::Open ( this->filePath.c_str(), Host_IO::openReadWrite ); this->currLength = Host_IO::Length ( this->fileRef ); this->currOffset = 0; XMP_FILESIO_END1 ( kXMPErrSev_FileFatal ) } // XMPFiles_IO::AbsorbTemp
void XMP_HomeGrownLock::AcquireForRead() { XMP_AutoMutex autoMutex ( &this->queueMutex ); ++this->readersWaiting; // ! Does not need atomic increment, protected by queue mutex. while ( (this->beingWritten) || (this->writersWaiting > 0) ) { // Don't allow more readers if writers are waiting. WaitOnBasicQueue ( this->readerQueue, this->queueMutex ); } --this->readersWaiting; // ! Does not need atomic decrement, protected by queue mutex. XMP_Assert ( ! this->beingWritten ); ++this->lockCount; // ! Does not need atomic increment, protected by queue mutex. }
void XMP_HomeGrownLock::AcquireForWrite() { XMP_AutoMutex autoMutex ( &this->queueMutex ); ++this->writersWaiting; // ! Does not need atomic increment, protected by queue mutex. while ( this->lockCount > 0 ) { WaitOnBasicQueue ( this->writerQueue, this->queueMutex ); } --this->writersWaiting; // ! Does not need atomic decrement, protected by queue mutex. XMP_Assert ( (! this->beingWritten) && (this->lockCount == 0) ); ++this->lockCount; // ! Does not need atomic increment, protected by queue mutex. this->beingWritten = true; }
void XMP_HomeGrownLock::ReleaseFromWrite() { XMP_AutoMutex autoMutex ( &this->queueMutex ); XMP_Assert ( this->beingWritten && (this->lockCount == 1) ); --this->lockCount; // ! Does not need atomic decrement, protected by queue mutex. this->beingWritten = false; if ( this->writersWaiting > 0 ) { ReleaseOneBasicQueue ( this->writerQueue ); } else if ( this->readersWaiting > 0 ) { ReleaseAllBasicQueue ( this->readerQueue ); } }
void WXMPFiles_DecrementRefCount_1 ( XMPFilesRef xmpObjRef ) { WXMP_Result * wResult = &voidResult; // ! Needed to "fool" the EnterWrapper macro. XMP_ENTER_ObjWrite ( XMPFiles, "WXMPFiles_DecrementRefCount_1" ) XMP_Assert ( thiz->clientRefs > 0 ); --thiz->clientRefs; if ( thiz->clientRefs <= 0 ) { objLock.Release(); delete ( thiz ); } XMP_EXIT_NoThrow }
MOOV_Manager::BoxRef MOOV_Manager::GetNthChild ( BoxRef parentRef, size_t childIndex, BoxInfo * info ) const { XMP_Assert ( parentRef != 0 ); const BoxNode & parent = *((BoxNode*)parentRef); if ( info != 0 ) memset ( info, 0, sizeof(BoxInfo) ); if ( childIndex >= parent.children.size() ) return 0; const BoxNode & currNode = parent.children[childIndex]; this->FillBoxInfo ( currNode, info ); return &currNode; } // MOOV_Manager::GetNthChild
void WXMPMeta_DecrementRefCount_1 ( XMPMetaRef xmpRef ) { WXMP_Result * wResult = &void_wResult; // ! Needed to "fool" the EnterWrapper macro. XMP_ENTER_WRAPPER ( "WXMPMeta_DecrementRefCount_1" ) XMPMeta * thiz = (XMPMeta*)xmpRef; XMP_Assert ( thiz->clientRefs > 0 ); --thiz->clientRefs; if ( thiz->clientRefs <= 0 ) delete ( thiz ); XMP_EXIT_WRAPPER_NO_THROW }
static void RDF_NodeElementList ( XMP_Node * xmpParent, const XML_Node & xmlParent, bool isTopLevel ) { XMP_Assert ( isTopLevel ); XML_cNodePos currChild = xmlParent.content.begin(); // *** Change these loops to the indexed pattern. XML_cNodePos endChild = xmlParent.content.end(); for ( ; currChild != endChild; ++currChild ) { if ( (*currChild)->IsWhitespaceNode() ) continue; RDF_NodeElement ( xmpParent, **currChild, isTopLevel ); } } // RDF_NodeElementList
MOOV_Manager::BoxRef MOOV_Manager::AddChildBox ( BoxRef parentRef, XMP_Uns32 childType, const void* dataPtr, XMP_Uns32 size , const XMP_Uns8 * idUUID ) { BoxNode * parent = (BoxNode*)parentRef; XMP_Assert ( parent != 0 ); if( childType == ISOMedia::k_uuid && idUUID != 0) parent->children.push_back ( BoxNode ( 0, childType, 0, idUUID, 0 ) ); else parent->children.push_back ( BoxNode ( 0, childType, 0, 0 ) ); BoxNode * newNode = &parent->children.back(); this->SetBox ( newNode, dataPtr, size ); return newNode; } // MOOV_Manager::AddChildBox
static void CreatorAtom_MakeValid ( CR8R_CreatorAtom * creator_atomP ) { // If already valid, no conversion is needed. if ( creator_atomP->magicLu == AdobeCreatorAtom_Magic ) return; Flip4 ( &creator_atomP->magicLu ); Flip2 ( &creator_atomP->atom_vers_majorS ); Flip2 ( &creator_atomP->atom_vers_minorS ); Flip4 ( &creator_atomP->atom_sizeL ); Flip4 ( &creator_atomP->creator_codeLu ); Flip4 ( &creator_atomP->creator_eventLu ); XMP_Assert ( creator_atomP->magicLu == AdobeCreatorAtom_Magic ); }
static inline bool GetDecimalUns32 ( const char * str, XMP_Uns32 * bin ) { XMP_Assert ( bin != 0 ); if ( (str == 0) || (str[0] == 0) ) return false; *bin = 0; for ( size_t i = 0; str[i] != 0; ++i ) { char ch = str[i]; if ( (ch < '0') || (ch > '9') ) return false; *bin = (*bin * 10) + (ch - '0'); } return true; }
static std::string CharsToString ( const char* buffer, int maxBuffer ) { // convert possibly non-zero terminated char buffer to std::string std::string result; char bufferz[256]; XMP_Assert ( maxBuffer < 256 ); if ( maxBuffer >= 256 ) return result; memcpy ( bufferz, buffer, maxBuffer ); bufferz[maxBuffer] = 0; result = bufferz; return result; }
static void StripOutsideSpaces ( std::string * value ) { size_t length = value->size(); size_t first, last; for ( first = 0; ((first < length) && ((*value)[first] == ' ')); ++first ) {} if ( first == length ) { value->erase(); return; } XMP_Assert ( (first < length) && ((*value)[first] != ' ') ); for ( last = length-1; ((last > first) && ((*value)[last] == ' ')); --last ) {} if ( (first == 0) && (last == length-1) ) return; size_t newLen = last - first + 1; if ( newLen < length ) *value = value->substr ( first, newLen ); }
static void RDF_NodeElementAttrs ( XMP_Node * xmpParent, const XML_Node & xmlNode, bool isTopLevel ) { XMP_OptionBits exclusiveAttrs = 0; // Used to detect attributes that are mutually exclusive. XML_cNodePos currAttr = xmlNode.attrs.begin(); XML_cNodePos endAttr = xmlNode.attrs.end(); for ( ; currAttr != endAttr; ++currAttr ) { RDFTermKind attrTerm = GetRDFTermKind ( (*currAttr)->name ); switch ( attrTerm ) { case kRDFTerm_ID : case kRDFTerm_nodeID : case kRDFTerm_about : if ( exclusiveAttrs & kExclusiveAttrMask ) XMP_Throw ( "Mutally exclusive about, ID, nodeID attributes", kXMPErr_BadRDF ); exclusiveAttrs |= (1 << attrTerm); if ( isTopLevel && (attrTerm == kRDFTerm_about) ) { // This is the rdf:about attribute on a top level node. Set the XMP tree name if // it doesn't have a name yet. Make sure this name matches the XMP tree name. XMP_Assert ( xmpParent->parent == 0 ); // Must be the tree root node. if ( xmpParent->name.empty() ) { xmpParent->name = (*currAttr)->value; } else if ( ! (*currAttr)->value.empty() ) { if ( xmpParent->name != (*currAttr)->value ) XMP_Throw ( "Mismatched top level rdf:about values", kXMPErr_BadXMP ); } } break; case kRDFTerm_Other : AddChildNode ( xmpParent, **currAttr, (*currAttr)->value.c_str(), isTopLevel ); break; default : XMP_Throw ( "Invalid nodeElement attribute", kXMPErr_BadRDF ); break; } } } // RDF_NodeElementAttrs
static void ProjectLinkAtom_MakeValid ( Embed_ProjectLinkAtom * link_atomP ) { // If already valid, no conversion is needed. if ( link_atomP->magicLu == PR_PROJECT_LINK_MAGIC ) return; // do the header Flip4 ( &link_atomP->magicLu ); Flip4 ( &link_atomP->atom_sizeL ); Flip2 ( &link_atomP->atom_vers_apiS ); Flip2 ( &link_atomP->atom_vers_codeS ); // do the FSSpec data Flip2 ( &link_atomP->fullPath.vRefNum ); Flip4 ( &link_atomP->fullPath.parID ); XMP_Assert ( link_atomP->magicLu == PR_PROJECT_LINK_MAGIC ); }
/* class static */ void XMPUtils::AppendProperties ( const XMPMeta & source, XMPMeta * dest, XMP_OptionBits options ) { XMP_Assert ( dest != 0 ); // ! Enforced by wrapper. const bool doAll = ((options & kXMPUtil_DoAllProperties) != 0); const bool replaceOld = ((options & kXMPUtil_ReplaceOldValues) != 0); const bool deleteEmpty = ((options & kXMPUtil_DeleteEmptyValues) != 0); for ( size_t schemaNum = 0, schemaLim = source.tree.children.size(); schemaNum != schemaLim; ++schemaNum ) { const XMP_Node * sourceSchema = source.tree.children[schemaNum]; // Make sure we have a destination schema node. Remember if it is newly created. XMP_Node * destSchema = FindSchemaNode ( &dest->tree, sourceSchema->name.c_str(), kXMP_ExistingOnly ); const bool newDestSchema = (destSchema == 0); if ( newDestSchema ) { destSchema = new XMP_Node ( &dest->tree, sourceSchema->name, sourceSchema->value, kXMP_SchemaNode ); dest->tree.children.push_back ( destSchema ); } // Process the source schema's children. Do this backwards in case deleteEmpty is set. for ( long propNum = ((long)sourceSchema->children.size() - 1); propNum >= 0; --propNum ) { const XMP_Node * sourceProp = sourceSchema->children[propNum]; if ( doAll || IsExternalProperty ( sourceSchema->name, sourceProp->name ) ) { AppendSubtree ( sourceProp, destSchema, replaceOld, deleteEmpty ); // *** RemoveMultiValueInfo ( dest, sourceSchema->name.c_str(), sourceProp->name.c_str() ); } } if ( destSchema->children.empty() ) { if ( newDestSchema ) { delete ( destSchema ); dest->tree.children.pop_back(); } else if ( deleteEmpty ) { DeleteEmptySchema ( destSchema ); } } } } // AppendProperties
bool PutChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, long tagID, const char * inBuffer, UInt32 inBufferSize ) { UInt32 len; UInt64 pos; atag tag; // Make sure we're writting an even number of bytes. Required by the RIFF specification. XMP_Assert ( (inBufferSize & 1) == 0 ); try { bool found = FindChunk ( inOutRiffState, tagID, 0, 0, NULL, &len, &pos ); if ( found ) { if ( len == inBufferSize ) { LFA_Seek ( inFileRef, pos, SEEK_SET ); LFA_Write ( inFileRef, inBuffer, inBufferSize ); return true; } pos -= 8; tag.id = MakeUns32LE ( ckidPremierePadding ); LFA_Seek ( inFileRef, pos, SEEK_SET ); LFA_Write ( inFileRef, &tag, 4 ); if ( len > inBufferSize ) { pos += 8; AddTag ( inOutRiffState, ckidPremierePadding, len, pos, 0, 0, 0 ); } } } catch ( ... ) { // If a write fails, it throws, so we return false return false; } bool ok = MakeChunk ( inFileRef, inOutRiffState, riffType, (inBufferSize + 8) ); if ( ! ok ) return false; return WriteChunk ( inFileRef, tagID, inBuffer, inBufferSize ); }
bool GIF_CheckFormat ( XMP_FileFormat format, XMP_StringPtr filePath, XMP_IO* fileRef, XMPFiles * parent ) { IgnoreParam(format); IgnoreParam(filePath); IgnoreParam(parent); XMP_Assert ( format == kXMP_GIFFile ); if ( fileRef->Length() < GIF_89_Header_LEN ) return false; XMP_Uns8 buffer[ GIF_89_Header_LEN ]; fileRef->Rewind(); fileRef->Read( buffer, GIF_89_Header_LEN ); if ( !CheckBytes( buffer, GIF_89_Header_DATA, GIF_89_Header_LEN ) ) return false; return true; } // GIF_CheckFormat
TIFF_Manager::TIFF_Manager() : bigEndian(false), nativeEndian(false), GetUns16(0), GetUns32(0), GetFloat(0), GetDouble(0), PutUns16(0), PutUns32(0), PutFloat(0), PutDouble(0) { if ( sFirstCTor ) { sFirstCTor = false; #if XMP_DebugBuild for ( int ifd = 0; ifd < kTIFF_KnownIFDCount; ++ifd ) { // Make sure the known tag arrays are sorted. for ( const XMP_Uns16* idPtr = sKnownTags[ifd]; *idPtr != 0xFFFF; ++idPtr ) { XMP_Assert ( *idPtr < *(idPtr+1) ); } } #endif } } // TIFF_Manager::TIFF_Manager
bool XMP_NamespaceTable::GetPrefix ( XMP_StringPtr _uri, XMP_StringPtr * prefixPtr, XMP_StringLen * prefixLen ) const { XMP_AutoLock tableLock ( &this->lock, kXMP_ReadLock ); bool found = false; XMP_Assert ( (_uri != 0) && (*_uri != 0) ); XMP_VarString uri ( _uri ); XMP_cStringMapPos uriPos = this->uriToPrefixMap.find ( uri ); if ( uriPos != this->uriToPrefixMap.end() ) { if ( prefixPtr != 0 ) *prefixPtr = uriPos->second.c_str(); if ( prefixLen != 0 ) *prefixLen = (XMP_StringLen)uriPos->second.size(); found = true; } return found; } // XMP_NamespaceTable::GetPrefix
bool ASF_CheckFormat ( XMP_FileFormat format, XMP_StringPtr filePath, XMP_IO* fileRef, XMPFiles * parent ) { IgnoreParam(format); IgnoreParam(fileRef); IgnoreParam(parent); XMP_Assert ( format == kXMP_WMAVFile ); if ( fileRef->Length() < guidLen ) return false; GUID guid; fileRef->Rewind(); fileRef->Read ( &guid, guidLen ); if ( ! IsEqualGUID ( ASF_Header_Object, guid ) ) return false; return true; } // ASF_CheckFormat