|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Copyright 2002-2008 Adobe Systems Incorporated
|
|
Packit Service |
21b5d1 |
// All Rights Reserved.
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
|
|
Packit Service |
21b5d1 |
// of the Adobe license agreement accompanying it.
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Adobe patent application tracking #P435, entitled 'Unique markers to simplify embedding data of
|
|
Packit Service |
21b5d1 |
// one format in a file with a different format', inventors: Sean Parent, Greg Gilley.
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include "XMP_Environment.h" // ! This must be the first include!
|
|
Packit Service |
21b5d1 |
#include "XMPCore_Impl.hpp"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include <stdio.h>
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include "XMPMeta.hpp"
|
|
Packit Service |
21b5d1 |
#include "XMPIterator.hpp"
|
|
Packit Service |
21b5d1 |
#include "XMPUtils.hpp"
|
|
Packit Service |
21b5d1 |
#include "XMP_Version.h"
|
|
Packit Service |
21b5d1 |
#include "UnicodeInlines.incl_cpp"
|
|
Packit Service |
21b5d1 |
#include "UnicodeConversions.hpp"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#include <algorithm> // For sort and stable_sort.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
#include <iostream>
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
using namespace std;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if XMP_WinBuild
|
|
Packit Service |
21b5d1 |
#ifdef _MSC_VER
|
|
Packit Service |
21b5d1 |
#pragma warning ( disable : 4533 ) // initialization of '...' is skipped by 'goto ...'
|
|
Packit Service |
21b5d1 |
#pragma warning ( disable : 4702 ) // unreachable code
|
|
Packit Service |
21b5d1 |
#pragma warning ( disable : 4800 ) // forcing value to bool 'true' or 'false' (performance warning)
|
|
Packit Service |
21b5d1 |
#pragma warning ( disable : 4996 ) // '...' was declared deprecated
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *** Use the XMP_PropIsXyz (Schema, Simple, Struct, Array, ...) macros
|
|
Packit Service |
21b5d1 |
// *** Add debug codegen checks, e.g. that typical masking operations really work
|
|
Packit Service |
21b5d1 |
// *** Change all uses of strcmp and strncmp to XMP_LitMatch and XMP_LitNMatch
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Local Types and Constants
|
|
Packit Service |
21b5d1 |
// =========================
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Static Variables
|
|
Packit Service |
21b5d1 |
// ================
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_VarString * xdefaultName = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// These are embedded version strings.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const char * kXMPCore_EmbeddedVersion = kXMPCore_VersionMessage;
|
|
Packit Service |
21b5d1 |
const char * kXMPCore_EmbeddedCopyright = kXMPCoreName " " kXMP_CopyrightStr;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Local Utilities
|
|
Packit Service |
21b5d1 |
// ===============
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define IsHexDigit(ch) ( (('0' <= (ch)) && ((ch) <= '9')) || (('A' <= (ch)) && ((ch) <= 'F')) )
|
|
Packit Service |
21b5d1 |
#define HexDigitValue(ch) ( (((ch) - '0') < 10) ? ((ch) - '0') : ((ch) - 'A' + 10) )
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static const char * kTenSpaces = " ";
|
|
Packit Service |
21b5d1 |
#define OutProcPadding(pad) { size_t padLen = (pad); \
|
|
Packit Service |
21b5d1 |
for ( ; padLen >= 10; padLen -= 10 ) OutProcNChars ( kTenSpaces, 10 ); \
|
|
Packit Service |
21b5d1 |
for ( ; padLen > 0; padLen -= 1 ) OutProcNChars ( " ", 1 ); }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcNewline() { status = (*outProc) ( refCon, "\n", 1 ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcNChars(p,n) { status = (*outProc) ( refCon, (p), (n) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcLiteral(lit) { status = (*outProc) ( refCon, (lit), strlen(lit) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcString(str) { status = (*outProc) ( refCon, (str).c_str(), (str).size() ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcULong(num) { snprintf ( buffer, sizeof(buffer), "%lu", (num) ); /* AUDIT: Using sizeof for snprintf length is safe */ \
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, buffer, strlen(buffer) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
#ifdef __APPLE__
|
|
Packit Service |
21b5d1 |
#define OutProcHexInt(num) { snprintf ( buffer, sizeof(buffer), "%X", (num) ); /* AUDIT: Using sizeof for snprintf length is safe */ \
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, buffer, strlen(buffer) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
#else
|
|
Packit Service |
21b5d1 |
#define OutProcHexInt(num) { snprintf ( buffer, sizeof(buffer), "%lX", (num) ); /* AUDIT: Using sizeof for snprintf length is safe */ \
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, buffer, strlen(buffer) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define OutProcHexByte(num) { snprintf ( buffer, sizeof(buffer), "%.2X", (num) ); /* AUDIT: Using sizeof for snprintf length is safe */ \
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, buffer, strlen(buffer) ); if ( status != 0 ) goto EXIT; }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static const char * kIndent = " ";
|
|
Packit Service |
21b5d1 |
#define OutProcIndent(lev) { for ( size_t i = 0; i < (lev); ++i ) OutProcNChars ( kIndent, 3 ); }
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpClearString
|
|
Packit Service |
21b5d1 |
// ---------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static XMP_Status
|
|
Packit Service |
21b5d1 |
DumpClearString ( const XMP_VarString & value, XMP_TextOutputProc outProc, void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
char buffer [20];
|
|
Packit Service |
21b5d1 |
bool prevNormal;
|
|
Packit Service |
21b5d1 |
XMP_Status status = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringPtr spanStart, spanEnd;
|
|
Packit Service |
21b5d1 |
XMP_StringPtr valueEnd = &value[0] + value.size();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
spanStart = &value[0];
|
|
Packit Service |
21b5d1 |
while ( spanStart < valueEnd ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Output the next span of regular characters.
|
|
Packit Service |
21b5d1 |
for ( spanEnd = spanStart; spanEnd < valueEnd; ++spanEnd ) {
|
|
Packit Service |
21b5d1 |
if ( (unsigned char)(*spanEnd) > 0x7F ) break;
|
|
Packit Service |
21b5d1 |
if ( (*spanEnd < 0x20) && (*spanEnd != kTab) && (*spanEnd != kLF) ) break;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( spanStart != spanEnd ) status = (*outProc) ( refCon, spanStart, (spanEnd-spanStart) );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) break;
|
|
Packit Service |
21b5d1 |
spanStart = spanEnd;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Output the next span of irregular characters.
|
|
Packit Service |
21b5d1 |
prevNormal = true;
|
|
Packit Service |
21b5d1 |
for ( spanEnd = spanStart; spanEnd < valueEnd; ++spanEnd ) {
|
|
Packit Service |
21b5d1 |
if ( ((0x20 <= *spanEnd) && ((unsigned char)(*spanEnd) <= 0x7F)) || (*spanEnd == kTab) || (*spanEnd == kLF) ) break;
|
|
Packit Service |
21b5d1 |
char space = ' ';
|
|
Packit Service |
21b5d1 |
if ( prevNormal ) space = '<';
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, &space, 1 );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) break;
|
|
Packit Service |
21b5d1 |
OutProcHexByte ( *spanEnd );
|
|
Packit Service |
21b5d1 |
prevNormal = false;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( ! prevNormal ) {
|
|
Packit Service |
21b5d1 |
status = (*outProc) ( refCon, ">", 1 );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) return status;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
spanStart = spanEnd;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpClearString
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpStringMap
|
|
Packit Service |
21b5d1 |
// -------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static XMP_Status
|
|
Packit Service |
21b5d1 |
DumpStringMap ( const XMP_StringMap & map, XMP_StringPtr label, XMP_TextOutputProc outProc, void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Status status;
|
|
Packit Service |
21b5d1 |
XMP_cStringMapPos currPos;
|
|
Packit Service |
21b5d1 |
XMP_cStringMapPos endPos = map.end();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
size_t maxLen = 0;
|
|
Packit Service |
21b5d1 |
for ( currPos = map.begin(); currPos != endPos; ++currPos ) {
|
|
Packit Service |
21b5d1 |
size_t currLen = currPos->first.size();
|
|
Packit Service |
21b5d1 |
if ( currLen > maxLen ) maxLen = currLen;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( label );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( currPos = map.begin(); currPos != endPos; ++currPos ) {
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 2 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currPos->first, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcPadding ( maxLen - currPos->first.size() );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " => ", 4 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currPos->second, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpStringMap
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpNodeOptions
|
|
Packit Service |
21b5d1 |
// ---------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static XMP_Status
|
|
Packit Service |
21b5d1 |
DumpNodeOptions ( XMP_OptionBits options,
|
|
Packit Service |
21b5d1 |
XMP_TextOutputProc outProc,
|
|
Packit Service |
21b5d1 |
void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Status status;
|
|
Packit Service |
21b5d1 |
char buffer [32]; // Decimal of a 64 bit int is at most about 20 digits.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static const char * optNames[] = { " schema", // 0x8000_0000
|
|
Packit Service |
21b5d1 |
" ?30",
|
|
Packit Service |
21b5d1 |
" ?29",
|
|
Packit Service |
21b5d1 |
" -COMMAS-",
|
|
Packit Service |
21b5d1 |
" ?27", // 0x0800_0000
|
|
Packit Service |
21b5d1 |
" ?26",
|
|
Packit Service |
21b5d1 |
" ?25",
|
|
Packit Service |
21b5d1 |
" ?24",
|
|
Packit Service |
21b5d1 |
" ?23", // 0x0080_0000
|
|
Packit Service |
21b5d1 |
" isStale",
|
|
Packit Service |
21b5d1 |
" isDerived",
|
|
Packit Service |
21b5d1 |
" isStable",
|
|
Packit Service |
21b5d1 |
" ?19", // 0x0008_0000
|
|
Packit Service |
21b5d1 |
" isInternal",
|
|
Packit Service |
21b5d1 |
" hasAliases",
|
|
Packit Service |
21b5d1 |
" isAlias",
|
|
Packit Service |
21b5d1 |
" -AFTER-", // 0x0000_8000
|
|
Packit Service |
21b5d1 |
" -BEFORE-",
|
|
Packit Service |
21b5d1 |
" isCompact",
|
|
Packit Service |
21b5d1 |
" isLangAlt",
|
|
Packit Service |
21b5d1 |
" isAlt", // 0x0000_0800
|
|
Packit Service |
21b5d1 |
" isOrdered",
|
|
Packit Service |
21b5d1 |
" isArray",
|
|
Packit Service |
21b5d1 |
" isStruct",
|
|
Packit Service |
21b5d1 |
" hasType", // 0x0000_0080
|
|
Packit Service |
21b5d1 |
" hasLang",
|
|
Packit Service |
21b5d1 |
" isQual",
|
|
Packit Service |
21b5d1 |
" hasQual",
|
|
Packit Service |
21b5d1 |
" ?3", // 0x0000_0008
|
|
Packit Service |
21b5d1 |
" ?2",
|
|
Packit Service |
21b5d1 |
" URI",
|
|
Packit Service |
21b5d1 |
" ?0" };
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( options == 0 ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "(0x0)", 5 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "(0x", 3 );
|
|
Packit Service |
21b5d1 |
OutProcHexInt ( options );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " :", 2 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_OptionBits mask = 0x80000000;
|
|
Packit Service |
21b5d1 |
for ( int b = 0; b < 32; ++b ) {
|
|
Packit Service |
21b5d1 |
if ( options & mask ) OutProcLiteral ( optNames[b] );
|
|
Packit Service |
21b5d1 |
mask = mask >> 1;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
OutProcNChars ( ")", 1 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpNodeOptions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpPropertyTree
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *** Extract the validation code into a separate routine to call on exit in debug builds.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static XMP_Status
|
|
Packit Service |
21b5d1 |
DumpPropertyTree ( const XMP_Node * currNode,
|
|
Packit Service |
21b5d1 |
int indent,
|
|
Packit Service |
21b5d1 |
size_t itemIndex,
|
|
Packit Service |
21b5d1 |
XMP_TextOutputProc outProc,
|
|
Packit Service |
21b5d1 |
void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Status status;
|
|
Packit Service |
21b5d1 |
char buffer [32]; // Decimal of a 64 bit int is at most about 20 digits.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcIndent ( (size_t)indent );
|
|
Packit Service |
21b5d1 |
if ( itemIndex == 0 ) {
|
|
Packit Service |
21b5d1 |
if ( currNode->options & kXMP_PropIsQualifier ) OutProcNChars ( "? ", 2 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currNode->name, outProc, refCon );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "[", 1 );
|
|
Packit Service |
21b5d1 |
OutProcULong ( static_cast<unsigned long>(itemIndex) );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "]", 1 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! (currNode->options & kXMP_PropCompositeMask) ) {
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " = \"", 4 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currNode->value, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "\"", 1 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( currNode->options != 0 ) {
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 2 );
|
|
Packit Service |
21b5d1 |
status = DumpNodeOptions ( currNode->options, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( currNode->options & kXMP_PropHasLang ) {
|
|
Packit Service |
21b5d1 |
if ( currNode->qualifiers.empty() || (currNode->qualifiers[0]->name != "xml:lang") ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** bad lang flag **" );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
// *** Check rdf:type also.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! (currNode->options & kXMP_PropCompositeMask) ) {
|
|
Packit Service |
21b5d1 |
if ( ! currNode->children.empty() ) OutProcLiteral ( " ** bad children **" );
|
|
Packit Service |
21b5d1 |
} else if ( currNode->options & kXMP_PropValueIsArray ) {
|
|
Packit Service |
21b5d1 |
if ( currNode->options & kXMP_PropValueIsStruct ) OutProcLiteral ( " ** bad comp flags **" );
|
|
Packit Service |
21b5d1 |
} else if ( (currNode->options & kXMP_PropCompositeMask) != kXMP_PropValueIsStruct ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** bad comp flags **" );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if 0 // *** XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
if ( (currNode->_namePtr != currNode->name.c_str()) ||
|
|
Packit Service |
21b5d1 |
(currNode->_valuePtr != currNode->value.c_str()) ) OutProcLiteral ( " ** bad debug string **" );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t qualNum = 0, qualLim = currNode->qualifiers.size(); qualNum < qualLim; ++qualNum ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XMP_Node * currQual = currNode->qualifiers[qualNum];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( currQual->parent != currNode ) OutProcLiteral ( "** bad parent link => " );
|
|
Packit Service |
21b5d1 |
if ( currQual->name == kXMP_ArrayItemName ) OutProcLiteral ( "** bad qual name => " );
|
|
Packit Service |
21b5d1 |
if ( ! (currQual->options & kXMP_PropIsQualifier) ) OutProcLiteral ( "** bad qual flag => " );
|
|
Packit Service |
21b5d1 |
if ( currQual->name == "xml:lang" ) {
|
|
Packit Service |
21b5d1 |
if ( (qualNum != 0) || (! (currNode->options & kXMP_PropHasLang)) ) OutProcLiteral ( "** bad lang qual => " );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
status = DumpPropertyTree ( currQual, indent+2, 0, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t childNum = 0, childLim = currNode->children.size(); childNum < childLim; ++childNum ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XMP_Node * currChild = currNode->children[childNum];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( currChild->parent != currNode ) OutProcLiteral ( "** bad parent link => " );
|
|
Packit Service |
21b5d1 |
if ( currChild->options & kXMP_PropIsQualifier ) OutProcLiteral ( "** bad qual flag => " );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( currNode->options & kXMP_PropValueIsArray ) {
|
|
Packit Service |
21b5d1 |
itemIndex = childNum+1;
|
|
Packit Service |
21b5d1 |
if ( currChild->name != kXMP_ArrayItemName ) OutProcLiteral ( "** bad item name => " );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
itemIndex = 0;
|
|
Packit Service |
21b5d1 |
if ( currChild->name == kXMP_ArrayItemName ) OutProcLiteral ( "** bad field name => " );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
status = DumpPropertyTree ( currChild, indent+1, itemIndex, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpPropertyTree
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpXMLTree
|
|
Packit Service |
21b5d1 |
// -----------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if DumpXMLParseTree
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static inline void PutHexByte ( FILE * log, unsigned char ch )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\\x" );
|
|
Packit Service |
21b5d1 |
if ( ch < 0x10 ) {
|
|
Packit Service |
21b5d1 |
fprintf ( log, "%c", kHexDigits[ch] );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
fprintf ( log, "%c%c", kHexDigits[ch>>4], kHexDigits[ch&0xF] );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // PutHexByte
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static void PutClearString ( FILE * log, const std::string & str )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t i = 0; i != str.size(); ++i ) {
|
|
Packit Service |
21b5d1 |
unsigned char ch = str[i];
|
|
Packit Service |
21b5d1 |
if ( (0x20 <= ch) && (ch <= 0x7F) ) {
|
|
Packit Service |
21b5d1 |
fprintf ( log, "%c", ch );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
PutHexByte ( log, ch );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // PutClearString
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static void DumpXMLTree ( FILE * log, const XML_Node & node, int indent )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
size_t i;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if 0 // *** XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
if ( (node._namePtr != node.name.c_str()) ||
|
|
Packit Service |
21b5d1 |
(node._valuePtr != node.value.c_str()) ) fprintf ( log, "*** bad debug string ***\n" );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( i = 0; i != (size_t)indent; ++i ) fprintf ( log, " " );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
switch ( node.kind ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
case kRootNode :
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\nStart of XML tree dump\n\n" );
|
|
Packit Service |
21b5d1 |
if ( (indent != 0) || (! node.attrs.empty()) ||
|
|
Packit Service |
21b5d1 |
(! node.ns.empty()) || (! node.name.empty()) || (!node.value.empty()) ) fprintf ( log, " ** invalid root ** \n" );
|
|
Packit Service |
21b5d1 |
for ( i = 0; i < node.children.size(); ++i ) {
|
|
Packit Service |
21b5d1 |
XMP_Uns8 kind = node.children[i]->kind;
|
|
Packit Service |
21b5d1 |
if ( (kind == kRootNode) || (kind == kAttrNode) ) fprintf ( log, " ** invalid child ** \n" );
|
|
Packit Service |
21b5d1 |
DumpXMLTree ( log, *node.children[i], indent+1 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\nEnd of XML tree dump\n" );
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
case kElemNode :
|
|
Packit Service |
21b5d1 |
fprintf ( log, "Elem %s", node.name.c_str() );
|
|
Packit Service |
21b5d1 |
if ( indent == 0 ) fprintf ( log, " ** invalid elem ** " );
|
|
Packit Service |
21b5d1 |
if ( ! node.ns.empty() ) fprintf ( log, " @ %s", node.ns.c_str() );
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\n" );
|
|
Packit Service |
21b5d1 |
for ( i = 0; i < node.attrs.size(); ++i ) {
|
|
Packit Service |
21b5d1 |
XMP_Uns8 kind = node.attrs[i]->kind;
|
|
Packit Service |
21b5d1 |
if ( kind != kAttrNode ) fprintf ( log, " ** invalid attr ** \n" );
|
|
Packit Service |
21b5d1 |
DumpXMLTree ( log, *node.attrs[i], indent+2 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
for ( i = 0; i < node.children.size(); ++i ) {
|
|
Packit Service |
21b5d1 |
XMP_Uns8 kind = node.children[i]->kind;
|
|
Packit Service |
21b5d1 |
if ( (kind == kRootNode) || (kind == kAttrNode) ) fprintf ( log, " ** invalid child ** \n" );
|
|
Packit Service |
21b5d1 |
DumpXMLTree ( log, *node.children[i], indent+1 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
case kAttrNode :
|
|
Packit Service |
21b5d1 |
fprintf ( log, "Attr %s", node.name.c_str() );
|
|
Packit Service |
21b5d1 |
if ( (indent == 0) || node.name.empty() || (! node.attrs.empty()) || (! node.children.empty()) ) fprintf ( log, " ** invalid attr ** " );
|
|
Packit Service |
21b5d1 |
fprintf ( log, " = \"" );
|
|
Packit Service |
21b5d1 |
PutClearString ( log, node.value );
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\"" );
|
|
Packit Service |
21b5d1 |
if ( ! node.ns.empty() ) fprintf ( log, " @ %s", node.ns.c_str() );
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\n" );
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
case kCDataNode :
|
|
Packit Service |
21b5d1 |
if ( (indent == 0) || (! node.ns.empty()) || (! node.name.empty()) ||
|
|
Packit Service |
21b5d1 |
(! node.attrs.empty()) || (! node.children.empty()) ) fprintf ( log, " ** invalid cdata ** \n" );
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\"" );
|
|
Packit Service |
21b5d1 |
PutClearString ( log, node.value );
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\"\n" );
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
case kPINode :
|
|
Packit Service |
21b5d1 |
fprintf ( log, "PI %s", node.name.c_str() );
|
|
Packit Service |
21b5d1 |
if ( (indent == 0) || node.name.empty() || (! node.children.empty()) ) fprintf ( log, " ** invalid pi ** \n" );
|
|
Packit Service |
21b5d1 |
if ( ! node.value.empty() ) {
|
|
Packit Service |
21b5d1 |
fprintf ( log, "
|
|
Packit Service |
21b5d1 |
PutClearString ( log, node.value );
|
|
Packit Service |
21b5d1 |
fprintf ( log, " ?>" );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
fprintf ( log, "\n" );
|
|
Packit Service |
21b5d1 |
break;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpXMLTree
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#endif // DumpXMLParseTree
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// CompareNodeNames
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Comparison routine for sorting XMP nodes by name. The name "xml:lang" is less than anything else,
|
|
Packit Service |
21b5d1 |
// and "rdf:type" is less than anything except "xml:lang". This preserves special rules for qualifiers.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static bool
|
|
Packit Service |
21b5d1 |
CompareNodeNames ( XMP_Node * left, XMP_Node * right )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( left->name == "xml:lang" ) return true;
|
|
Packit Service |
21b5d1 |
if ( right->name == "xml:lang" ) return false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( left->name == "rdf:type" ) return true;
|
|
Packit Service |
21b5d1 |
if ( right->name == "rdf:type" ) return false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return ( left->name < right->name );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // CompareNodeNames
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// CompareNodeValues
|
|
Packit Service |
21b5d1 |
// -----------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Comparison routine for sorting XMP nodes by value.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static bool
|
|
Packit Service |
21b5d1 |
CompareNodeValues ( XMP_Node * left, XMP_Node * right )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( XMP_PropIsSimple ( left->options ) && XMP_PropIsSimple ( right->options ) ) {
|
|
Packit Service |
21b5d1 |
return ( left->value < right->value );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_OptionBits leftForm = left->options & kXMP_PropCompositeMask;
|
|
Packit Service |
21b5d1 |
XMP_OptionBits rightForm = right->options & kXMP_PropCompositeMask;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return ( leftForm < rightForm );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // CompareNodeValues
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// CompareNodeLangs
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Comparison routine for sorting XMP nodes by xml:lang qualifier. An "x-default" value is less than
|
|
Packit Service |
21b5d1 |
// any other language.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static bool
|
|
Packit Service |
21b5d1 |
CompareNodeLangs ( XMP_Node * left, XMP_Node * right )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( left->qualifiers.empty() || (left->qualifiers[0]->name != "xml:lang") ) return false;
|
|
Packit Service |
21b5d1 |
if ( right->qualifiers.empty() || (right->qualifiers[0]->name != "xml:lang") ) return false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( left->qualifiers[0]->value == "x-default" ) return true;
|
|
Packit Service |
21b5d1 |
if ( right->qualifiers[0]->value == "x-default" ) return false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return ( left->qualifiers[0]->value < right->qualifiers[0]->value );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // CompareNodeLangs
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// SortWithinOffspring
|
|
Packit Service |
21b5d1 |
// -------------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Sort one level down, within the elements of a node vector. This sorts the qualifiers of each
|
|
Packit Service |
21b5d1 |
// node. If the node is a struct it sorts the fields by names. If the node is an unordered array it
|
|
Packit Service |
21b5d1 |
// sorts the elements by value. If the node is an AltText array it sorts the elements by language.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
static void
|
|
Packit Service |
21b5d1 |
SortWithinOffspring ( XMP_NodeOffspring & nodeVec )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t i = 0, limit = nodeVec.size(); i < limit; ++i ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Node * currPos = nodeVec[i];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! currPos->qualifiers.empty() ) {
|
|
Packit Service |
21b5d1 |
sort ( currPos->qualifiers.begin(), currPos->qualifiers.end(), CompareNodeNames );
|
|
Packit Service |
21b5d1 |
SortWithinOffspring ( currPos->qualifiers );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! currPos->children.empty() ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( XMP_PropIsStruct ( currPos->options ) || XMP_NodeIsSchema ( currPos->options ) ) {
|
|
Packit Service |
21b5d1 |
sort ( currPos->children.begin(), currPos->children.end(), CompareNodeNames );
|
|
Packit Service |
21b5d1 |
} else if ( XMP_PropIsArray ( currPos->options ) ) {
|
|
Packit Service |
21b5d1 |
if ( XMP_ArrayIsUnordered ( currPos->options ) ) {
|
|
Packit Service |
21b5d1 |
stable_sort ( currPos->children.begin(), currPos->children.end(), CompareNodeValues );
|
|
Packit Service |
21b5d1 |
} else if ( XMP_ArrayIsAltText ( currPos->options ) ) {
|
|
Packit Service |
21b5d1 |
sort ( currPos->children.begin(), currPos->children.end(), CompareNodeLangs );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
SortWithinOffspring ( currPos->children );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // SortWithinOffspring
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Constructors
|
|
Packit Service |
21b5d1 |
// ============
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMPMeta::XMPMeta() : clientRefs(0), prevTkVer(0), tree(XMP_Node(0,"",0)), xmlParser(0)
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
// Nothing more to do, clientRefs is incremented in wrapper.
|
|
Packit Service |
21b5d1 |
#if XMP_TraceCTorDTor
|
|
Packit Service |
21b5d1 |
printf ( "Default construct XMPMeta @ %.8X\n", this );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
} // XMPMeta
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMPMeta::~XMPMeta() RELEASE_NO_THROW
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
#if XMP_TraceCTorDTor
|
|
Packit Service |
21b5d1 |
printf ( "Destruct XMPMeta @ %.8X\n", this );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( this->clientRefs <= 0 );
|
|
Packit Service |
21b5d1 |
if ( xmlParser != 0 ) delete ( xmlParser );
|
|
Packit Service |
21b5d1 |
xmlParser = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // ~XMPMeta
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Class Static Functions
|
|
Packit Service |
21b5d1 |
// ======================
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetVersionInfo
|
|
Packit Service |
21b5d1 |
// --------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::GetVersionInfo ( XMP_VersionInfo * info )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
memset ( info, 0, sizeof(*info) ); // AUDIT: Safe, using sizeof the destination.
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(*info) == sizeof(XMP_VersionInfo) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
info->major = XMP_API_VERSION_MAJOR;
|
|
Packit Service |
21b5d1 |
info->minor = XMP_API_VERSION_MINOR;
|
|
Packit Service |
21b5d1 |
info->micro = XMP_API_VERSION_MICRO;
|
|
Packit Service |
21b5d1 |
info->isDebug = kXMPCore_DebugFlag;
|
|
Packit Service |
21b5d1 |
info->flags = 0; // ! None defined yet.
|
|
Packit Service |
21b5d1 |
info->message = kXMPCore_VersionMessage;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetVersionInfo
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Initialize
|
|
Packit Service |
21b5d1 |
// ----------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ bool
|
|
Packit Service |
21b5d1 |
XMPMeta::Initialize()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
// Allocate and initialize static objects.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
++sXMP_InitCount;
|
|
Packit Service |
21b5d1 |
if ( sXMP_InitCount > 1 ) return true;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if TraceXMPCalls
|
|
Packit Service |
21b5d1 |
// xmpOut = fopen ( "xmp.out", "w" ); // Coordinate with client glue in WXMP_Common.hpp
|
|
Packit Service |
21b5d1 |
fprintf ( xmpOut, "XMP initializing\n" ); fflush ( xmpOut );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
sExceptionMessage = new XMP_VarString();
|
|
Packit Service |
21b5d1 |
XMP_InitMutex ( &sXMPCoreLock );
|
|
Packit Service |
21b5d1 |
sOutputNS = new XMP_VarString;
|
|
Packit Service |
21b5d1 |
sOutputStr = new XMP_VarString;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
xdefaultName = new XMP_VarString ( "x-default" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
sNamespaceURIToPrefixMap = new XMP_StringMap;
|
|
Packit Service |
21b5d1 |
sNamespacePrefixToURIMap = new XMP_StringMap;
|
|
Packit Service |
21b5d1 |
sRegisteredAliasMap = new XMP_AliasMap;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
InitializeUnicodeConversions();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Register standard namespaces and aliases.
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XML, "xml" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_RDF, "rdf" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_DC, "dc" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP, "xmp" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDF, "pdf" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_Photoshop, "photoshop" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PSAlbum, "album" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_EXIF, "exif" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_EXIF_Aux, "aux" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_TIFF, "tiff" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PNG, "png" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_JPEG, "jpeg" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_JP2K, "jp2k" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_CameraRaw, "crs" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_ASF, "asf" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_WAV, "wav" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_AdobeStockPhoto, "bmsp" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_CreatorAtom, "creatorAtom" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Rights, "xmpRights" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_MM, "xmpMM" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_BJ, "xmpBJ" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Note, "xmpNote" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_DM, "xmpDM" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Text, "xmpT" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_PagedFile, "xmpTPg" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Graphics, "xmpG" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Image, "xmpGImg" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Font, "stFnt" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_Dimensions, "stDim" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_ResourceEvent, "stEvt" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_ResourceRef, "stRef" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_ST_Version, "stVer" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_ST_Job, "stJob" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_ManifestItem, "stMfs" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_XMP_IdentifierQual, "xmpidq" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_IPTCCore, "Iptc4xmpCore" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_DICOM, "DICOM" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_Schema, "pdfaSchema" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_Property, "pdfaProperty" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_Type, "pdfaType" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_Field, "pdfaField" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_ID, "pdfaid" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFA_Extension, "pdfaExtension" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFX, "pdfx" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( kXMP_NS_PDFX_ID, "pdfxid" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( "adobe:ns:meta/", "x" );
|
|
Packit Service |
21b5d1 |
RegisterNamespace ( "http://ns.adobe.com/iX/1.0/", "iX" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// 06-Oct-07, ahu: Do not use aliases. They result in unexpected behaviour.
|
|
Packit Service |
21b5d1 |
// XMPMeta::RegisterStandardAliases ( "" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Initialize the other core classes.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! XMPIterator::Initialize() ) XMP_Throw ( "Failure from XMPIterator::Initialize", kXMPErr_InternalFailure );
|
|
Packit Service |
21b5d1 |
if ( ! XMPUtils::Initialize() ) XMP_Throw ( "Failure from XMPUtils::Initialize", kXMPErr_InternalFailure );
|
|
Packit Service |
21b5d1 |
// Do miscelaneous semantic checks of types and arithmetic.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Int8) == 1 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Int16) == 2 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Int32) == 4 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Int64) == 8 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Uns8) == 1 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Uns16) == 2 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Uns32) == 4 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_Uns64) == 8 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sizeof(XMP_OptionBits) == 4 ); // Check that option masking work on all 32 bits.
|
|
Packit Service |
21b5d1 |
XMP_OptionBits flag = ~0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( flag == (XMP_OptionBits)(-1L) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (flag ^ kXMP_PropHasLang) == 0xFFFFFFBFUL );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (flag & ~kXMP_PropHasLang) == 0xFFFFFFBFUL );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_OptionBits opt1 = 0; // Check the general option bit macros.
|
|
Packit Service |
21b5d1 |
XMP_OptionBits opt2 = flag;
|
|
Packit Service |
21b5d1 |
XMP_SetOption ( opt1, kXMP_PropValueIsArray );
|
|
Packit Service |
21b5d1 |
XMP_ClearOption ( opt2, kXMP_PropValueIsArray );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( opt1 == ~opt2 );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_TestOption ( opt1, kXMP_PropValueIsArray ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_TestOption ( opt2, kXMP_PropValueIsArray ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropIsSimple ( ~kXMP_PropCompositeMask ) ); // Check the special option bit macros.
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsSimple ( kXMP_PropValueIsStruct ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsSimple ( kXMP_PropValueIsArray ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropIsStruct ( kXMP_PropValueIsStruct ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropIsArray ( kXMP_PropValueIsArray ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsStruct ( ~kXMP_PropValueIsStruct ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsArray ( ~kXMP_PropValueIsArray ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_ArrayIsUnordered ( ~kXMP_PropArrayIsOrdered ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_ArrayIsOrdered ( kXMP_PropArrayIsOrdered ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_ArrayIsAlternate ( kXMP_PropArrayIsAlternate ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_ArrayIsAltText ( kXMP_PropArrayIsAltText ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_ArrayIsUnordered ( kXMP_PropArrayIsOrdered ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_ArrayIsOrdered ( ~kXMP_PropArrayIsOrdered ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_ArrayIsAlternate ( ~kXMP_PropArrayIsAlternate ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_ArrayIsAltText ( ~kXMP_PropArrayIsAltText ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropHasQualifiers ( kXMP_PropHasQualifiers ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropIsQualifier ( kXMP_PropIsQualifier ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropHasLang ( kXMP_PropHasLang ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropHasQualifiers ( ~kXMP_PropHasQualifiers ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsQualifier ( ~kXMP_PropIsQualifier ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropHasLang ( ~kXMP_PropHasLang ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_NodeIsSchema ( kXMP_SchemaNode ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( XMP_PropIsAlias ( kXMP_PropIsAlias ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_NodeIsSchema ( ~kXMP_SchemaNode ) );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( ! XMP_PropIsAlias ( ~kXMP_PropIsAlias ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if 0 // Generally off, enable to hand check generated code.
|
|
Packit Service |
21b5d1 |
extern XMP_OptionBits opt3, opt4;
|
|
Packit Service |
21b5d1 |
if ( XMP_TestOption ( opt3, kXMP_PropValueIsArray ) ) opt4 = opt3;
|
|
Packit Service |
21b5d1 |
if ( ! XMP_TestOption ( opt3, kXMP_PropValueIsStruct ) ) opt4 = opt3;
|
|
Packit Service |
21b5d1 |
static bool ok1 = XMP_TestOption ( opt4, kXMP_PropValueIsArray );
|
|
Packit Service |
21b5d1 |
static bool ok2 = ! XMP_TestOption ( opt4, kXMP_PropValueIsStruct );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Make sure the embedded info strings are referenced and kept.
|
|
Packit Service |
21b5d1 |
if ( (kXMPCore_EmbeddedVersion[0] == 0) || (kXMPCore_EmbeddedCopyright[0] == 0) ) return false;
|
|
Packit Service |
21b5d1 |
return true;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Initialize
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Terminate
|
|
Packit Service |
21b5d1 |
// ---------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#define EliminateGlobal(g) delete ( g ); g = 0
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::Terminate() RELEASE_NO_THROW
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
--sXMP_InitCount;
|
|
Packit Service |
21b5d1 |
if ( sXMP_InitCount > 0 ) return;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if TraceXMPCalls
|
|
Packit Service |
21b5d1 |
fprintf ( xmpOut, "XMP terminating\n" ); fflush ( xmpOut );
|
|
Packit Service |
21b5d1 |
// fclose ( xmpOut ); // Coordinate with fopen in XMPMeta::Initialize.
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMPIterator::Terminate();
|
|
Packit Service |
21b5d1 |
XMPUtils::Terminate();
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sNamespaceURIToPrefixMap );
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sNamespacePrefixToURIMap );
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sRegisteredAliasMap );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( xdefaultName );
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sOutputNS );
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sOutputStr );
|
|
Packit Service |
21b5d1 |
EliminateGlobal ( sExceptionMessage );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_TermMutex ( sXMPCoreLock );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Terminate
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Unlock
|
|
Packit Service |
21b5d1 |
// ------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::Unlock ( XMP_OptionBits options )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
UNUSED(options);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if TraceXMPLocking
|
|
Packit Service |
21b5d1 |
fprintf ( xmpOut, " Unlocking XMP toolkit, count = %d\n", sLockCount ); fflush ( xmpOut );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
--sLockCount;
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sLockCount == 0 );
|
|
Packit Service |
21b5d1 |
XMP_ExitCriticalRegion ( sXMPCoreLock );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Unlock
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// UnlockObject
|
|
Packit Service |
21b5d1 |
// ------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::UnlockObject ( XMP_OptionBits options ) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
UNUSED(options);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMPMeta::Unlock ( 0 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // UnlockObject
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpNamespaces
|
|
Packit Service |
21b5d1 |
// --------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Dump the prefix to URI map (easier to read) and verify that both are consistent and legit.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *** Should put checks in a separate routine for regular calling in debug builds.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ XMP_Status
|
|
Packit Service |
21b5d1 |
XMPMeta::DumpNamespaces ( XMP_TextOutputProc outProc,
|
|
Packit Service |
21b5d1 |
void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( outProc != 0 ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Status status = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos p2uEnd = sNamespacePrefixToURIMap->end(); // ! Move up to avoid gcc complaints.
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos u2pEnd = sNamespaceURIToPrefixMap->end();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
status = DumpStringMap ( *sNamespacePrefixToURIMap, "Dumping namespace prefix to URI map", outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( sNamespacePrefixToURIMap->size() != sNamespaceURIToPrefixMap->size() ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "** bad namespace map sizes **" );
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Fatal namespace map problem", kXMPErr_InternalFailure );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( XMP_StringMapPos nsLeft = sNamespacePrefixToURIMap->begin(); nsLeft != p2uEnd; ++nsLeft ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos nsOther = sNamespaceURIToPrefixMap->find ( nsLeft->second );
|
|
Packit Service |
21b5d1 |
if ( (nsOther == u2pEnd) || (nsLeft != sNamespacePrefixToURIMap->find ( nsOther->second )) ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** bad namespace URI ** " );
|
|
Packit Service |
21b5d1 |
DumpClearString ( nsLeft->second, outProc, refCon );
|
|
Packit Service |
21b5d1 |
goto FAILURE;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( XMP_StringMapPos nsRight = nsLeft; nsRight != p2uEnd; ++nsRight ) {
|
|
Packit Service |
21b5d1 |
if ( nsRight == nsLeft ) continue; // ! Can't start at nsLeft+1, no operator+!
|
|
Packit Service |
21b5d1 |
if ( nsLeft->second == nsRight->second ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** duplicate namespace URI ** " );
|
|
Packit Service |
21b5d1 |
DumpClearString ( nsLeft->second, outProc, refCon );
|
|
Packit Service |
21b5d1 |
goto FAILURE;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( XMP_StringMapPos nsLeft = sNamespaceURIToPrefixMap->begin(); nsLeft != u2pEnd; ++nsLeft ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos nsOther = sNamespacePrefixToURIMap->find ( nsLeft->second );
|
|
Packit Service |
21b5d1 |
if ( (nsOther == p2uEnd) || (nsLeft != sNamespaceURIToPrefixMap->find ( nsOther->second )) ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** bad namespace prefix ** " );
|
|
Packit Service |
21b5d1 |
DumpClearString ( nsLeft->second, outProc, refCon );
|
|
Packit Service |
21b5d1 |
goto FAILURE;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( XMP_StringMapPos nsRight = nsLeft; nsRight != u2pEnd; ++nsRight ) {
|
|
Packit Service |
21b5d1 |
if ( nsRight == nsLeft ) continue; // ! Can't start at nsLeft+1, no operator+!
|
|
Packit Service |
21b5d1 |
if ( nsLeft->second == nsRight->second ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( " ** duplicate namespace prefix ** " );
|
|
Packit Service |
21b5d1 |
DumpClearString ( nsLeft->second, outProc, refCon );
|
|
Packit Service |
21b5d1 |
goto FAILURE;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
FAILURE:
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
(void) DumpStringMap ( *sNamespaceURIToPrefixMap, "Dumping namespace URI to prefix map", outProc, refCon );
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Fatal namespace map problem", kXMPErr_InternalFailure );
|
|
Packit Service |
21b5d1 |
return 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpNamespaces
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpAliases
|
|
Packit Service |
21b5d1 |
// -----------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ XMP_Status
|
|
Packit Service |
21b5d1 |
XMPMeta::DumpAliases ( XMP_TextOutputProc outProc,
|
|
Packit Service |
21b5d1 |
void * refCon )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( outProc != 0 ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Status status = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( sRegisteredAliasMap != 0 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_cAliasMapPos aliasPos;
|
|
Packit Service |
21b5d1 |
XMP_cAliasMapPos aliasEnd = sRegisteredAliasMap->end();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
size_t maxLen = 0;
|
|
Packit Service |
21b5d1 |
for ( aliasPos = sRegisteredAliasMap->begin(); aliasPos != aliasEnd; ++aliasPos ) {
|
|
Packit Service |
21b5d1 |
size_t currLen = aliasPos->first.size();
|
|
Packit Service |
21b5d1 |
if ( currLen > maxLen ) maxLen = currLen;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "Dumping alias name to actual path map" );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( aliasPos = sRegisteredAliasMap->begin(); aliasPos != aliasEnd; ++aliasPos ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 3 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( aliasPos->first, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcPadding ( maxLen - aliasPos->first.size() );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " => ", 4 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
size_t actualPathSize = aliasPos->second.size();
|
|
Packit Service |
21b5d1 |
for ( size_t stepNum = 1; stepNum < actualPathSize; ++stepNum ) OutProcString ( aliasPos->second[stepNum].step );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_OptionBits arrayForm = aliasPos->second[1].options & kXMP_PropArrayFormMask;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( arrayForm == 0 ) {
|
|
Packit Service |
21b5d1 |
if ( actualPathSize != 2 ) OutProcLiteral ( " ** bad actual path **" );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 2 );
|
|
Packit Service |
21b5d1 |
DumpNodeOptions ( arrayForm, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( ! (arrayForm & kXMP_PropValueIsArray) ) OutProcLiteral ( " ** bad array form **" );
|
|
Packit Service |
21b5d1 |
if ( actualPathSize != 3 ) OutProcLiteral ( " ** bad actual path **" );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( aliasPos->second[0].options != kXMP_SchemaNode ) OutProcLiteral ( " ** bad schema form **" );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpAliases
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetGlobalOptions
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ XMP_OptionBits
|
|
Packit Service |
21b5d1 |
XMPMeta::GetGlobalOptions()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_OptionBits options = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return options;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetGlobalOptions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// SetGlobalOptions
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::SetGlobalOptions ( XMP_OptionBits /*options*/ )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Unimplemented method XMPMeta::SetGlobalOptions", kXMPErr_Unimplemented );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // SetGlobalOptions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// RegisterNamespace
|
|
Packit Service |
21b5d1 |
// -----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterNamespace ( XMP_StringPtr namespaceURI,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr prefix )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if ( (*namespaceURI == 0) || (*prefix == 0) ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Empty namespace URI or prefix", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_VarString nsURI ( namespaceURI );
|
|
Packit Service |
21b5d1 |
XMP_VarString prfix ( prefix );
|
|
Packit Service |
21b5d1 |
if ( prfix[prfix.size()-1] != ':' ) prfix += ':';
|
|
Packit Service |
21b5d1 |
VerifySimpleXMLName ( prefix, prefix+prfix.size()-1 ); // Exclude the colon.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Set the new namespace in both maps.
|
|
Packit Service |
21b5d1 |
(*sNamespaceURIToPrefixMap)[nsURI] = prfix;
|
|
Packit Service |
21b5d1 |
(*sNamespacePrefixToURIMap)[prfix] = nsURI;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // RegisterNamespace
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetNamespacePrefix
|
|
Packit Service |
21b5d1 |
// ------------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ bool
|
|
Packit Service |
21b5d1 |
XMPMeta::GetNamespacePrefix ( XMP_StringPtr namespaceURI,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr * namespacePrefix,
|
|
Packit Service |
21b5d1 |
XMP_StringLen * prefixSize )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
bool found = false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( *namespaceURI != 0 ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (namespacePrefix != 0) && (prefixSize != 0) ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_VarString nsURI ( namespaceURI );
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos uriPos = sNamespaceURIToPrefixMap->find ( nsURI );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( uriPos != sNamespaceURIToPrefixMap->end() ) {
|
|
Packit Service |
21b5d1 |
*namespacePrefix = uriPos->second.c_str();
|
|
Packit Service |
21b5d1 |
*prefixSize = uriPos->second.size();
|
|
Packit Service |
21b5d1 |
found = true;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return found;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetNamespacePrefix
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetNamespaceURI
|
|
Packit Service |
21b5d1 |
// ---------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ bool
|
|
Packit Service |
21b5d1 |
XMPMeta::GetNamespaceURI ( XMP_StringPtr namespacePrefix,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr * namespaceURI,
|
|
Packit Service |
21b5d1 |
XMP_StringLen * uriSize )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
bool found = false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( *namespacePrefix != 0 ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (namespacePrefix != 0) && (namespaceURI != 0) ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_VarString nsPrefix ( namespacePrefix );
|
|
Packit Service |
21b5d1 |
if ( nsPrefix[nsPrefix.size()-1] != ':' ) nsPrefix += ':';
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos prefixPos = sNamespacePrefixToURIMap->find ( nsPrefix );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( prefixPos != sNamespacePrefixToURIMap->end() ) {
|
|
Packit Service |
21b5d1 |
*namespaceURI = prefixPos->second.c_str();
|
|
Packit Service |
21b5d1 |
*uriSize = prefixPos->second.size();
|
|
Packit Service |
21b5d1 |
found = true;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return found;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetNamespaceURI
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DeleteNamespace
|
|
Packit Service |
21b5d1 |
// ---------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// *** Don't allow standard namespaces to be deleted.
|
|
Packit Service |
21b5d1 |
// *** We would be better off not having this. Instead, have local namespaces from parsing be
|
|
Packit Service |
21b5d1 |
// *** restricted to the object that introduced them.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::DeleteNamespace ( XMP_StringPtr namespaceURI )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos uriPos = sNamespaceURIToPrefixMap->find ( namespaceURI );
|
|
Packit Service |
21b5d1 |
if ( uriPos == sNamespaceURIToPrefixMap->end() ) return;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_StringMapPos prefixPos = sNamespacePrefixToURIMap->find ( uriPos->second );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( prefixPos != sNamespacePrefixToURIMap->end() );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
sNamespaceURIToPrefixMap->erase ( uriPos );
|
|
Packit Service |
21b5d1 |
sNamespacePrefixToURIMap->erase ( prefixPos );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DeleteNamespace
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// RegisterAlias
|
|
Packit Service |
21b5d1 |
// -------------
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Allow 3 kinds of alias:
|
|
Packit Service |
21b5d1 |
// TopProp => TopProp
|
|
Packit Service |
21b5d1 |
// TopProp => TopArray[1]
|
|
Packit Service |
21b5d1 |
// TopProp => TopArray[@xml:lang='x-default']
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// A new alias can be made to something that is already aliased, as long as the net result is one of
|
|
Packit Service |
21b5d1 |
// the legitimate forms. The new alias can already have aliases to it, also as long as result of
|
|
Packit Service |
21b5d1 |
// adjusting all of the exiting aliases leaves them legal.
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// ! The caller assumes all risk that new aliases do not invalidate existing XMPMeta objects. Any
|
|
Packit Service |
21b5d1 |
// ! conflicts will result in later references throwing bad XPath exceptions.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( XMP_StringPtr aliasNS,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr aliasProp,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr actualNS,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr actualProp,
|
|
Packit Service |
21b5d1 |
XMP_OptionBits arrayForm )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPath expAlias, expActual;
|
|
Packit Service |
21b5d1 |
XMP_AliasMapPos mapPos;
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPath * regActual = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (aliasNS != 0) && (aliasProp != 0) && (actualNS != 0) && (actualProp != 0) ); // Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Expand the alias and actual names, make sure they are one of the basic 3 forms. When counting
|
|
Packit Service |
21b5d1 |
// the expanded XPath size remember that the schema URI is the first component. We don't have to
|
|
Packit Service |
21b5d1 |
// compare the schema URIs though, the (unique) prefix is part of the top property name.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
ExpandXPath ( aliasNS, aliasProp, &expAlias );
|
|
Packit Service |
21b5d1 |
ExpandXPath ( actualNS, actualProp, &expActual );
|
|
Packit Service |
21b5d1 |
if ( (expAlias.size() != 2) || (expActual.size() != 2) ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Alias and actual property names must be simple", kXMPErr_BadXPath );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
arrayForm = VerifySetOptions ( arrayForm, 0 );
|
|
Packit Service |
21b5d1 |
if ( arrayForm != 0 ) {
|
|
Packit Service |
21b5d1 |
if ( (arrayForm & ~kXMP_PropArrayFormMask) != 0 ) XMP_Throw ( "Only array form flags are allowed", kXMPErr_BadOptions );
|
|
Packit Service |
21b5d1 |
expActual[1].options |= arrayForm; // Set the array form for the top level step.
|
|
Packit Service |
21b5d1 |
if ( ! (arrayForm & kXMP_PropArrayIsAltText) ) {
|
|
Packit Service |
21b5d1 |
expActual.push_back ( XPathStepInfo ( "[1]", kXMP_ArrayIndexStep ) );
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
expActual.push_back ( XPathStepInfo ( "[?xml:lang=\"x-default\"]", kXMP_QualSelectorStep ) );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// See if there are any conflicts with existing aliases. A couple of the checks are easy. If the
|
|
Packit Service |
21b5d1 |
// alias is already aliased it is only OK to reregister an identical alias. If the actual is
|
|
Packit Service |
21b5d1 |
// already aliased to something else and the new chain is legal, just swap in the old base.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
mapPos = sRegisteredAliasMap->find ( expAlias[kRootPropStep].step );
|
|
Packit Service |
21b5d1 |
if ( mapPos != sRegisteredAliasMap->end() ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// This alias is already registered to something, make sure it is the same something.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
regActual = &mapPos->second;
|
|
Packit Service |
21b5d1 |
if ( arrayForm != (mapPos->second[1].options & kXMP_PropArrayFormMask) ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Mismatch with existing alias array form", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( expActual.size() != regActual->size() ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Mismatch with existing actual path", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( expActual[kRootPropStep].step != (*regActual)[kRootPropStep].step ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Mismatch with existing actual name", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
if ( (expActual.size() == 3) && (expActual[kAliasIndexStep].step != (*regActual)[kAliasIndexStep].step) ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Mismatch with existing actual array item", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
return;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
mapPos = sRegisteredAliasMap->find ( expActual[kRootPropStep].step );
|
|
Packit Service |
21b5d1 |
if ( mapPos != sRegisteredAliasMap->end() ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// The actual is already aliased to something else.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
regActual = &mapPos->second;
|
|
Packit Service |
21b5d1 |
if ( expActual.size() == 2 ) {
|
|
Packit Service |
21b5d1 |
expActual = *regActual; // TopProp => TopProp => anything : substitute the entire old base.
|
|
Packit Service |
21b5d1 |
} else if ( regActual->size() != 2 ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Can't alias an array item to an array item", kXMPErr_BadParam ); // TopProp => TopArray[] => TopArray[] : nope.
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
expActual[kSchemaStep].step = (*regActual)[kSchemaStep].step; // TopProp => TopArray[] => TopProp :
|
|
Packit Service |
21b5d1 |
expActual[kRootPropStep].step = (*regActual)[kRootPropStep].step; // substitute the old base name.
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Checking for existing aliases to this one is touchier. This involves updating the alias map,
|
|
Packit Service |
21b5d1 |
// which must not be done unless all of the changes are legal. So we need 2 loops, one to verify
|
|
Packit Service |
21b5d1 |
// that everything is OK, and one to make the changes. The bad case is:
|
|
Packit Service |
21b5d1 |
// TopProp => TopArray[] => TopArray[]
|
|
Packit Service |
21b5d1 |
// In the valid cases we back substitute the new base.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( mapPos = sRegisteredAliasMap->begin(); mapPos != sRegisteredAliasMap->end(); ++mapPos ) {
|
|
Packit Service |
21b5d1 |
regActual = &mapPos->second;
|
|
Packit Service |
21b5d1 |
if ( expAlias[kRootPropStep].step == (*regActual)[kRootPropStep].step ) {
|
|
Packit Service |
21b5d1 |
if ( (regActual->size() == 2) && (expAlias.size() == 2) ) {
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Can't alias an array item to an array item", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( mapPos = sRegisteredAliasMap->begin(); mapPos != sRegisteredAliasMap->end(); ++mapPos ) {
|
|
Packit Service |
21b5d1 |
regActual = &mapPos->second;
|
|
Packit Service |
21b5d1 |
if ( expAlias[kRootPropStep].step == (*regActual)[kRootPropStep].step ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( regActual->size() == 1 ) {
|
|
Packit Service |
21b5d1 |
*regActual = expActual; // TopProp => TopProp => anything : substitute the entire new base.
|
|
Packit Service |
21b5d1 |
} else {
|
|
Packit Service |
21b5d1 |
(*regActual)[kSchemaStep].step = expActual[kSchemaStep].step; // TopProp => TopArray[] => TopProp :
|
|
Packit Service |
21b5d1 |
(*regActual)[kRootPropStep].step = expActual[kRootPropStep].step; // substitute the new base name.
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Finally, all is OK to register the new alias.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
(void) sRegisteredAliasMap->insert ( XMP_AliasMap::value_type ( expAlias[kRootPropStep].step, expActual ) );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // RegisterAlias
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// ResolveAlias
|
|
Packit Service |
21b5d1 |
// ------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ bool
|
|
Packit Service |
21b5d1 |
XMPMeta::ResolveAlias ( XMP_StringPtr aliasNS,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr aliasProp,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr * actualNS,
|
|
Packit Service |
21b5d1 |
XMP_StringLen * nsSize,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr * actualProp,
|
|
Packit Service |
21b5d1 |
XMP_StringLen * propSize,
|
|
Packit Service |
21b5d1 |
XMP_OptionBits * arrayForm )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (aliasNS != 0) && (aliasProp != 0) ); // Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (actualNS != 0) && (nsSize != 0) && (actualProp != 0) && (propSize != 0) && (arrayForm != 0) ); // Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Expand the input path and look up the first component in the alias table. Return if not an alias.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPath fullPath, minPath;
|
|
Packit Service |
21b5d1 |
ExpandXPath ( aliasNS, aliasProp, &fullPath );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( fullPath.size() >= 2 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
minPath.push_back ( fullPath[kSchemaStep] );
|
|
Packit Service |
21b5d1 |
minPath.push_back ( fullPath[kRootPropStep] );
|
|
Packit Service |
21b5d1 |
XMP_AliasMapPos mapPos = sRegisteredAliasMap->find ( minPath[kRootPropStep].step );
|
|
Packit Service |
21b5d1 |
if ( mapPos == sRegisteredAliasMap->end() ) return false;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Replace the alias portion of the full expanded path. Compose the output path string.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XMP_ExpandedXPath & actualPath = mapPos->second;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
fullPath[kSchemaStep] = actualPath[kSchemaStep];
|
|
Packit Service |
21b5d1 |
fullPath[kRootPropStep] = actualPath[kRootPropStep];
|
|
Packit Service |
21b5d1 |
if ( actualPath.size() > 2 ) { // This is an alias to an array item.
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPathPos insertPos = fullPath.begin() + kAliasIndexStep;
|
|
Packit Service |
21b5d1 |
fullPath.insert ( insertPos, actualPath[kAliasIndexStep] );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
*sOutputNS = fullPath[kSchemaStep].step;
|
|
Packit Service |
21b5d1 |
*actualNS = sOutputNS->c_str();
|
|
Packit Service |
21b5d1 |
*nsSize = sOutputNS->size();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
ComposeXPath ( fullPath, sOutputStr );
|
|
Packit Service |
21b5d1 |
*actualProp = sOutputStr->c_str();
|
|
Packit Service |
21b5d1 |
*propSize = sOutputStr->size();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
*arrayForm = actualPath[kRootPropStep].options & kXMP_PropArrayFormMask;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if XMP_DebugBuild // Test that the output string is valid and unchanged by round trip expand/compose.
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPath rtPath;
|
|
Packit Service |
21b5d1 |
ExpandXPath ( *actualNS, *actualProp, &rtPath );
|
|
Packit Service |
21b5d1 |
std::string rtString;
|
|
Packit Service |
21b5d1 |
ComposeXPath ( rtPath, &rtString );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( rtString == *sOutputStr );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return true;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // ResolveAlias
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DeleteAlias
|
|
Packit Service |
21b5d1 |
// -----------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::DeleteAlias ( XMP_StringPtr /*aliasNS*/,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr /*aliasProp*/ )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// Todo: XMP_Assert ( (aliasNS != 0) && (aliasProp != 0) ); / / Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Unimplemented method XMPMeta::DeleteAlias", kXMPErr_Unimplemented ); // *** #error "write me"
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DeleteAlias
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// RegisterStandardAliases
|
|
Packit Service |
21b5d1 |
// -----------------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
/* class-static */ void
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterStandardAliases ( XMP_StringPtr schemaNS )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( schemaNS != 0 ); // Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const bool doAll = (*schemaNS == 0);
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( doAll || XMP_LitMatch ( schemaNS, kXMP_NS_XMP ) ) {
|
|
Packit Service |
21b5d1 |
// Aliases from XMP to DC.
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Author", kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Authors", kXMP_NS_DC, "creator", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Description", kXMP_NS_DC, "description", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Format", kXMP_NS_DC, "format", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Keywords", kXMP_NS_DC, "subject", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Locale", kXMP_NS_DC, "language", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP, "Title", kXMP_NS_DC, "title", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_XMP_Rights, "Copyright", kXMP_NS_DC, "rights", 0 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( doAll || XMP_LitMatch ( schemaNS, kXMP_NS_PDF ) ) {
|
|
Packit Service |
21b5d1 |
// Aliases from PDF to DC and XMP.
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "Author", kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "BaseURL", kXMP_NS_XMP, "BaseURL", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "CreationDate", kXMP_NS_XMP, "CreateDate", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "Creator", kXMP_NS_XMP, "CreatorTool", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "ModDate", kXMP_NS_XMP, "ModifyDate", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "Subject", kXMP_NS_DC, "description", kXMP_PropArrayIsAltText );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PDF, "Title", kXMP_NS_DC, "title", kXMP_PropArrayIsAltText );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( doAll || XMP_LitMatch ( schemaNS, kXMP_NS_Photoshop ) ) {
|
|
Packit Service |
21b5d1 |
// Aliases from PHOTOSHOP to DC and XMP.
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Author", kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Caption", kXMP_NS_DC, "description", kXMP_PropArrayIsAltText );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Copyright", kXMP_NS_DC, "rights", kXMP_PropArrayIsAltText );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Keywords", kXMP_NS_DC, "subject", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Marked", kXMP_NS_XMP_Rights, "Marked", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "Title", kXMP_NS_DC, "title", kXMP_PropArrayIsAltText );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_Photoshop, "WebStatement", kXMP_NS_XMP_Rights, "WebStatement", 0 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( doAll || XMP_LitMatch ( schemaNS, kXMP_NS_TIFF ) || XMP_LitMatch ( schemaNS, kXMP_NS_EXIF ) ) {
|
|
Packit Service |
21b5d1 |
// Aliases from TIFF and EXIF to DC and XMP.
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_TIFF, "Artist", kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered);
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_TIFF, "Copyright", kXMP_NS_DC, "rights", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_TIFF, "DateTime", kXMP_NS_XMP, "ModifyDate", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_TIFF, "ImageDescription", kXMP_NS_DC, "description", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_TIFF, "Software", kXMP_NS_XMP, "CreatorTool", 0 );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( doAll || XMP_LitMatch ( schemaNS, kXMP_NS_PNG ) ) { // ! From Acrobat ImageCapture:
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "Author", kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered);
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "Copyright", kXMP_NS_DC, "rights", kXMP_PropArrayIsAltText);
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "CreationTime", kXMP_NS_XMP, "CreateDate", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "Description", kXMP_NS_DC, "description", kXMP_PropArrayIsAltText);
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "ModificationTime", kXMP_NS_XMP, "ModifyDate", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "Software", kXMP_NS_XMP, "CreatorTool", 0 );
|
|
Packit Service |
21b5d1 |
XMPMeta::RegisterAlias ( kXMP_NS_PNG, "Title", kXMP_NS_DC, "title", kXMP_PropArrayIsAltText);
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // RegisterStandardAliases
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
// Class Methods
|
|
Packit Service |
21b5d1 |
// =============
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// DumpObject
|
|
Packit Service |
21b5d1 |
// ----------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Status
|
|
Packit Service |
21b5d1 |
XMPMeta::DumpObject ( XMP_TextOutputProc outProc,
|
|
Packit Service |
21b5d1 |
void * refCon ) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( outProc != 0 ); // ! Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
XMP_Status status = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "Dumping XMPMeta object \"" );
|
|
Packit Service |
21b5d1 |
DumpClearString ( tree.name, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "\" ", 3 );
|
|
Packit Service |
21b5d1 |
status = DumpNodeOptions ( tree.options, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
#if 0 // *** XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
if ( (tree._namePtr != tree.name.c_str()) ||
|
|
Packit Service |
21b5d1 |
(tree._valuePtr != tree.value.c_str()) ) OutProcLiteral ( " ** bad debug string **" );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! tree.value.empty() ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "** bad root value ** \"" );
|
|
Packit Service |
21b5d1 |
DumpClearString ( tree.value, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( "\"", 1 );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! tree.qualifiers.empty() ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "** bad root qualifiers **" );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
for ( size_t qualNum = 0, qualLim = tree.qualifiers.size(); qualNum < qualLim; ++qualNum ) {
|
|
Packit Service |
21b5d1 |
status = DumpPropertyTree ( tree.qualifiers[qualNum], 3, 0, outProc, refCon );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! tree.children.empty() ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t childNum = 0, childLim = tree.children.size(); childNum < childLim; ++childNum ) {
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XMP_Node * currSchema = tree.children[childNum];
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
OutProcIndent ( 1 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currSchema->value, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 2 );
|
|
Packit Service |
21b5d1 |
DumpClearString ( currSchema->name, outProc, refCon );
|
|
Packit Service |
21b5d1 |
OutProcNChars ( " ", 2 );
|
|
Packit Service |
21b5d1 |
status = DumpNodeOptions ( currSchema->options, outProc, refCon );
|
|
Packit Service |
21b5d1 |
if ( status != 0 ) goto EXIT;
|
|
Packit Service |
21b5d1 |
#if 0 // *** XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
if ( (currSchema->_namePtr != currSchema->name.c_str()) ||
|
|
Packit Service |
21b5d1 |
(currSchema->_valuePtr != currSchema->value.c_str()) ) OutProcLiteral ( " ** bad debug string **" );
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! (currSchema->options & kXMP_SchemaNode) ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "** bad schema options **" );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! currSchema->qualifiers.empty() ) {
|
|
Packit Service |
21b5d1 |
OutProcLiteral ( "** bad schema qualifiers **" );
|
|
Packit Service |
21b5d1 |
OutProcNewline();
|
|
Packit Service |
21b5d1 |
for ( size_t qualNum = 0, qualLim = currSchema->qualifiers.size(); qualNum < qualLim; ++qualNum ) {
|
|
Packit Service |
21b5d1 |
DumpPropertyTree ( currSchema->qualifiers[qualNum], 3, 0, outProc, refCon );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
for ( size_t childNum = 0, childLim = currSchema->children.size(); childNum < childLim; ++childNum ) {
|
|
Packit Service |
21b5d1 |
DumpPropertyTree ( currSchema->children[childNum], 2, 0, outProc, refCon );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
EXIT:
|
|
Packit Service |
21b5d1 |
return status;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // DumpObject
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// CountArrayItems
|
|
Packit Service |
21b5d1 |
// ---------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Index
|
|
Packit Service |
21b5d1 |
XMPMeta::CountArrayItems ( XMP_StringPtr schemaNS,
|
|
Packit Service |
21b5d1 |
XMP_StringPtr arrayName ) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_Assert ( (schemaNS != 0) && (arrayName != 0) ); // Enforced by wrapper.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_ExpandedXPath expPath;
|
|
Packit Service |
21b5d1 |
ExpandXPath ( schemaNS, arrayName, &expPath );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
const XMP_Node * arrayNode = FindConstNode ( &tree, expPath );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( arrayNode == 0 ) return 0;
|
|
Packit Service |
21b5d1 |
if ( ! (arrayNode->options & kXMP_PropValueIsArray) ) XMP_Throw ( "The named property is not an array", kXMPErr_BadXPath );
|
|
Packit Service |
21b5d1 |
return arrayNode->children.size();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // CountArrayItems
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetObjectName
|
|
Packit Service |
21b5d1 |
// -------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::GetObjectName ( XMP_StringPtr * namePtr,
|
|
Packit Service |
21b5d1 |
XMP_StringLen * nameLen ) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
*namePtr = tree.name.c_str();
|
|
Packit Service |
21b5d1 |
*nameLen = tree.name.size();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetObjectName
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// SetObjectName
|
|
Packit Service |
21b5d1 |
// -------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::SetObjectName ( XMP_StringPtr name )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
VerifyUTF8 ( name ); // Throws if the string is not legit UTF-8.
|
|
Packit Service |
21b5d1 |
tree.name = name;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // SetObjectName
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// GetObjectOptions
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_OptionBits
|
|
Packit Service |
21b5d1 |
XMPMeta::GetObjectOptions() const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
XMP_OptionBits options = 0;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
return options;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // GetObjectOptions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// SetObjectOptions
|
|
Packit Service |
21b5d1 |
// ----------------
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::SetObjectOptions ( XMP_OptionBits /*options*/ )
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
XMP_Throw ( "Unimplemented method XMPMeta::SetObjectOptions", kXMPErr_Unimplemented );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // SetObjectOptions
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Sort
|
|
Packit Service |
21b5d1 |
// ----
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// At the top level the namespaces are sorted by their prefixes. Within a namespace, the top level
|
|
Packit Service |
21b5d1 |
// properties are sorted by name. Within a struct, the fields are sorted by their qualified name,
|
|
Packit Service |
21b5d1 |
// i.e. their XML prefix:local form. Unordered arrays of simple items are sorted by value. Language
|
|
Packit Service |
21b5d1 |
// Alternative arrays are sorted by the xml:lang qualifiers, with the "x-default" item placed first.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::Sort()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! this->tree.qualifiers.empty() ) {
|
|
Packit Service |
21b5d1 |
sort ( this->tree.qualifiers.begin(), this->tree.qualifiers.end(), CompareNodeNames );
|
|
Packit Service |
21b5d1 |
SortWithinOffspring ( this->tree.qualifiers );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
if ( ! this->tree.children.empty() ) {
|
|
Packit Service |
21b5d1 |
// The schema prefixes are the node's value, the name is the URI, so we sort schemas by value.
|
|
Packit Service |
21b5d1 |
sort ( this->tree.children.begin(), this->tree.children.end(), CompareNodeValues );
|
|
Packit Service |
21b5d1 |
SortWithinOffspring ( this->tree.children );
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Sort
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Erase
|
|
Packit Service |
21b5d1 |
// -----
|
|
Packit Service |
21b5d1 |
//
|
|
Packit Service |
21b5d1 |
// Clear everything except for clientRefs.
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::Erase()
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
this->prevTkVer = 0;
|
|
Packit Service |
21b5d1 |
if ( this->xmlParser != 0 ) {
|
|
Packit Service |
21b5d1 |
delete ( this->xmlParser );
|
|
Packit Service |
21b5d1 |
this->xmlParser = 0;
|
|
Packit Service |
21b5d1 |
}
|
|
Packit Service |
21b5d1 |
this->tree.ClearNode();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Erase
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// -------------------------------------------------------------------------------------------------
|
|
Packit Service |
21b5d1 |
// Clone
|
|
Packit Service |
21b5d1 |
// -----
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
void
|
|
Packit Service |
21b5d1 |
XMPMeta::Clone ( XMPMeta * clone, XMP_OptionBits options ) const
|
|
Packit Service |
21b5d1 |
{
|
|
Packit Service |
21b5d1 |
if ( clone == 0 ) XMP_Throw ( "Null clone pointer", kXMPErr_BadParam );
|
|
Packit Service |
21b5d1 |
if ( options != 0 ) XMP_Throw ( "No options are defined yet", kXMPErr_BadOptions );
|
|
Packit Service |
21b5d1 |
XMP_Assert ( this->tree.parent == 0 );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
clone->tree.ClearNode();
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
clone->tree.options = this->tree.options;
|
|
Packit Service |
21b5d1 |
clone->tree.name = this->tree.name;
|
|
Packit Service |
21b5d1 |
clone->tree.value = this->tree.value;
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
#if 0 // *** XMP_DebugBuild
|
|
Packit Service |
21b5d1 |
clone->tree._namePtr = clone->tree.name.c_str();
|
|
Packit Service |
21b5d1 |
clone->tree._valuePtr = clone->tree.value.c_str();
|
|
Packit Service |
21b5d1 |
#endif
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
CloneOffspring ( &this->tree, &clone->tree );
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
} // Clone
|
|
Packit Service |
21b5d1 |
|
|
Packit Service |
21b5d1 |
// =================================================================================================
|