search.h

Go to the documentation of this file.
00001 /**
00002  *  Copyright (C) 2004-2005 Alo Sarv <madcat_@users.sourceforge.net>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 /** @file search.h Interface for Searching API */
00020 
00021 #ifndef __SEARCH_H__
00022 #define __SEARCH_H__
00023 
00024 #include <hn/osdep.h>
00025 #include <hn/hnfwd.h>
00026 #include <boost/shared_ptr.hpp>
00027 #include <boost/enable_shared_from_this.hpp>
00028 #include <boost/function.hpp>
00029 #include <boost/signal.hpp>
00030 
00031 /**
00032  * Search result encapsualtes a single result from a search. It is-a MetaData,
00033  * and inherits all the properties of MetaData object. This provides maximum
00034  * extedability in search results, since they can contain ALL kinds of meta
00035  * data supported by the MetaData and member structures.
00036  */
00037 class DLLEXPORT SearchResult {
00038 public:
00039         SearchResult(const std::string &name, uint64_t fileSize);
00040         virtual ~SearchResult();
00041 
00042         /**
00043          * Download this search result. Must be overridden by derived classes,
00044          * e.g. the module providing this search result, since only that module
00045          * can safely start the download.
00046          */
00047         virtual void download() = 0;
00048 
00049         //! @name Accessors
00050         //@{
00051         void addSources(uint32_t amount)  { m_sources += amount;  }
00052         void addComplete(uint32_t amount) { m_complete += amount; }
00053         uint32_t    getSources()    const { return m_sources;     }
00054         uint32_t    getComplete()   const { return m_complete;    }
00055         std::string getName()       const { return m_fileName;    }
00056         uint64_t    getSize()       const { return m_fileSize;    }
00057         boost::shared_ptr<AudioMetaData>&   getAmd()  { return m_amd;  }
00058         boost::shared_ptr<VideoMetaData>&   getVmd()  { return m_vmd;  }
00059         boost::shared_ptr<ArchiveMetaData>& getArmd() { return m_armd; }
00060         boost::shared_ptr<ImageMetaData>&   getImd()  { return m_imd;  }
00061         boost::shared_ptr<StreamData>&      getStrd() { return m_strd; }
00062         //@}
00063 private:
00064         SearchResult();                                   //!< Forbidden
00065         SearchResult(const SearchResult&);                //!< Forbidden
00066         SearchResult& operator=(const SearchResult&);     //!< Forbidden
00067 
00068         std::string m_fileName; //!< Name of the file
00069         uint64_t m_fileSize;    //!< Size of the file
00070         uint32_t m_sources;     //!< Number of sources
00071         uint32_t m_complete;    //!< Number of complete sources
00072 
00073         //! @name Various MetaData received from search results
00074         //@{
00075         boost::shared_ptr<AudioMetaData>   m_amd;
00076         boost::shared_ptr<VideoMetaData>   m_vmd;
00077         boost::shared_ptr<ArchiveMetaData> m_armd;
00078         boost::shared_ptr<ImageMetaData>   m_imd;
00079         boost::shared_ptr<StreamData>      m_strd;
00080         //@}
00081 };
00082 
00083 /**
00084  * Search class represents one search sent to one or more modules for
00085  * processing, emitting events when new results are added, which the original
00086  * request creator can then handle.
00087  *
00088  * The basic usage of this object evolves around constructing the object on
00089  * heap, but within boost::shared_ptr, then customizing the search by
00090  * adding terms and setting other limits, and then passing the pointer to
00091  * Search::run() static function, which then sends the object to all search
00092  * handlers.
00093  *
00094  * Modules wishing to support searching may register their search handler
00095  * method using addHandler() member function (Note: EventTable class also
00096  * defines a function with same name, however that one is accessible through
00097  * getEventTable() member function, as defined by Event Handling API). When
00098  * new search is performed, all handler functions are notified about the search,
00099  * and can thus perform module-dependant searching procedure, adding results
00100  * and posting events.
00101  *
00102  * Module developers: When you are adding many results at once to a Search
00103  * object, do not post a new event after each addition. Instead, post event
00104  * after all results that are available to that moment have been added to this
00105  * object. This is needed to save event's processing overhead, as well as
00106  * processing overhead at target search client.
00107  */
00108 class DLLEXPORT Search : public boost::enable_shared_from_this<Search> {
00109 public:
00110         /**
00111          * Construct empty search. The object should later be customized by
00112          * by adding terms and limitations to the search, before run()'ing it.
00113          */
00114         Search();
00115 
00116         /**
00117          * Construct a new search object. This should  be called by client code
00118          * which wishes to perform the search.
00119          *
00120          * @param terms         Search terms, separated by spaces
00121          */
00122         Search(const std::string &terms);
00123 
00124         /**
00125          * Execute the search. Call this method after setting up event handlers
00126          * for results.
00127          *
00128          * @param search           Search to be run.
00129          */
00130         void run();
00131 
00132         /**
00133          * Add a new search. This is used by search handlers to append new
00134          * search results to the object.
00135          *
00136          * @param result           Search result to be added.
00137          */
00138         void addResult(SearchResultPtr result);
00139 
00140         /**
00141          * Add a search query handler, which shall be called whenever someone
00142          * runs a new search. It is recommended that the object is set up
00143          * using boost::connection::trackable to automate the removal process.
00144          */
00145         static void addQueryHandler(SearchHandler handler);
00146 
00147         /**
00148          * Set up a results handler, which shall be notified whenever someone
00149          * adds new results to this search. Note that the actual notification
00150          * is done on demand by the results adder via notifyResults() method,
00151          * not whenever a new result is added to the query. This is done to
00152          * avoid excessive function calls when adding many results at same time.
00153          */
00154         void addResultHandler(SearchHandler handler);
00155 
00156         /**
00157          * Add a handler for links to be downloaded. A link is defined as any
00158          * string. It may be a ed2k://, http://, ftp:// links, but it may also
00159          * be a full path to a local file for example - it's up to the modules
00160          * to decide what they can (or cannot) accept as "download starter"
00161          * string.
00162          */
00163         static void addLinkHandler(LinkHandler handler);
00164 
00165         /**
00166          * Start a direct download from link. The passed here is sent to all
00167          * link handlers. The handler handling the download will return true,
00168          * others return false.
00169          */
00170         static void downloadLink(const std::string &link);
00171 
00172         /**
00173          * Notify all results handlers that there are new results added to this
00174          * search query.
00175          */
00176         void notifyResults();
00177 
00178         //! @name Accessors for various internal structures
00179         //@{
00180         uint32_t    getTermCount()           const { return m_terms.size();    }
00181         std::string getTerm(uint32_t num)    const { return m_terms.at(num);   }
00182         uint32_t    getResultCount()         const { return m_results.size();  }
00183         uint64_t    getMinSize()             const { return m_minSize;         }
00184         uint64_t    getMaxSize()             const { return m_maxSize;         }
00185         FileType    getType()                const { return m_type;            }
00186         SearchResultPtr getResult(uint32_t num) const {
00187                  return m_results.at(num);
00188         }
00189         //@}
00190 
00191         //! @name Setters
00192         //@{
00193         void addTerm(const std::string &term)       { m_terms.push_back(term); }
00194         void setMinSize(uint64_t size)                  { m_minSize = size;    }
00195         void setMaxSize(uint64_t size)                  { m_maxSize = size;    }
00196         void setType(FileType type)                     { m_type = type;       }
00197         //@}
00198 private:
00199         // Internal data
00200         // -------------
00201 
00202         //! Vector which will be filled by search handlers using addResult()
00203         //! method.
00204         std::vector<SearchResultPtr> m_results;
00205         std::vector<std::string> m_terms;         //!< Terms to search for
00206         uint64_t m_minSize;                       //!< Minimum file size
00207         uint64_t m_maxSize;                       //!< Maximum file size
00208         FileType m_type;                          //!< File type
00209 
00210         // Notification mechanisms
00211         // -----------------------
00212 
00213         /**
00214          * This signal is fired whenever a new search query is started. Modules
00215          * must connect their handlers to this signal to receive search query
00216          * notifications.
00217          */
00218         static boost::signal<void (SearchPtr)> s_sigQuery;
00219 
00220         /**
00221          * This signal is fired when new results are added to an existing
00222          * search. This is fired by Search object in addResult method.
00223          */
00224         boost::signal<void (SearchPtr)> m_sigResult;
00225 
00226         /**
00227          * Handlers for text-based link downloadings.
00228          */
00229         static std::vector<LinkHandler> s_linkHandlers;
00230 };
00231 
00232 #endif