interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/home/tetron/hack/vos/libs/vos/vutil/typehelper.hh

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project (http://interreality.org).
00004 
00005     Copyright (C) 2001-2003 Peter Amstutz <http://www.interreality.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 */
00021 
00022 #ifndef _TYPEHELPER_HH_
00023 #define _TYPEHELPER_HH_
00024 
00025 #include <vos/vutil/vutildefs.hh>
00026 
00027 #include <list>
00028 #include <deque>
00029 #include <set>
00030 #include <string>
00031 #include <stdexcept>
00032 
00033 /**
00034  * @defgroup libtypehelper libtypehelper
00035  *  Portable Type Helper-Application Abstraction Library
00036  */
00037 
00038 /** Use a subclass of this class to specify action performed when a running
00039  * helper process ends by passing an instance to TypeHeler::addProcessEndCallback().
00040  * @ingroup libtypehelper
00041  */
00042 class VUTIL_API ProcessEndCallback
00043 {
00044 public:
00045     virtual ~ProcessEndCallback() { }
00046     /// Override this method.
00047     virtual void notifyProcessTerminate(int pid) = 0;
00048 };
00049 
00050 /** A ProcessEndCallback that deletes a file when called.
00051  * @ingroup libtypehelper
00052  */
00053 class VUTIL_API DeleteTempFile : public ProcessEndCallback
00054 {
00055 private:
00056     std::string file;
00057     std::set<int>* other_pids;
00058 public:
00059     /** Deletes a file when called back.
00060      * @param f     The name of the file to delete.
00061      */
00062     DeleteTempFile(const std::string& f);
00063 
00064     /** Removes the PID for the helper associated with this callback from
00065      * the given set of PIDs. If that set is then empty, then the file
00066      * is deleted and the PID set is freed from the heap.
00067      * Use a new instance of DeleteTempFile for each process, and pass each of
00068      * them a pointer to the PID set.
00069      * @param f         File to delete when the PID set becomes empty.
00070      * @param pidset    The PID set. If NULL, then behavior will be as described
00071      *                  in DeleteTempFile(const std::string&).
00072      */
00073     DeleteTempFile(const std::string& f, std::set<int>* pidset);
00074 
00075     virtual ~DeleteTempFile();
00076     virtual void notifyProcessTerminate(int pid);
00077 };
00078 
00079 /** @class TypeHelper typehelper.hh typehelper/typehelper.hh
00080   * @ingroup libtypehelper
00081   *
00082   * This class represents a helper program.  It also contains static
00083   * information on all type helpers, which you can access with
00084   * findVobjectHelpers, findDataHelpers, addHelper, etc.
00085   *
00086   * This utility does not require VOS, but it includes special features
00087   * to facilitate VOS applications.
00088   */
00089 class VUTIL_API TypeHelper {
00090 public:
00091     typedef enum { DATA, VOBJECT } RunFunc;
00092 
00093 private:
00094     std::string type;
00095     std::deque<std::string> parameters;
00096     std::string target;
00097     RunFunc runFunc;
00098 
00099 public:
00100 
00101     /** Create a new typehelper for Data with no associated type identifier */
00102     TypeHelper() :
00103         runFunc(DATA)
00104     { }
00105 
00106     /** Create a new typehelper for Data with the givent type identifier */
00107     TypeHelper(std::string init_type) :
00108         type(init_type),
00109         runFunc(DATA)
00110     { }
00111 
00112     /** Create a new typehelper
00113         @param init_type    Type of data or Vobject
00114         @param vobject_or_data  DATA or VOBJECT
00115         @param init_target       Temporary file if DATA, URL if VOBJECT.
00116     */
00117     TypeHelper(std::string init_type, RunFunc vobject_or_data, std::string init_target ) :
00118         type(init_type),
00119         target(init_target),
00120         runFunc(vobject_or_data)
00121     { }
00122 
00123 
00124     /** Load helpers configuration from a config file.
00125         @param filename Name of the configuration file
00126         @todo load multiple filenames, including a default
00127              ~/.typehelpers.cfg and INSTALL_DIR/etc/typehelpers.cfg
00128             as well as the given filename.
00129         @throw std::runtime_error if there is an error opening the file
00130     */
00131     static void init(std::string filename);
00132 
00133     /** Find helpers that can handle a VOS Vobject with one of the given types.
00134         @return List of helpers, in the order in which they were found
00135                 in configuration files.
00136         @param types If a helper is known that can handle one of these types,
00137                 it is added to the return set.
00138         @param objpath URL to pass to the helper when run.
00139     */
00140     static std::deque<TypeHelper> findVobjectHelpers(const std::set<std::string>& types,
00141 const std::string& objpath);
00142 
00143     /** Find helpers that can handle data with the given type. Typically
00144       * this is a MIME type (e.g. "audio/mpeg").  Information loaded from
00145       * a config file by init() will be used, as well as Gnome handlers
00146       * if libtypehelper was linked against Gnome libraries.
00147 
00148         @return List of matching helpers, in the order in which they were
00149                 found in configuration files and platform config.
00150         @param type Type identifier, typically a MIME type.
00151         @param tempfile Name of a file to use for temporary storage, if
00152                 one of the matching helpers needs one. (
00153         @todo make tempfile optional and figure out our own according to
00154                 platform policies
00155     */
00156     static std::deque<TypeHelper> findDataHelpers(const std::string& type, const
00157 std::string& tempfile);
00158 
00159     /** Add a helper to the static list of helpers.
00160         @param configline A string in one of these 2 forms:
00161             <ul>
00162                 <li>For "Data" helpers: <code>data(</code>type<code>) = </code> command</li>
00163                 <li>For "Vobject helpers: <code>vobject(</code>type<code>) = </code> command</li>
00164             </ul>
00165 
00166             You can use the following special character sequences in <i>command</i>:
00167             <dl>
00168                 <dt><code>%f</code></dt>
00169                     <dd>(Data helpers only) Make a temporary file, and replace <code>%f</code> with its name</dd>
00170                 <dt><code>%d</code></dt>
00171                     <dd>(Data helpers only) Replace <code>%d</code> with the data.</dd>
00172                 <dt><code>%u</code></dt>
00173                     <dd>(Vobject helpers only) Replace <code>%u</code> with the URL of the starting object.</dd>
00174             </dl>
00175     */
00176     static void addHelper(const std::string& configline);
00177 
00178     /** When checkProcesses sees that a process has ended, call
00179         the supplied callback function.
00180         @see removeProcessEndCallback
00181         @see checkProcesses
00182     */
00183     static void addProcessEndCallback(int pid, ProcessEndCallback* pec);
00184 
00185     /** Remove a process-end callback.
00186         @see addProcessEndCallback
00187     */
00188     static void removeProcessEndCallback(int pid, ProcessEndCallback* pec);
00189 
00190     /** If a process associated with a process-end callback has ended,
00191         then call the callback and remove the callback.
00192         @see addProcessEndCallback
00193     */
00194     static void checkProcesses();
00195 
00196     /** What is the type for this helper? */
00197     std::string getType() { return type; }
00198 
00199     /** What are the command-line paramaters that will be passed to this
00200         helper?
00201     */
00202     const std::deque<std::string>& getParameters() { return parameters; }
00203 
00204     /** What is the full command line that will be run
00205         for this helper?
00206     */
00207     std::string getCommand();
00208 
00209     /** Run this helper.
00210         @return PID (Process ID) of the child process.
00211     */
00212     int run();
00213 
00214     /** Set the type for this helper */
00215     void setType(std::string t) { type = t; }
00216 
00217     /** Set the individual command-line parameters for this helper.
00218         params[0] is the command to run, etc. */
00219     void setParameters(std::deque<std::string> params) { parameters = params; }
00220 
00221     /** Set the full command line for this helper: it will be broken into
00222         individual arguments on spaces and tabs.
00223     */
00224     void setCommand(const std::string& cmd);
00225 };
00226 
00227 
00228 #endif