1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //  The contents of this file are subject to the Mozilla Public License
4 //  Version 1.1 (the "License"); you may not use this file except in
5 //  compliance with the License. You may obtain a copy of the License at
6 //  http://www.mozilla.org/MPL/
7 //
8 //  Software distributed under the License is distributed on an "AS IS"
9 //  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10 //  License for the specific language governing rights and limitations
11 //  under the License.
12 //
13 //  The Original Code is MP4v2.
14 //
15 //  The Initial Developer of the Original Code is Kona Blend.
16 //  Portions created by Kona Blend are Copyright (C) 2008.
17 //  All Rights Reserved.
18 //
19 //  Contributors:
20 //      Kona Blend, kona8lend@@gmail.com
21 //
22 ///////////////////////////////////////////////////////////////////////////////
23 
24 #ifndef MP4V2_UTIL_UTILITY_H
25 #define MP4V2_UTIL_UTILITY_H
26 
27 namespace mp4v2 { namespace util {
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 ///
31 /// Utility general program class.
32 ///
33 /// This class provides a base implementation for a general utility which
34 /// helps meet behavioral criteria for command-line executables.
35 ///
36 /// Inherit batch processing ability is also provided and is used optionally
37 /// by the concrete implementation.
38 ///
39 /// Criteria and guidelines for utility behavior in MP4v2 are as follows:
40 ///     @li exit with 0 when the utility succeeds at its main task, 1 for failure.
41 ///     @li print brief-usage when no arguments are supplied and exit with 1.
42 ///     @li print brief-usage when too many arguments are supplied and exit with 1.
43 ///     @li issue brief-usage when invalid argument is supplied and exit with 1.
44 ///     @li support --help option and exit with 0.
45 ///     @li support --version option and exit with 0.
46 ///     @li utilities which <b>create</b> new output files should never
47 ///         over-write an existing file unless given the project's universal
48 ///         '-o' or '--overwrite' option.
49 ///
50 ///////////////////////////////////////////////////////////////////////////////
51 class MP4V2_EXPORT Utility
52 {
53 protected:
54     enum LongCode {
55         LC_NONE = 0xf0000000, // safe (cannot conflict with char values)
56         LC_DEBUG,
57         LC_VERBOSE,
58         LC_HELP,
59         LC_VERSION,
60         LC_VERSIONX,
61         _LC_MAX // will be used to seeed derived-class long-codes enum
62     };
63 
64     class MP4V2_EXPORT Option {
65     public:
66         Option( char, bool, string, bool, uint32_t, string, string = "ARG", string = "", bool = false );
67 
68         const char     scode;
69         const bool     shasarg;
70         const string   lname;
71         const bool     lhasarg;
72         const uint32_t lcode;
73         const string   descr;
74         const string   argname;
75         const string   help;
76         const bool     hidden;
77     };
78 
79     class MP4V2_EXPORT Group {
80     public:
81         explicit Group( string );
82         ~Group();
83 
84         void add( const Option& ); // options added this way will not be deleted
85         void add( char, bool, string, bool, uint32_t, string, string = "ARG", string = "", bool = false );
86         void add( string, bool, uint32_t, string, string = "ARG", string = "", bool = false );
87 
88         const string name;
89 
90     public:
91         typedef list<const Option*> List;
92 
93     private:
94         List _options;
95         List _optionsDelete;
96 
97     public:
98         const List& options;
99     };
100 
101     //! structure passed as argument to each job during batch processing
102     class MP4V2_EXPORT JobContext
103     {
104     public:
105         JobContext( string file_ );
106 
107         const string  file;               //!< file job is working on
108         MP4FileHandle fileHandle;         //!< handle of file, if applicable to job
109         bool          optimizeApplicable; //!< indicate file optimization is applicable
110         list<void*>   tofree;             //!< memory to free at end of job
111     };
112 
113 public:
114     virtual ~Utility();
115 
116     bool process();
117 
118 protected:
119     Utility( string, int, char** );
120 
121     void printUsage   ( bool );       //!< print usage
122     void printHelp    ( bool, bool ); //!< print help
123     void printVersion ( bool );       //!< print utility version
124 
125     void errf ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3); //!< print to stderr
126     void outf ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3); //!< print to stdout
127 
128     bool herrf  ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3); //!< print to stderr indicating error
129     bool hwarnf ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3); //!< print to stderr indicating warning
130 
131     void verbose1f ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3);
132     void verbose2f ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3);
133     void verbose3f ( const char*, ... ) MP4V2_WFORMAT_PRINTF(2,3);
134 
135     bool batch ( int );    //!< process all remaining arguments (jobs)
136     bool job   ( string ); //!< process next argument
137 
138     //! open file in consideration of overwrite/force options
139     bool openFileForWriting( io::File& );
140 
141     bool dryrunAbort();
142 
143     // delegates
144     virtual bool utility_option( int, bool& ) = 0; //!< process command-line option
145     virtual bool utility_job( JobContext& )   = 0; //!< process positional argument
146 
147 private:
148     void formatGroups();
149     void debugUpdate( uint32_t );
150     void verbose( uint32_t, const char*, va_list );
151     bool process_impl();
152 
153 private:
154     string _help;
155 
156     prog::Option* _longOptions;
157     string        _shortOptions;
158 
159 protected:
160     const string       _name; //!< executable basename
161     const int          _argc; //!< arg count
162     char* const* const _argv; //!< arg vector
163 
164     // common options state
165     bool     _optimize;  //!< optimize mp4 file after modification
166     bool     _dryrun;    //!< dry-run, no writing is actually performed
167     bool     _keepgoing; //!< contine batch processing even after error
168     bool     _overwrite; //!< overwrite file if already exists
169     bool     _force;     //!< force overwriting a file even if read-only
170     uint32_t _debug;     //!< mp4 file I/O verbosity
171     uint32_t _verbosity; //!< verbosity level, default=1
172 
173     uint32_t          _jobCount;
174     uint32_t          _jobTotal;
175     bool              _debugImplicits;
176 
177     Group         _group; // group to which standard options are added
178     string        _usage;
179     string        _description;
180     list<Group*>  _groups;
181 
182 protected:
183     // standard options for concrete utilities to add to _group in constructor
184     const Option STD_OPTIMIZE;
185     const Option STD_DRYRUN;
186     const Option STD_KEEPGOING;
187     const Option STD_OVERWRITE;
188     const Option STD_FORCE;
189     const Option STD_QUIET;
190     const Option STD_DEBUG;
191     const Option STD_VERBOSE;
192     const Option STD_HELP;
193     const Option STD_VERSION;
194     const Option STD_VERSIONX;
195 
196 public:
197     static const bool SUCCESS;
198     static const bool FAILURE;
199 };
200 
201 ///////////////////////////////////////////////////////////////////////////////
202 
203 }} // namespace mp4v2::util
204 
205 #endif // MP4V2_UTIL_UTILITY_H
206