sharedfile.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 sharedfile.h Interface for SharedFile class */
00020 
00021 #ifndef __SHAREDFILE_H__
00022 #define __SHAREDFILE_H__
00023 
00024 #include <hn/event.h>
00025 #include <hn/object.h>
00026 #include <hn/hasher.h>
00027 #include <set>
00028 #include <iosfwd>
00029 #include <boost/filesystem/path.hpp>
00030 #include <boost/weak_ptr.hpp>
00031 
00032 //! Events emitted from SharedFile objects
00033 enum SFEvent {
00034         SF_DESTROY = 0, //!< Posted whenever SharedFile is about to be destroyed
00035         SF_ADDED,       //!< Posted whenever new SharedFile is constructed
00036         SF_METADATA_ADDED  //!< Posted whenever metadata is added to SharedFile
00037 };
00038 
00039 class MetaData;
00040 class PartData;
00041 class MoveWork;
00042 typedef boost::shared_ptr<MoveWork> MoveWorkPtr;
00043 
00044 /**
00045  * SharedFile object represents a file which is currently being shared. It may
00046  * be partial or complete or completely empty. SharedFile objects are owned by
00047  * FilesList class - the destructor of SharedFile has been protected to avoid
00048  * unwanted deletion of SharedFile objects.
00049  */
00050 class DLLEXPORT SharedFile : public Object, public Trackable {
00051 public:
00052         DECLARE_EVENT_TABLE(SharedFile*, int);
00053 
00054         /**
00055          * Construct SharedFile object.
00056          *
00057          * @param location    Location of the physical file.
00058          * @param metaData    Optional MetaData pointer corresponding to this
00059          *                    SharedFile object.
00060          */
00061         SharedFile(boost::filesystem::path location, MetaData *metaData = 0);
00062 
00063         /**
00064          * Construct SharedFile from existing PartData.
00065          *
00066          * @param partData    Pointer to PartData object.
00067          * @param metaData    Optional pointer to MetaData object.
00068          */
00069         SharedFile(PartData *partData, MetaData *metaData = 0);
00070 
00071         //! @name Accessors
00072         //@{
00073         std::string getLocation() const {
00074                 return m_location.branch_path().string();
00075         }
00076         std::string getName()             const;
00077         boost::filesystem::path getPath() const { return m_location; }
00078         MetaData* getMetaData()           const { return m_metaData; }
00079         PartData* getPartData()           const { return m_partData; }
00080         uint64_t getUploaded()            const { return m_uploaded; }
00081         uint64_t getSize()                const { return m_size;     }
00082         bool hasMetaData()                const { return m_metaData; }
00083         bool isComplete() const;
00084         bool isPartial()  const;
00085         //@}
00086 
00087         //! @name Setters
00088         //@{
00089         void setMetaData(MetaData *md);
00090         void setPartData(PartData *pd);
00091         void addUploaded(uint64_t sum)                    { m_uploaded += sum; }
00092         //@}
00093 
00094         //! Schedule for destruction
00095         void destroy();
00096 
00097         //! Order the SharedFile to re-check the integrity of the physical file,
00098         //! and up2date metadata.
00099         void verify();
00100 
00101         /**
00102          * Read data from disk from location and return it.
00103          *
00104          * @param begin   Begin offset where to start reading
00105          * @param end     End offset where to stop reading (included)
00106          * @return        Data buffer of the read data
00107          */
00108         std::string read(uint64_t begin, uint64_t end);
00109 private:
00110         friend class FilesList;
00111         ~SharedFile();                             //!< Allowed by FilesList
00112         SharedFile();                              //!< Forbidden
00113         SharedFile(SharedFile &);                  //!< Forbidden
00114         SharedFile& operator=(const SharedFile &); //!< Forbidden
00115 
00116         /**
00117          * Locate MetaData for a file.
00118          *
00119          * @param loc        Path to file to inspect.
00120          * @param name       Name of the file (useful if dealing with tmp files)
00121          * @param pd         If set, indicates that we'r dealing with a partial
00122          *                   file, thus the size on the disk cannot be trusted,
00123          *                   and filesize should be retrieved from PartData
00124          *                   object instead.
00125          * @return           MetaData object found. May be null if not found.
00126          */
00127         static MetaData* findMetaData(
00128                 boost::filesystem::path loc, const std::string &name,
00129                 PartData *pd = 0
00130         );
00131 
00132         //! Event handler for PartData events
00133         void onPartEvent(PartData *pd, int evt);
00134 
00135         //! Event handler for file moving events
00136         void onMoveEvent(MoveWorkPtr ptr, int evt);
00137 
00138         /**
00139          * Verifies our current m_fileSize against what is stored in MetaData.
00140          *
00141          * @param md      Pointer to MetaData to verify against. May not be NULL
00142          *
00143          * Preconditions: m_location points to current file location
00144          *                m_filesize is set to correct file size.
00145          * Sideeffects:   md->filesize may be modified/fixed if it does not
00146          *                match the actual file size.
00147          */
00148         void checkFileSize(MetaData *md);
00149 
00150         //! Event handler for hash events
00151         void onHashEvent(boost::shared_ptr<HashWork> hw, HashEvent evt);
00152 
00153         //! Updates the files modification date that is stored in MetaDb
00154         void updateModDate();
00155 
00156         /**
00157          * \brief Check if there are any other SharedFiles which match the
00158          *        specs of this file.
00159          *
00160          * @return True if a duplicate was found, and handled appropriately,
00161          *         false otherwise.
00162          *
00163          * Note that the behaviour when duplicate is found is to destroy this
00164          * one, not the duplicate.
00165          */
00166         bool isDuplicate();
00167 
00168         /**
00169          * \brief Change the location for this file
00170          *
00171          * @param loc       New location
00172          *
00173          * \note If m_metaData is non-zero, this also updates modification date
00174          *       in m_metaData object.
00175          */
00176         void setLocation(const boost::filesystem::path &loc);
00177 
00178         /**
00179          * \brief Add an alternative location.
00180          *
00181          * @param loc       New location
00182          *
00183          * This can be used when we detect an identical file shared from
00184          * multiple folders.
00185          */
00186         void addLocation(const boost::filesystem::path &loc);
00187 
00188         boost::filesystem::path m_location;   //!< (primary) Physical location
00189         MetaData *m_metaData;                      //!< May be null
00190         PartData *m_partData;                      //!< May be null
00191         uint64_t m_uploaded;                       //!< Amount uploaded
00192         uint64_t m_size;                           //!< Size of file
00193         friend std::ostream& operator<<(std::ostream &o, const SharedFile &sf);
00194         boost::weak_ptr<HashWork> m_pendingJob;    //!< Pending job (if any)
00195 
00196         //! If we have PartData, this is connected to PartData events
00197         boost::signals::connection m_pdSigHandler;
00198 
00199         //! Vector of alternative locations, with timestamps
00200         std::vector<std::pair<uint32_t, boost::filesystem::path> > m_locations;
00201 
00202 };
00203 
00204 #endif