[Helix-client-dev] CR/CN: Implemented redirection of output into log file [GMPMetaEditor branch]
Petar Basic <[email protected]> Sat, 16 Jan 2010 23:36:20 +0100
| Newsgroups | gmane.comp.multimedia.helix.devel |
|---|---|
| Message-ID | <[email protected]> |
Modified by: pbasic at real.com Date: 2010/01/16 Project: GMPMetaEditor (meta3gp.exe) Synopsis: Implemented redirection of output into log file [GMPMetaEditor branch] Details: Implemented -log option which redirects all output (stdout, stderr) into specified log file. Files Modified: datatype/tools/dtdriver/apps/meta3gp/main.cpp Platforms and Profiles Affected: All Image Size and Heap Use impact: None Platforms and Profiles Build Verified: system id: win32-i386-vc7, sunos-5.10-sparc-studio11 profile: helix-client-all-defines Platforms and Profiles Functionality Verified: x86 Windows XP SP2 Sparc SunOS 5.10 Branch: GMPMetaEditor Copyright assignment: I am a RealNetworks employee or contractor. _______________________________________________ Helix-client-dev mailing list [email protected] http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
datatype_tools_dtdriver_apps_meta3gp.diff
(application/octet-stream, 52.2 KB)
Index: main.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/apps/meta3gp/main.cpp,v
retrieving revision 1.7.2.2
diff -d -H -w -U30 -r1.7.2.2 main.cpp
--- main.cpp 14 Jan 2010 22:59:00 -0000 1.7.2.2
+++ main.cpp 16 Jan 2010 22:32:09 -0000
@@ -149,60 +149,61 @@
*/
ENABLE_DLLACCESS_PATHS(g_Meta3GPAccessPath);
/****************************************************************************
* Defines
*/
#define PROGRAM_NAME_STRING "RealNetworks meta-data editor"
#define PROGRAM_COPYRIGHT_STRING "Copyright (c) RealNetworks 2010"
// input/output control
#ifdef _WINDOWS
#define OPTION_STRING_ASYNCMODE "dev-asyncmode"
#endif //_WINDOWS
#define OPTION_STRING_DEFMETAPROC "dev-defmetaproc"
#define OPTION_STRING_INPUTFILE "if"
#define OPTION_STRING_OUTPUTFILE "of"
#define OPTION_STRING_XMLINPUTFILE "xmlin"
#define OPTION_STRING_XMLOUTPUTFILE "xmlout"
#define OPTION_STRING_CLEARMETADATA "metaclear"
#define OPTION_STRING_METASTYLE "metastyle"
#define OPTION_STRING_UTF16OUTPUT "utf16"
#define OPTION_STRING_ID3V240OUTPUT "id3v240"
#define OPTION_STRING_ID3V230OUTPUT "id3v230"
#define OPTION_STRING_ID3V2NOOUTPUT "id3v2no"
#define OPTION_STRING_OVERWRITEFILE "overwrite"
#define OPTION_STRING_PRINTMETADATA "print"
#define OPTION_STRING_HELP "help"
#define OPTION_STRING_GENERATEHASH "audiohash"
+#define OPTION_STRING_LOGFILE "log"
// common metadata
#define OPTION_STRING_TITLE "title"
#define OPTION_STRING_ARTIST "artist"
#define OPTION_STRING_ALBUM "album"
#define OPTION_STRING_GENRE "genre"
#define OPTION_STRING_COMPOSER "composer"
#define OPTION_STRING_COMMENT "comment"
#define OPTION_STRING_TRACKNUMBER "track"
#define OPTION_STRING_YEAR "year"
#define OPTION_STRING_PICTURE_ADD "addpic"
#define OPTION_STRING_PICTURE_REMOVE "rempic"
#define OPTION_STRING_PICTURE_CLEAR "clrpic"
#define OPTION_STRING_PICTURE_EXTRACT "savepic"
#define OPTION_STRING_UITS_INSERT "insertsignature"
#define OPTION_STRING_UITS_EXTRACT "extractsignature"
// iTunes specific metadata
#define OPTION_STRING_SOFTWARE "software"
#define OPTION_STRING_ENCODEDBY "encodedby"
#define OPTION_STRING_GROUPING "grouping"
#define OPTION_STRING_ALBUMARTIST "albumartist"
#define OPTION_STRING_LYRICS "lyrics"
#define OPTION_STRING_SUBTITLE "subtitle"
#define OPTION_STRING_BPM "bpm"
#define OPTION_STRING_PARTOFCOMP "partofcompilation"
#define OPTION_STRING_EXPLICIT "explicitcontent"
#define OPTION_STRING_TRACKSTOTAL "trackstotal"
@@ -214,128 +215,128 @@
#define OPTION_STRING_COPYRIGHT "copyright"
#define OPTION_STRING_RATING_ENTITY "rtngent"
#define OPTION_STRING_RATING_CRITERIA "rtngcrit"
#define OPTION_STRING_RATING_INFO "rtnginfo"
#define OPTION_STRING_CLASSIFICATION_ENTITY "clsent"
#define OPTION_STRING_CLASSIFICATION_TABLE "clstbl"
#define OPTION_STRING_CLASSIFICATION_INFO "clsinfo"
#define OPTION_STRING_KEYWORD_ADD "addkwd"
#define OPTION_STRING_KEYWORD_REMOVE "remkwd"
#define OPTION_STRING_KEYWORD_CLEAR "clrkwd"
#define OPTION_STRING_LOCATION_NAME "locname"
#define OPTION_STRING_LOCATION_ASTRONOMICAL_BODY "locastro"
#define OPTION_STRING_LOCATION_ADDITIONAL_NOTES "locnotes"
#define OPTION_STRING_LOCATION_ROLE "locrole"
#define OPTION_STRING_LOCATION_LONGITUDE "loclong"
#define OPTION_STRING_LOCATION_LATITUDE "loclat"
#define OPTION_STRING_LOCATION_ALTITUDE "localt"
/****************************************************************************
* Help display utilities
*/
class OptionDesc
{
public:
OptionDesc(const char* option_ = 0, const char* option_args_ = 0, const char* desc_ = 0,
- int option_num_ = 0, const char* xpath_ = 0)
+ int arg_count_ = 0, const char* xpath_ = 0)
{
option = option_;
option_args = option_args_;
desc = desc_;
- option_num = option_num_;
+ arg_count = arg_count_;
xpath = xpath_;
}
UINT32 GetLeftColumnWidth()
{
UINT32 len = 0;
if(option)
{
len += 2 + strlen(option); //leading whitespace and option prefix
if(option_args)
{
len += 1 + strlen(option_args); //whitespace separator and option args
}
}
return len;
}
CHXString BuildLine(UINT32 leftColumnWidth)
{
CHXString out = "";
if(option)
{
out += " -"; //leading whitespace and option prefix
out += option;
if(option_args)
{
out += " "; //whitespace separator
out += option_args;
}
if(desc)
{
INT32 diff = leftColumnWidth - strlen(out);
for(int d = 0; d < diff; d++)
{
out += " ";
}
out += desc;
}
}
return out;
}
const char* GetOptionString() const
{
return option ? option : "";
}
const char* GetXPath() const
{
return xpath ? xpath : "";
}
- int GetNumberOfOptions()
+ int GetNumberOfArguments()
{
- return option_num;
+ return arg_count;
}
private:
const char* option;
const char* option_args;
const char* desc;
- int option_num;
+ int arg_count;
const char* xpath;
};
class OptionRegistry
{
public:
~OptionRegistry()
{
for(int i = 0; i < descs.GetSize(); i++)
{
delete (OptionDesc*)descs.GetAt(i);
}
}
void Add(OptionDesc* od)
{
descs.Add(od);
}
int CalcLeftColumnWidth()
{
int leftColumnWidth = 0;
for(int i = 0; i < descs.GetSize(); i++)
{
OptionDesc* od = (OptionDesc*)descs.GetAt(i);
int width = od->GetLeftColumnWidth();
if(width > leftColumnWidth)
{
leftColumnWidth = width;
@@ -400,77 +401,93 @@
OptionDesc* GetOptionDescWithPath(CHXString& strArg) const
{
for(int i = 0; i < descs.GetSize(); i++)
{
OptionDesc* od = (OptionDesc*)descs.GetAt(i);
if(strArg == od->GetXPath())
{
return od;
}
}
return NULL;
}
void InitializeXmlPairs(CParsedXmlPairs *xmlPairs)
{
for(int i = 0; i < descs.GetSize(); i++)
{
OptionDesc* desc = (OptionDesc*)descs.GetAt(i);
CHXString xpath(desc->GetXPath());
if(!xpath.IsEmpty())
{
xmlPairs->Add(new XmlPair(xpath, EncodedString()));
}
}
}
private:
CHXPtrArray descs;
};
-void DisplayUsage(const TCHAR* argv0, OptionRegistry& optionReg)
+void DisplayProgramInfo()
{
const char* pszDbg = "";
#if defined(DEBUG) || defined(_DEBUG)
pszDbg = ".debug";
#endif
- CHXString exeName = CHXFileSpecUtils::GetCurrentApplication().GetName();
-
printf("\n--- %s ---\n %s\n Version %s%s\n\n",
PROGRAM_NAME_STRING, PROGRAM_COPYRIGHT_STRING, TARVER_STRING_VERSION, pszDbg);
+}
+
+void DisplayUsage(const TCHAR* argv0, OptionRegistry& optionReg)
+{
+ CHXString exeName = CHXFileSpecUtils::GetCurrentApplication().GetName();
+
printf("usage: %s [ -option [value]... ]...\n", (const char*)exeName);
printf("with options:\n");
optionReg.PrintColumns(2);
}
+CHXString GetUTCTimeString()
+{
+ time_t currTime = time(0);
+ tm* pUTCTime = gmtime(&currTime);
+
+ const UINT32 bufSize = 64;
+ char buffer[bufSize];
+ strftime(buffer, bufSize, "%Y-%m-%dT%H:%M:%SZ", pUTCTime);
+
+ return CHXString(buffer);
+}
+
/****************************************************************************
* Asynchronous mode helpers
*/
void SignalAsyncDriveEnd()
{
#ifdef _WINDOWS
::PostMessage(0, (WM_USER + 202), 0, 0);
#else
printf("ERROR: SignalAsyncDriveEnd not implemented.\n");
#endif
}
void WaitAsyncDriveEnd()
{
#ifdef _WINDOWS
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
if(msg.message == (WM_USER + 202))
{
break;
}
DispatchMessage(&msg);
}
#else
printf("ERROR: WaitAsyncDriveEnd not implemented.\n");
#endif
}
@@ -717,80 +734,93 @@
argPosition += step;
if(argPosition < 0)
{
argPosition = 0;
}
}
const TCHAR* CurrentRawArg()
{
if(argPosition < argc)
{
return argv[argPosition];
}
return 0;
}
// Returns pointer to option name
const TCHAR* CurrentOption(HXBOOL bWithPrefix)
{
if(argPosition < argc)
{
const TCHAR* pVal = argv[argPosition];
if(pVal && (pVal[0] == _T('-')))
{
return bWithPrefix ? pVal : (pVal + 1);
}
}
return 0;
}
- const TCHAR* CurrentArg(UINT32 offset, HXBOOL bOptional = FALSE)
+ const TCHAR* CurrentArg(UINT32 offset, HXBOOL bOptional, HXBOOL bPrintError)
{
int argIndex = argPosition + (int)offset;
if(argIndex < argc)
{
const TCHAR* pVal = argv[argIndex];
if(pVal && !optionReg.IsOption(pVal))
{
return pVal;
}
}
- if(!bOptional)
+ if(!bOptional && bPrintError)
{
CHXString strOption = TCHXStringCtor(CurrentOption(TRUE));
printf("Missing argument for option: %s\n", (const char*)strOption);
}
return 0;
}
+ void DumpCommandLine()
+ {
+ for(int i = 0; i < argc; i++)
+ {
+#ifdef USE_WIDE_CHAR_COMMAND_LINE
+ wprintf(L"%ls ", argv[i]);
+#else
+ printf("%s ", argv[i]);
+#endif
+ }
+ printf("\n");
+ }
+
private:
int argc;
TCHAR** argv;
int argPosition;
OptionRegistry& optionReg;
};
void ReportUnsupportedMetaStyleOption(const char* optionName)
{
printf("Option -%s not supported in combination with specified metastyle(s)\n", optionName);
}
void ReportInvalidValueForOption(const char* optionName, const EncodedString& optionValueUTF8)
{
printf("Invalid value for option -%s: ", optionName);
EncStrUtils::PrintTextUTF8(optionValueUTF8.GetData());
printf("\n");
}
HX_RESULT ProcessStringOption(bool bSkipArgOnly, InputOption* option, MetaInfo& metainfo,
MetaInfo::eStringMetaItem itemName, UINT32 metaFlavorFlags)
{
if(option->OptionValueUTF8.IsEmpty() && option->XmlOptionValueUTF8.IsEmpty())
{
return HXR_PARSE_ERROR;
}
if(bSkipArgOnly)
{
return HXR_OK;
@@ -1078,76 +1108,310 @@
}
if(FAILED(retVal))
{
printf("Invalid image file for option %s: %s\n",
(const char*)option->OptionName, (const char*)sFileName);
}
// export frame
if(SUCCEEDED(retVal) && pFrame)
{
if(!aAddedAPICFrames.AddIfUnique(pFrame))
{
retVal = HXR_FAILED;
}
}
if(FAILED(retVal))
{
// cleanup
HX_DELETE(pFrame);
}
return retVal;
}
ReportUnsupportedMetaStyleOption(option->OptionName);
return HXR_PARSE_ERROR;
}
+// Only moves argVars position if successful
HX_RESULT CopyOptionArgumentString(ArgVars& argVars, EncodedString& sOut, HXBOOL bOptional = FALSE)
{
sOut.Clear();
- const TCHAR* pVal = argVars.CurrentArg(1, bOptional);
+ const TCHAR* pVal = argVars.CurrentArg(1, bOptional, TRUE);
if(!pVal && !bOptional)
{
return HXR_PARSE_ERROR;
}
sOut = TUTF8EncodedStringCtor(pVal);
argVars.MovePosition(1);
return HXR_OK;
}
+class InputOptions
+{
+public:
+ InputOptions()
+ : position(0)
+ {
+ }
+
+ ~InputOptions()
+ {
+ Clear();
+ }
+
+ void Clear()
+ {
+ for(int i = 0; i < options.GetSize(); i++)
+ {
+ delete (InputOption*)options.GetAt(i);
+ }
+
+ options.RemoveAll();
+ position = 0;
+ }
+
+ void Add(InputOption* inputOpt)
+ {
+ options.Add(inputOpt);
+ }
+
+ void ResetPosition(int pos = 0)
+ {
+ position = pos;
+ }
+
+ HXBOOL ReachedEndPosition()
+ {
+ return (position >= options.GetSize());
+ }
+
+ void MovePosition(int step = 1)
+ {
+ position += step;
+ if(position < 0)
+ {
+ position = 0;
+ }
+ }
+
+ InputOption* GetOption(const CHXString& optionName) const
+ {
+ for(int i = 0; i < options.GetSize(); i++)
+ {
+ InputOption* option = (InputOption*)options.GetAt(i);
+
+ if(option->OptionName == optionName)
+ {
+ return option;
+ }
+ }
+
+ return 0;
+ }
+
+ // Returns pointer to option
+ InputOption* CurrentOption() const
+ {
+ if(position < options.GetSize())
+ {
+ return (InputOption*)options.GetAt(position);
+ }
+
+ return 0;
+ }
+
+private:
+ CHXPtrArray options;
+ int position;
+};
+
+HX_RESULT ParseCommandLineInputOptions(ArgVars& argVars, OptionRegistry& optionReg, InputOptions& inputOptions,
+ HXBOOL bStrictMode, HXBOOL bPrintErrors)
+{
+ HX_RESULT retVal = HXR_OK;
+
+ for(argVars.ResetPosition(1); SUCCEEDED(retVal) && !argVars.ReachedEndPosition(); argVars.MovePosition(1))
+ {
+ // accept option format only
+ CHXString strOption = TCHXStringCtor(argVars.CurrentOption(FALSE));
+
+ if(strOption.IsEmpty())
+ {
+ if(bPrintErrors)
+ {
+ printf("Found non-option command-line argument: %s\n",
+ (const char*)TCHXStringCtor(argVars.CurrentRawArg()));
+ }
+ if(bStrictMode)
+ {
+ retVal = HXR_PARSE_ERROR;
+ }
+ continue;
+ }
+
+ // check if we're looking at known option
+ OptionDesc* od = optionReg.GetOptionDesc(strOption);
+ if(od == NULL)
+ {
+ if(bPrintErrors)
+ {
+ printf("Unrecognized option: -%s\n", (const char*)strOption);
+ }
+ if(bStrictMode)
+ {
+ retVal = HXR_PARSE_ERROR;
+ }
+ continue;
+ }
+
+ EncodedString optionArgument;
+
+ // retrieve argument values and store them into inputOptions
+ UINT32 numArgs = od->GetNumberOfArguments();
+ switch(numArgs)
+ {
+ case -1:
+ {
+ // zero or one argument
+ numArgs = 1;
+ retVal = CopyOptionArgumentString(argVars, optionArgument, TRUE);
+ break;
+ }
+
+ case 0:
+ // no arguments
+ break;
+
+ case 1:
+ {
+ // one argument
+ retVal = CopyOptionArgumentString(argVars, optionArgument, FALSE);
+ break;
+ }
+
+ default:
+ // unsupported number of option arguments
+ retVal = HXR_PARSE_ERROR;
+ continue;
+ }
+
+ if(FAILED(retVal) && !bStrictMode)
+ {
+ retVal = HXR_OK;
+ argVars.MovePosition(numArgs);
+ continue;
+ }
+
+ if(SUCCEEDED(retVal))
+ {
+ inputOptions.Add(new InputOption(strOption, optionArgument, EncodedString()));
+ }
+ }
+
+ return retVal;
+}
+
+HX_RESULT ParseXMLInputOptions(IHXCommonClassFactory* pCommonClassFactory, CHXXmlInputParser* pInputParser,
+ InputOption* option, CParsedXmlPairs* parsedXmlResults)
+{
+ if(option->OptionValueUTF8.IsEmpty())
+ {
+ return HXR_FAIL;
+ }
+
+ FILE* fp = fopen((const char*)option->GetEffectiveOptionValueCCP(), "r");
+ if(fp == NULL)
+ {
+ printf("Unable to open file: %s\n", (const char*)option->GetEffectiveOptionValueCCP());
+ return HXR_FAIL;
+ }
+
+ HX_RESULT retVal = HXR_OK;
+ retVal = pInputParser->Start(parsedXmlResults);
+
+ ULONG32 uParserBufferSize = 64 * 1024;
+
+ if(SUCCEEDED(retVal))
+ {
+ // create temporary buffer for manifest chunks
+ IHXBuffer* pBuffer = NULL;
+ retVal = CreateBufferCCF(pBuffer, pCommonClassFactory);
+ if(SUCCEEDED(retVal))
+ {
+ pBuffer->SetSize(uParserBufferSize);
+
+ // read manifest, chunk by chunk
+ while(true)
+ {
+ size_t nItemsRead = fread(pBuffer->GetBuffer(), 1, uParserBufferSize, fp);
+ if(nItemsRead != 0)
+ {
+ if(uParserBufferSize != nItemsRead)
+ {
+ pBuffer->SetSize(nItemsRead);
+ }
+
+ // parse chunk
+ HXBOOL bIsFinal = uParserBufferSize != nItemsRead;
+ retVal = pInputParser->Parse(pBuffer, bIsFinal);
+ if(!SUCCEEDED(retVal))
+ {
+ break;
+ }
+ }
+ if(nItemsRead < uParserBufferSize)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+
+ if(SUCCEEDED(retVal))
+ {
+ // retrieve manifest
+ retVal = pInputParser->EndParse();
+ }
+
+ fclose(fp);
+
+ return retVal;
+}
+
HXBOOL NeedOverwriteConfirmation(const char* pFileName, HXBOOL bOverwriteFile)
{
HXBOOL bNeedConfirmation = FALSE;
if(pFileName)
{
if(CHXFileSpecUtils::FileExists(CHXFileSpecifier(pFileName)))
{
if(!bOverwriteFile)
{
bNeedConfirmation = TRUE;
printf("Output file [%s] already exists. Use -%s option to force overwrite.\n",
pFileName, OPTION_STRING_OVERWRITEFILE);
}
}
}
return bNeedConfirmation;
}
/****************************************************************************
* Meta-data processor
*/
class CProcessor : public IHXMetaDataProcessor
{
public:
CProcessor(MetaProcessorVars& vars)
: m_lRefCount(0)
, m_vars(vars)
, m_pContext(0)
{
@@ -1297,318 +1561,243 @@
#ifdef HELIX_FEATURE_METAEDIT_AUDIO_HASH
if(m_vars.GenerateHash)
{
sha256_init(&m_vars.HashState);
m_bHashGenerated = FALSE;
}
#endif
return HXR_OK;
}
STDMETHOD(OnStreamDone)(UINT16 unStreamNumber)
{
#ifdef HELIX_FEATURE_METAEDIT_AUDIO_HASH
if(m_vars.GenerateHash && !m_bHashGenerated)
{
sha256_done(&m_vars.HashState, m_vars.SHAHash);
// make sure, that even if there is more than one call to OnStreamDone, we execute sha finalizer just one time
m_bHashGenerated = TRUE;
}
#endif
return HXR_OK;
}
private:
LONG32 m_lRefCount;
MetaProcessorVars& m_vars;
IUnknown* m_pContext;
HXBOOL m_bHashGenerated;
};
-class InputOptions
-{
-public:
- InputOptions()
- : position(0)
- {
- }
-
- ~InputOptions()
- {
- for(int i = 0; i < options.GetSize(); i++)
- {
- delete (InputOption*)options.GetAt(i);
- }
- }
-
- void Add(InputOption* inputOpt)
- {
- options.Add(inputOpt);
- }
-
- void ResetPosition(int pos = 0)
- {
- position = pos;
- }
-
- HXBOOL ReachedEndPosition()
- {
- return (position >= options.GetSize());
- }
-
- void MovePosition(int step = 1)
- {
- position += step;
- if(position < 0)
- {
- position = 0;
- }
- }
-
- InputOption* GetOption(const CHXString& optionName) const
- {
- for(int i = 0; i < options.GetSize(); i++)
- {
- InputOption* option = (InputOption*)options.GetAt(i);
-
- if(option->OptionName == optionName)
- {
- return option;
- }
- }
-
- return 0;
- }
-
- // Returns pointer to option
- InputOption* CurrentOption() const
- {
- if(position < options.GetSize())
- {
- return (InputOption*)options.GetAt(position);
- }
-
- return 0;
- }
-
-private:
- CHXPtrArray options;
- int position;
-};
-
-HX_RESULT ParseCommandLineInputOptions(ArgVars& argVars, OptionRegistry& optionReg, InputOptions& inputOptions)
-{
- HX_RESULT retVal = HXR_OK;
-
- for(argVars.ResetPosition(1); SUCCEEDED(retVal) && !argVars.ReachedEndPosition(); argVars.MovePosition(1))
- {
- // accept option format only
- CHXString strOption = TCHXStringCtor(argVars.CurrentOption(FALSE));
-
- if(strOption.IsEmpty())
- {
- printf("Found non-option command-line argument: %s\n",
- (const char*)TCHXStringCtor(argVars.CurrentRawArg()));
- retVal = HXR_PARSE_ERROR;
- continue;
- }
-
- // check if we're looking at known option
- OptionDesc* od = optionReg.GetOptionDesc(strOption);
- if(od == NULL)
- {
- printf("Unrecognized option: -%s\n", (const char*)strOption);
- retVal = HXR_PARSE_ERROR;
- continue;
- }
-
- EncodedString optionArgument;
-
- // get the option value and store it into inputOptions
- switch(od->GetNumberOfOptions())
- {
- case -1:
- {
- // zero or one parameter
- retVal = CopyOptionArgumentString(argVars, optionArgument, TRUE);
- break;
- }
-
- case 0:
- // no parameters
- break;
-
- case 1:
- {
- // one parameter
- retVal = CopyOptionArgumentString(argVars, optionArgument, FALSE);
- break;
- }
-
- default:
- // unsupported number of option arguments
- retVal = HXR_PARSE_ERROR;
- break;
- }
-
- if(SUCCEEDED(retVal))
- {
- inputOptions.Add(new InputOption(strOption, optionArgument, EncodedString()));
- }
- }
-
- return retVal;
-}
-
-HX_RESULT ParseXMLInputOptions(IHXCommonClassFactory* pCommonClassFactory, CHXXmlInputParser* pInputParser,
- InputOption* option, CParsedXmlPairs* parsedXmlResults)
-{
- if(option->OptionValueUTF8.IsEmpty())
- {
- return HXR_FAIL;
- }
-
- FILE* fp = fopen((const char*)option->GetEffectiveOptionValueCCP(), "r");
- if(fp == NULL)
- {
- printf("Unable to open file: %s\n", (const char*)option->GetEffectiveOptionValueCCP());
- return HXR_FAIL;
- }
-
- HX_RESULT retVal = HXR_OK;
- retVal = pInputParser->Start(parsedXmlResults);
-
- ULONG32 uParserBufferSize = 64 * 1024;
-
- if(SUCCEEDED(retVal))
- {
- // create temporary buffer for manifest chunks
- IHXBuffer* pBuffer = NULL;
- retVal = CreateBufferCCF(pBuffer, pCommonClassFactory);
- if(SUCCEEDED(retVal))
- {
- pBuffer->SetSize(uParserBufferSize);
-
- // read manifest, chunk by chunk
- while(true)
- {
- size_t nItemsRead = fread(pBuffer->GetBuffer(), 1, uParserBufferSize, fp);
- if(nItemsRead != 0)
- {
- if(uParserBufferSize != nItemsRead)
- {
- pBuffer->SetSize(nItemsRead);
- }
-
- // parse chunk
- HXBOOL bIsFinal = uParserBufferSize != nItemsRead;
- retVal = pInputParser->Parse(pBuffer, bIsFinal);
- if(!SUCCEEDED(retVal))
- {
- break;
- }
- }
- if(nItemsRead < uParserBufferSize)
- {
- break;
- }
- }
- }
- }
-
-
- if(SUCCEEDED(retVal))
- {
- // retrieve manifest
- retVal = pInputParser->EndParse();
- }
-
- fclose(fp);
-
- return retVal;
-}
/****************************************************************************
* Main entry point
*/
int TMAIN(int argc, TCHAR* argv[])
{
- // separate shell command from output
- printf("\n");
-
// initialize variables
- CHXFileSpecifier exeFileSpec;
+ HX_RESULT retVal = HXR_OK;
+
UINT32 startTime = 0;
+ CHXFileSpecifier exeFileSpec;
+ HXBOOL bUsingLog = FALSE;
+ HXBOOL bFailedToOpenLog = FALSE;
DLLAccess* pDLLAccess = 0;
FPHXMEDIAPLATFORMOPEN fpHXMediaPlatformOpen = 0;
FPHXCREATEMEDIAPLATFORM fpHXCreateMediaPlatform = 0;
FPHXMEDIAPLATFORMCLOSE fpHXMediaPlatformClose = 0;
IHXMediaPlatform* pMediaPlatform = 0;
IHXCommonClassFactory* pCommonClassFactory = 0;
+ CHXXmlInputParser* pInputParser = 0;
IHXMetaDataEditor* pEditor = 0;
CResponse* pResponse = 0;
CProcessor* pProcessor = 0;
IHXValues* pOptions = 0;
char pDllPath[_MAX_PATH] = {0};
char pDllFile[_MAX_PATH] = {0};
const char* pszHelixPluginPath = 0;
CHXString strInputFileName;
CHXString strOutputFileName;
CHXString strPictureFileNamePrefix;
CHXString strUITSDataOutputFileName;
CHXString strMetaStyleName;
HXBOOL bDisplayHelp = FALSE;
HXBOOL bOverwriteFile = FALSE;
HXBOOL bPrintMetaData = FALSE;
HXBOOL bExtractPicturesToFiles = FALSE;
HXBOOL bUTF16Output = FALSE;
UINT32 ulMetaDataID3VersionOutput = METADATAID3VERSION_240;
MetaProcessorVars metaProcessorVars;
+
+ // construct option registry
OptionRegistry optionReg;
- eCommandLineProcessorPhase clpp = CLPP_IndependentOptions;
- // input options parsed from the command line and xml file
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOGFILE, "<filename>", "redirect console output to log file", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_INPUTFILE, "<filename>", "input file", 1, "/albums/album/track/mediaFile/fileName"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_OUTPUTFILE, "<filename>", "output file", 1, "/albums/album/track/outputFileName"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_XMLINPUTFILE, "<filename>", "XML file with input parameters", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_OVERWRITEFILE, 0, "overwrite output file if it exists", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_CLEARMETADATA, 0, "clear all extracted metadata before injection", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_METASTYLE, "<3GPP | iTunes>", "flavor of injected metadata", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_UTF16OUTPUT, 0, "inject metadata strings in UTF16 format", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ID3V240OUTPUT, 0, "inject ID3v2 version 2.4.0, default", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ID3V230OUTPUT, 0, "inject ID3v2 version 2.3.0", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ID3V2NOOUTPUT, 0, "skip injecting ID3v2 tag", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PRINTMETADATA, 0, "print updated metadata", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_EXTRACT, "[filename-prefix]", "save extracted pictures", -1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_GENERATEHASH, 0, "generate hash", 0));
+ optionReg.Add(new OptionDesc());
+ optionReg.Add(new OptionDesc(OPTION_STRING_TITLE, "<string>", "update title", 1, "/albums/album/track/name"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ARTIST, "<string>", "update 3GPP performer, iTunes artist", 1, "/albums/album/track/artist/name"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ALBUM, "<string>", "update album", 1, "/albums/album/name"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_GENRE, "<string>", "update genre", 1, "/albums/album/track/style/name"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_COMPOSER, "<string>", "update 3GPP author, iTunes composer", 1, "/albums/album/track/artist/composer"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_COMMENT, "<string>", "update 3GPP description, iTunes comment", 1, "/albums/album/pline"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_COPYRIGHT, "<string>", "update copyright", 1, "/albums/album/cline"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_TRACKNUMBER, "<integer 0..255>", "update track number", 1, "/albums/album/track/sequence"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_YEAR, "<integer 0..65536>", "update 3GPP recording year, iTunes release date", 1, "/albums/album/OrigReleaseYear"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_ADD, "<filename>", "add picture", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_REMOVE, "<APIC picture type>", "remove picture", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_CLEAR, 0, "clear all extracted pictures", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_UITS_INSERT, "<filename>", "insert UITS signature from file", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_UITS_EXTRACT, "<filename>", "extract UITS signature into file", 1));
+ optionReg.Add(new OptionDesc());
+ optionReg.Add(new OptionDesc(OPTION_STRING_SOFTWARE, "<string>", "update iTunes generator tool", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ENCODEDBY, "<string>", "update iTunes encoded by", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_GROUPING, "<string>", "update iTunes grouping", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_ALBUMARTIST, "<string>", "update iTunes album artist", 1, "/albums/album/artist/name"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LYRICS, "<string>", "update iTunes lyrics", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_SUBTITLE, "<string>", "update iTunes track subtitle", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_BPM, "<integer>", "update iTunes beats per minute", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_PARTOFCOMP, "<0 | 1>", "update iTunes part of compilation", 1, "/albums/album/compilation"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_EXPLICIT, "<0 | 1>", "update iTunes content rating", 1, "/albums/album/explicit"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_TRACKSTOTAL, "<integer>", "update iTunes track count", 1, "/albums/album/trackCount"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_DISKNUMBER, "<integer>", "update iTunes disc number", 1, "/albums/album/track/discNumber"));
+ optionReg.Add(new OptionDesc(OPTION_STRING_DISKSTOTAL, "<integer>", "update iTunes disc count", 1, "/albums/album/discCount"));
+ optionReg.Add(new OptionDesc());
+ optionReg.Add(new OptionDesc(OPTION_STRING_RATING_ENTITY, "<4 character code>", "update 3GPP rating entity", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_RATING_CRITERIA, "<4 character code>", "update 3GPP rating criteria", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_RATING_INFO, "<string>", "update 3GPP rating info", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_ENTITY, "<4 character code>", "update 3GPP classification entity", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_TABLE, "<integer 0..65535>", "update 3GPP classification table", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_INFO, "<string>", "update 3GPP classification info", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_ADD, "<string>", "add 3GPP keyword", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_REMOVE, "<string>", "remove 3GPP keyword", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_CLEAR, 0, "clear all extracted 3GPP keywords", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_NAME, "<string>", "update 3GPP location name", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ASTRONOMICAL_BODY, "<string>", "update 3GPP location astronomical body", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ADDITIONAL_NOTES, "<string>", "update 3GPP location notes", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ROLE, "<integer 0..255>", "update 3GPP location role", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_LONGITUDE, "<decimal number>", "update 3GPP location longitude", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_LATITUDE, "<decimal number>", "update 3GPP location latitude", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ALTITUDE, "<decimal number>", "update 3GPP location altitude", 1));
+ optionReg.Add(new OptionDesc(OPTION_STRING_LANGUAGE_CODE, "<3 character code>", "ISO639.2/T language code of 3GPP metadata text", 1));
+ optionReg.Add(new OptionDesc());
+
+#ifdef _WINDOWS
+ optionReg.Add(new OptionDesc(OPTION_STRING_ASYNCMODE, 0, "dtdriver asynchronous mode (developer option)", 0));
+#endif //_WINDOWS
+
+ optionReg.Add(new OptionDesc(OPTION_STRING_DEFMETAPROC, 0, "default meta processor (developer option)", 0));
+ optionReg.Add(new OptionDesc(OPTION_STRING_HELP, 0, "display help text", 0));
+
+ // parse the command line
+ ArgVars argVars(argc, argv, optionReg);
InputOptions inputOptions;
- // xml parser to parse xml input file
- CHXXmlInputParser* pInputParser = 0;
+ // scan for log option, but do not print syntax errors yet
+ retVal = ParseCommandLineInputOptions(argVars, optionReg, inputOptions, FALSE, FALSE);
- // initialize Helix DNA client media-platform
- HX_RESULT retVal = HXR_OK;
+ // see if we should redirect output to a log file
+ CHXString sLogFilename;
+ InputOption* pOptionLogfile = inputOptions.GetOption(OPTION_STRING_LOGFILE);
+ if(pOptionLogfile)
+ {
+ sLogFilename = pOptionLogfile->GetEffectiveOptionValueCCP();
+ if(!sLogFilename.IsEmpty())
+ {
+ // see if we can actually open the log file before disconnecting from console
+ FILE* fpLog = fopen((const char*)sLogFilename, "a");
+ if(fpLog)
+ {
+ bUsingLog = TRUE;
- // load Helix media-platform library
+ // reopen standard output and standard error in append mode
+ freopen((const char*)sLogFilename, "a", stdout);
+ freopen((const char*)sLogFilename, "a", stderr);
+
+ // we can close our local pointer now
+ fclose(fpLog);
+ fpLog = 0;
+ }
+ else
+ {
+ bFailedToOpenLog = TRUE;
+ }
+ }
+ }
+
+ if(bUsingLog)
+ {
+ // echo current time to log
+ printf("\n========== %s ==========\n\n", (const char*)GetUTCTimeString());
+
+ // echo command line to log
+ argVars.DumpCommandLine();
+ }
+
+ // echo program startup header
+ DisplayProgramInfo();
+
+ // clear results of previous parsing
+ inputOptions.Clear();
+
+ // parse the command line again, this time print errors
+ retVal = ParseCommandLineInputOptions(argVars, optionReg, inputOptions, TRUE, TRUE);
+
+ if(bFailedToOpenLog)
+ {
+ printf("Failed to open log file: [%s]\n\n", (const char*)sLogFilename);
+ }
+
+ if(FAILED(retVal))
+ {
+ goto cleanup;
+ }
+
+ // initialize Helix DNA client media-platform
pDLLAccess = new DLLAccess();
if(!pDLLAccess)
{
retVal = HXR_OUTOFMEMORY;
goto cleanup;
}
// extract plugin directory
#ifdef _WINDOWS
exeFileSpec = CHXFileSpecUtils::GetCurrentApplication();
strncpy(pDllPath, (const char*)exeFileSpec.GetParentDirectory().GetPathName(), _MAX_PATH);
snprintf(pDllFile, _MAX_PATH, "%s\\%s", pDllPath, "hxmedpltfm.dll");
#else
pszHelixPluginPath = getenv(PLUGIN_PATH_ENV_VAR_NAME);
if(pszHelixPluginPath && (strlen(pszHelixPluginPath) > 0))
{
strncpy(pDllPath, pszHelixPluginPath, _MAX_PATH);
snprintf(pDllFile, _MAX_PATH, "%s/%s", pDllPath, "hxmedpltfm.so");
}
else
{
printf("Missing environment variable %s.\n", PLUGIN_PATH_ENV_VAR_NAME);
goto cleanup;
}
#endif
pDllPath[_MAX_PATH - 1] = '\0';
pDllFile[_MAX_PATH - 1] = '\0';
@@ -1681,255 +1870,191 @@
}
// initialize meta-data processor object
pProcessor = new CProcessor(metaProcessorVars);
HX_ADDREF(pProcessor);
if(!pProcessor)
{
retVal = HXR_OUTOFMEMORY;
}
if(FAILED(retVal))
{
printf("Failed to initialize Helix meta-data processor object.\n");
goto cleanup;
}
// initialize meta-data editor plugin
retVal = CreateInstanceCCF_QI(CLSID_IHXMetaDataEditor, IID_IHXMetaDataEditor,
(void**)&pEditor, pCommonClassFactory);
if(SUCCEEDED(retVal))
{
retVal = pEditor->InitMetaDataEditor(pCommonClassFactory);
}
if(FAILED(retVal))
{
printf("Failed to initialize Helix meta-data editor plugin.\n");
goto cleanup;
}
- // create xml parser
+ // initialize xml parser
+ if(SUCCEEDED(retVal))
+ {
+ retVal = HXR_OUTOFMEMORY;
pInputParser = new CHXXmlInputParser();
+
+ if(pInputParser)
+ {
pInputParser->AddRef();
+ retVal = HXR_OK;
+ }
+ }
if(SUCCEEDED(retVal))
{
retVal = pInputParser->Init(pCommonClassFactory);
}
if(FAILED(retVal))
{
- printf("Failed to initialize xml parser.\n");
+ printf("Failed to initialize XML parser.\n");
goto cleanup;
}
- // construct option registry
- optionReg.Add(new OptionDesc(OPTION_STRING_INPUTFILE, "<filename>", "input file", 1, "/albums/album/track/mediaFile/fileName"));
- optionReg.Add(new OptionDesc(OPTION_STRING_OUTPUTFILE, "<filename>", "output file", 1, "/albums/album/track/outputFileName"));
- optionReg.Add(new OptionDesc(OPTION_STRING_XMLINPUTFILE, "<filename>", "xml file with input parameters", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_OVERWRITEFILE, 0, "overwrite output file if it exists", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_CLEARMETADATA, 0, "clear all extracted metadata before injection", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_METASTYLE, "<3GPP | iTunes>", "flavor of injected metadata, default=all", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_UTF16OUTPUT, 0, "inject metadata strings in UTF16 format", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_ID3V240OUTPUT, 0, "inject ID3v2 version 2.4.0, default", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_ID3V230OUTPUT, 0, "inject ID3v2 version 2.3.0", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_ID3V2NOOUTPUT, 0, "skip injecting ID3v2 tag", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_PRINTMETADATA, 0, "print updated metadata", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_EXTRACT, "[filename-prefix]", "save extracted pictures", -1));
- optionReg.Add(new OptionDesc(OPTION_STRING_GENERATEHASH, 0, "generate hash", 0));
- optionReg.Add(new OptionDesc());
- optionReg.Add(new OptionDesc(OPTION_STRING_TITLE, "<string>", "update title", 1, "/albums/album/track/name"));
- optionReg.Add(new OptionDesc(OPTION_STRING_ARTIST, "<string>", "update 3GPP performer, iTunes artist", 1, "/albums/album/track/artist/name"));
- optionReg.Add(new OptionDesc(OPTION_STRING_ALBUM, "<string>", "update album", 1, "/albums/album/name"));
- optionReg.Add(new OptionDesc(OPTION_STRING_GENRE, "<string>", "update genre", 1, "/albums/album/track/style/name"));
- optionReg.Add(new OptionDesc(OPTION_STRING_COMPOSER, "<string>", "update 3GPP author, iTunes composer", 1, "/albums/album/track/artist/composer"));
- optionReg.Add(new OptionDesc(OPTION_STRING_COMMENT, "<string>", "update 3GPP description, iTunes comment", 1, "/albums/album/pline"));
- optionReg.Add(new OptionDesc(OPTION_STRING_COPYRIGHT, "<string>", "update copyright", 1, "/albums/album/cline"));
- optionReg.Add(new OptionDesc(OPTION_STRING_TRACKNUMBER, "<integer 0..255>", "update track number", 1, "/albums/album/track/sequence"));
- optionReg.Add(new OptionDesc(OPTION_STRING_YEAR, "<integer 0..65536>", "update 3GPP recording year, iTunes release date", 1, "/albums/album/OrigReleaseYear"));
- optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_ADD, "<filename>", "add picture", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_REMOVE, "<APIC picture type>", "remove picture", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_PICTURE_CLEAR, 0, "clear all extracted pictures", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_UITS_INSERT, "<filename>", "insert UITS signature from file", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_UITS_EXTRACT, "<filename>", "extract UITS signature into file", 1));
- optionReg.Add(new OptionDesc());
- optionReg.Add(new OptionDesc(OPTION_STRING_SOFTWARE, "<string>", "update iTunes generator tool", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_ENCODEDBY, "<string>", "update iTunes encoded by", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_GROUPING, "<string>", "update iTunes grouping", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_ALBUMARTIST, "<string>", "update iTunes album artist", 1, "/albums/album/artist/name"));
- optionReg.Add(new OptionDesc(OPTION_STRING_LYRICS, "<string>", "update iTunes lyrics", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_SUBTITLE, "<string>", "update iTunes track subtitle", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_BPM, "<integer>", "update iTunes beats per minute", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_PARTOFCOMP, "<0 | 1>", "update iTunes part of compilation", 1, "/albums/album/compilation"));
- optionReg.Add(new OptionDesc(OPTION_STRING_EXPLICIT, "<0 | 1>", "update iTunes content rating", 1, "/albums/album/explicit"));
- optionReg.Add(new OptionDesc(OPTION_STRING_TRACKSTOTAL, "<integer>", "update iTunes track count", 1, "/albums/album/trackCount"));
- optionReg.Add(new OptionDesc(OPTION_STRING_DISKNUMBER, "<integer>", "update iTunes disc number", 1, "/albums/album/track/discNumber"));
- optionReg.Add(new OptionDesc(OPTION_STRING_DISKSTOTAL, "<integer>", "update iTunes disc count", 1, "/albums/album/discCount"));
- optionReg.Add(new OptionDesc());
- optionReg.Add(new OptionDesc(OPTION_STRING_RATING_ENTITY, "<4 character code>", "update 3GPP rating entity", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_RATING_CRITERIA, "<4 character code>", "update 3GPP rating criteria", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_RATING_INFO, "<string>", "update 3GPP rating info", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_ENTITY, "<4 character code>", "update 3GPP classification entity", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_TABLE, "<integer 0..65535>", "update 3GPP classification table", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_CLASSIFICATION_INFO, "<string>", "update 3GPP classification info", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_ADD, "<string>", "add 3GPP keyword", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_REMOVE, "<string>", "remove 3GPP keyword", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_KEYWORD_CLEAR, 0, "clear all extracted 3GPP keywords", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_NAME, "<string>", "update 3GPP location name", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ASTRONOMICAL_BODY, "<string>", "update 3GPP location astronomical body", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ADDITIONAL_NOTES, "<string>", "update 3GPP location notes", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ROLE, "<integer 0..255>", "update 3GPP location role", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_LONGITUDE, "<decimal number>", "update 3GPP location longitude", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_LATITUDE, "<decimal number>", "update 3GPP location latitude", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LOCATION_ALTITUDE, "<decimal number>", "update 3GPP location altitude", 1));
- optionReg.Add(new OptionDesc(OPTION_STRING_LANGUAGE_CODE, "<3 character code>", "ISO639.2/T language code of 3GPP metadata text", 1));
- optionReg.Add(new OptionDesc());
-
-#ifdef _WINDOWS
- optionReg.Add(new OptionDesc(OPTION_STRING_ASYNCMODE, 0, "dtdriver async mode (developer option)", 0));
-#endif //_WINDOWS
-
- optionReg.Add(new OptionDesc(OPTION_STRING_DEFMETAPROC, 0, "default meta processor (developer option)", 0));
- optionReg.Add(new OptionDesc(OPTION_STRING_HELP, 0, "display help text", 0));
-
- {
- // parse command line
- ArgVars argVars(argc, argv, optionReg);
- retVal = ParseCommandLineInputOptions(argVars, optionReg, inputOptions);
-
+ // parse XML input file
if(SUCCEEDED(retVal))
{
InputOption* optionXmlIn = inputOptions.GetOption(CHXString(OPTION_STRING_XMLINPUTFILE));
if(optionXmlIn && !optionXmlIn->OptionValueUTF8.IsEmpty())
{
- // parse xml input file
- if(SUCCEEDED(retVal))
- {
printf("Processing XML input file:\n");
- }
CParsedXmlPairs parsedXmlResults;
optionReg.InitializeXmlPairs(&parsedXmlResults);
retVal = ParseXMLInputOptions(pCommonClassFactory, pInputParser, optionXmlIn, &parsedXmlResults);
if(SUCCEEDED(retVal))
{
// merge parsed results into inputOptions
CHXPtrArray *xmlPairs = parsedXmlResults.GetAllPairs();
for(int i = 0; i < xmlPairs->GetSize(); i++)
{
XmlPair *pair = (XmlPair*)xmlPairs->GetAt(i);
OptionDesc* optDesc = optionReg.GetOptionDescWithPath(pair->xmlPath);
// Add only results of XML file parsing which have non-empty value.
if((optDesc != NULL) && !pair->xmlValueUTF8.IsEmpty())
{
CHXString strName = optDesc->GetOptionString();
InputOption* inOpt = inputOptions.GetOption(strName);
if(inOpt == NULL)
{
inputOptions.Add(new InputOption(strName, EncodedString(), pair->xmlValueUTF8));
}
else
{
inOpt->XmlOptionValueUTF8 = pair->xmlValueUTF8;
}
printf("-%s taken from location [%s], value=[", (const char*)strName, (const char*)pair->xmlPath);
EncStrUtils::PrintTextUTF8(pair->xmlValueUTF8.GetData());
printf("]\n");
}
}
printf("\n");
}
}
}
- }
+ // Process final combination of command-line and XML file input.
// The first phase seeks for independent arguments, the second phase seeks for dependent arguments.
- clpp = CLPP_IndependentOptions;
+ eCommandLineProcessorPhase clpp = CLPP_IndependentOptions;
while(SUCCEEDED(retVal) && (clpp != CLPP_Done))
{
for(inputOptions.ResetPosition(0); SUCCEEDED(retVal) && !inputOptions.ReachedEndPosition();
inputOptions.MovePosition(1))
{
InputOption* option = inputOptions.CurrentOption();
CHXString strOption = option->OptionName;
if(strOption == OPTION_STRING_HELP)
{
bDisplayHelp = TRUE;
}
#ifdef _WINDOWS
else if(strOption == OPTION_STRING_ASYNCMODE)
{
g_bUseDTDriverSynchronousMode = FALSE;
}
#endif //_WINDOWS
else if(strOption == OPTION_STRING_DEFMETAPROC)
{
g_bUseDefaultMetaEditorProcessor = TRUE;
}
+ else if(strOption == OPTION_STRING_LOGFILE)
+ {
+ // do nothing, already processed
+ }
else if(strOption == OPTION_STRING_INPUTFILE)
{
strInputFileName = option->GetEffectiveOptionValueCCP();
}
else if(strOption == OPTION_STRING_OUTPUTFILE)
{
strOutputFileName = option->GetEffectiveOptionValueCCP();
}
else if(strOption == OPTION_STRING_OVERWRITEFILE)
{
bOverwriteFile = TRUE;
}
else if(strOption == OPTION_STRING_CLEARMETADATA)
{
metaProcessorVars.ClearMetaData = TRUE;
}
else if(strOption == OPTION_STRING_PRINTMETADATA)
{
bPrintMetaData = TRUE;
}
else if(strOption == OPTION_STRING_GENERATEHASH)
{
metaProcessorVars.GenerateHash = TRUE;
}
else if(strOption == OPTION_STRING_XMLINPUTFILE)
{
- // do nothing, since it was already done what needs to be done
+ // do nothing, already processed
}
else if(strOption == OPTION_STRING_METASTYLE)
{
strMetaStyleName = option->GetEffectiveOptionValueCCP();
if(clpp == CLPP_IndependentOptions)
{
if(SUCCEEDED(retVal) && !strMetaStyleName.IsEmpty())
{
if(!strMetaStyleName.CompareNoCase("3gpp"))
{
metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_3GPP;
}
else if(!strMetaStyleName.CompareNoCase("itunes"))
{
metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_ITUNES;
}
else
{
retVal = HXR_PARSE_ERROR;
ReportInvalidValueForOption(OPTION_STRING_METASTYLE, option->GetEffectiveOptionValueUTF8());
}
}
}
}
else if(strOption == OPTION_STRING_UTF16OUTPUT)
{
bUTF16Output = TRUE;
}
else if(strOption == OPTION_STRING_ID3V240OUTPUT)