metadata.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 /**
00020  * \file metadata.h Interface for various MetaData structurs
00021  */
00022 
00023 #ifndef __METADATA_H__
00024 #define __METADATA_H__
00025 
00026 #include <hn/osdep.h>
00027 #include <hn/utils.h>
00028 #include <hn/event.h>
00029 #include <hn/hnfwd.h>
00030 #include <iostream>
00031 #include <set>
00032 #include <string>
00033 
00034 //! Object describing an audio/video stream.
00035 class DLLEXPORT StreamData {
00036 public:
00037         //! Default constructor
00038         StreamData();
00039 
00040         //! Construct with pre-set values
00041         StreamData(const std::string &codec, uint32_t bitrate, uint32_t len =0);
00042 
00043         //! Load from input stream
00044         StreamData(std::istream &i);
00045 
00046         //! Destructor
00047         ~StreamData();
00048 
00049         /**
00050          * @name Setters
00051          */
00052         //@{
00053         void setBitrate(uint32_t bitrate)       { m_bitrate = bitrate; }
00054         void setCodec(const std::string &codec) { m_codec = codec;     }
00055         //@}
00056 
00057         /**
00058          * @name Getters
00059          */
00060         //@{
00061         uint32_t    getBitrate() const { return m_bitrate; }
00062         std::string getCodec()   const { return m_codec;   }
00063         //@}
00064 private:
00065         uint32_t    m_bitrate;       //!< Bitrate
00066         std::string m_codec;         //!< Codec used
00067         uint32_t    m_length;        //!< Length of stream
00068 
00069         //! Output operator for streams
00070         friend std::ostream& operator<<(
00071                 std::ostream &o, const StreamData &s
00072         );
00073 };
00074 
00075 namespace CGComm {
00076         //! VideoMetaData opcodes
00077         enum VMDOpCodes {
00078                 OP_VMD           = 0x40, //!<                  VideoMetaData
00079                 OP_VMD_RUNTIME   = 0x41, //!< <uint32>         Runtime
00080                 OP_VMD_FRAMES    = 0x42, //!< <uint32>         Frame count
00081                 OP_VMD_FRAMERATE = 0x43, //!< <float>          Frame rate (fps)
00082                 OP_VMD_FRAMESIZE = 0x44, //!< <uint32><uint32> Frame size
00083                 OP_VMD_SUBTITLES = 0x45, //!< <uint16>         Subtitle count
00084                 OP_VMD_VIDSTREAM = 0x46, //!< <StreamData>     Video stream
00085                 OP_VMD_AUDSTREAM = 0x47  //!< <StreamData>     Audio stream
00086         };
00087 }
00088 
00089 //! Video meta data
00090 class DLLEXPORT VideoMetaData {
00091 public:
00092         VideoMetaData();                            //!< Default constructor
00093         VideoMetaData(std::istream&);               //!< Construct & load
00094 
00095         /**
00096          * @name Setters
00097          */
00098         //@{
00099         void setRunTime(uint32_t runtime)     { m_runtime = runtime;     }
00100         void setFrameCount(uint32_t frames)   { m_frames = frames;       }
00101         void setFrameRate(float framerate)    { m_framerate = framerate; }
00102         void setSubtitleCount(uint32_t count) { m_subtitles = count;     }
00103         void setFrameSize(uint32_t width, uint32_t height) {
00104                 m_framesize.first = width;
00105                 m_framesize.second = height;
00106         }
00107         void addVideoStream(const char *codec, uint32_t bitrate) {
00108                 m_vidData.push_back(StreamData(codec, bitrate));
00109         }
00110         void addAudioStream(const char *codec, uint32_t bitrate) {
00111                 m_audData.push_back(StreamData(codec, bitrate));
00112         }
00113         //@}
00114 
00115         /**
00116          * @name Getters
00117          */
00118         //@{
00119         uint32_t getRunTime()          const { return m_runtime;        }
00120         uint32_t getFrameCount()       const { return m_frames;         }
00121         float    getFrameRate()        const { return m_framerate;      }
00122         uint32_t getVideoStreamCount() const { return m_vidData.size(); }
00123         uint32_t getAudioStreamCount() const { return m_audData.size(); }
00124         uint32_t getSubtitleCount()    const { return m_subtitles;      }
00125         std::pair<uint32_t, uint32_t> getFrameSize() const {
00126                 return m_framesize;
00127         }
00128         /**
00129          * Retrieve a specific stream. Note: Stream counting starts from 0.
00130          */
00131         StreamData getVideoStream(uint32_t num) const {
00132                 assert(num <= m_vidData.size());
00133                 return m_vidData.at(num);
00134         }
00135         /**
00136          * Retrieve a specific stream. Note: Stream counting starts from 0.
00137          */
00138         StreamData getAudioStream(uint32_t num) const {
00139                 assert(num <= m_audData.size());
00140                 return m_audData.at(num);
00141         }
00142         //@}
00143 private:
00144         friend class MetaData;
00145         ~VideoMetaData();                           //!< Allowed by MetaData
00146         VideoMetaData(const VideoMetaData&);            //!< Forbidden
00147         VideoMetaData& operator=(const VideoMetaData&); //!< Forbidden
00148 
00149         typedef std::vector<StreamData>::iterator SIter;
00150         typedef std::vector<StreamData>::const_iterator CSIter;
00151 
00152         uint32_t m_runtime;                         //!< Length of movie
00153         uint32_t m_frames;                          //!< Total number of frames
00154         float m_framerate;                          //!< frames-per-second
00155         std::pair<uint32_t, uint32_t> m_framesize;  //!< Size of a frame
00156         std::vector<StreamData> m_vidData;          //!< Video streams data
00157         std::vector<StreamData> m_audData;          //!< Audio streams data
00158         uint32_t m_subtitles;                       //!< Number of subtitles
00159 
00160         //! Output operator for streams
00161         friend std::ostream& operator<<(
00162                 std::ostream &o, const VideoMetaData &vmd
00163         );
00164 
00165         //! In testsuite
00166         friend void test_videodata();
00167 };
00168 
00169 namespace CGComm {
00170         //! AudioMetaData opcodes
00171         enum AMD_OpCodes {
00172                 OP_AMD            = 0x20,         //!<          AudioMetaData
00173                 OP_AMD_TITLE      = 0x21,         //!< <string> Title
00174                 OP_AMD_ARTIST     = 0x22,         //!< <string> Artist
00175                 OP_AMD_ALBUM      = 0x23,         //!< <string> Album
00176                 OP_AMD_GENRE      = 0x24,         //!< <string> Genre
00177                 OP_AMD_COMMENT    = 0x25,         //!< <string> Comment
00178                 OP_AMD_COMPOSER   = 0x26,         //!< <string> Composer
00179                 OP_AMD_ORIGARTIST = 0x27,         //!< <string> Original artist
00180                 OP_AMD_COPYRIGHT  = 0x28,         //!< <string> Copyright
00181                 OP_AMD_URL        = 0x29,         //!< <string> Web URL
00182                 OP_AMD_ENCODED    = 0x2a,         //!< <string> Encoded
00183                 OP_AMD_YEAR       = 0x2b          //!< <uint16> Year
00184         };
00185 }
00186 
00187 // \todo MetaData structures copy constructors - for string copies
00188 
00189 class DLLEXPORT AudioMetaData {
00190 public:
00191         //! Default constructor
00192         AudioMetaData();
00193 
00194         //!< Construct and load from stream
00195         AudioMetaData(std::istream &i);
00196 
00197         /**
00198          * @name Setters
00199          */
00200         //@{
00201         void setTitle(const char *title) {
00202                 Utils::copyString(title, m_title);
00203         }
00204         void setArtist(const char *artist) {
00205                 Utils::copyString(artist, m_artist);
00206         }
00207         void setAlbum(const char *album) {
00208                 Utils::copyString(album, m_album);
00209         }
00210         void setGenre(const char *genre) {
00211                 Utils::copyString(genre, m_genre);
00212         }
00213         void setComment(const char *comment) {
00214                 Utils::copyString(comment, m_comment);
00215         }
00216         void setComposer(const char *composer) {
00217                 Utils::copyString(composer, m_composer);
00218         }
00219         void setOrigArtist(const char *origartist) {
00220                 Utils::copyString(origartist, m_origartist);
00221         }
00222         void setCopyright(const char *copyright) {
00223                 Utils::copyString(copyright, m_copyright);
00224         }
00225         void setUrl(const char *url) {
00226                 Utils::copyString(url, m_url);
00227         }
00228         void setEncoded(const char *encoded) {
00229                 Utils::copyString(encoded, m_encoded);
00230         }
00231         void setYear(uint16_t year) { m_year = year; }
00232         //@}
00233 
00234         /**
00235          * @name Getters
00236          */
00237         //@{
00238         std::string getTitle()      const { return m_title;      }
00239         std::string getArtist()     const { return m_artist;     }
00240         std::string getAlbum()      const { return m_album;      }
00241         std::string getGenre()      const { return m_genre;      }
00242         std::string getComment()    const { return m_comment;    }
00243         std::string getComposer()   const { return m_composer;   }
00244         std::string getOrigArtist() const { return m_origartist; }
00245         std::string getCopyright()  const { return m_copyright;  }
00246         std::string getUrl()        const { return m_url;        }
00247         std::string getEncoded()    const { return m_encoded;    }
00248         uint16_t    getYear()       const { return m_year;       }
00249         //@}
00250 
00251         //! Output operator for streams
00252         friend std::ostream& operator<<(
00253                 std::ostream &o, const AudioMetaData &amd
00254         );
00255 private:
00256         friend class MetaData;
00257         ~AudioMetaData();
00258         AudioMetaData(const AudioMetaData&);            //!< Forbidden
00259         AudioMetaData& operator=(const AudioMetaData&); //!< Forbidden
00260 
00261         char* m_title;                              //!< Track title
00262         char* m_artist;                             //!< Track performer
00263         char* m_album;                              //!< Album
00264         char* m_genre;                              //!< Genre
00265         char* m_comment;                            //!< Comment
00266         char* m_composer;                           //!< Composer
00267         char* m_origartist;                         //!< Original artist
00268         char* m_copyright;                          //!< Copyright string
00269         char* m_url;                                //!< Web url
00270         char* m_encoded;                            //!< Encoded
00271         uint16_t m_year;                            //!< Release year
00272 };
00273 
00274 namespace CGComm {
00275         //! ArchiveMetaData tags
00276         enum ARMDOpCodes {
00277                 OP_ARMD          = 0x60,    //!< ArchiveMetaData
00278                 OP_ARMD_FORMAT   = 0x61,    //!< <uint32> Format
00279                 OP_ARMD_FILES    = 0x62,    //!< <uint32> File count
00280                 OP_ARMD_UNCOMPR  = 0x63,    //!< <uint64> Uncompressed size
00281                 OP_ARMD_RATIO    = 0x64,    //!< <float>  Compression ratio
00282                 OP_ARMD_COMMENT  = 0x65,    //!< <string> Comment
00283                 OP_ARMD_PASSWORD = 0x66     //!< <bool>   If password is set
00284         };
00285 }
00286 
00287 //! Archive meta data
00288 class DLLEXPORT ArchiveMetaData {
00289 public:
00290         ArchiveMetaData();                  //!< Default constructor
00291         ArchiveMetaData(std::istream &i);   //!< Construct and load from stream
00292 
00293         /**
00294          * @name Setters
00295          */
00296         //@{
00297         void setFormat(uint32_t format)      { m_format = format;     }
00298         void setFileCount(uint32_t files)    { m_files = files;       }
00299         void setUnComprSize(uint64_t size)   { m_uncomprsize = size;  }
00300         void setComprRatio(float ratio)      { m_ratio = ratio;       }
00301         void setPassword(bool password)      { m_password = password; }
00302         void setComment(const char *comment) {
00303                 Utils::copyString(comment, m_comment);
00304         }
00305         //@}
00306 
00307         /**
00308          * @name Getters
00309          */
00310         //@{
00311         uint32_t          getFormat()      const { return m_format;      }
00312         uint32_t          getFileCount()   const { return m_files;       }
00313         uint64_t          getUnComprSize() const { return m_uncomprsize; }
00314         float             getComprRatio()  const { return m_ratio;       }
00315         std::string       getComment()     const { return m_comment;     }
00316         bool              getPassword()    const { return m_password;    }
00317         //@}
00318 private:
00319         friend class MetaData;
00320         ~ArchiveMetaData() {
00321                 if (m_comment) { free(m_comment); }
00322         }
00323         ArchiveMetaData(const ArchiveMetaData&);             //!< Forbidden
00324         ArchiveMetaData& operator=(const ArchiveMetaData&);  //!< Forbidden
00325 
00326         uint32_t m_format;                          //!< Compression format
00327         uint32_t m_files;                           //!< Number of files stored
00328         uint64_t m_uncomprsize;                     //!< Uncompressed size
00329         float m_ratio;                              //!< Compression ratio
00330         char* m_comment;                            //!< Comment
00331         bool m_password;                            //!< If password is set
00332 
00333         //! Output operator for streams
00334         friend std::ostream& operator<<(
00335                 std::ostream &o, const ArchiveMetaData &amd
00336         );
00337         //! In testsuite
00338         friend void test_archivedata();
00339 };
00340 
00341 namespace CGComm {
00342         //! ImageMetaData opcodes
00343         enum IMDOpCodes {
00344                 OP_IMD         = 0x80,             //!< ImageMetaData
00345                 OP_IMD_FORMAT  = 0x81,             //!< <uint32> Format
00346                 OP_IMD_WIDTH   = 0x82,             //!< <uint32> Height
00347                 OP_IMD_HEIGHT  = 0x83,             //!< <uint32> Width
00348                 OP_IMD_DATE    = 0x84,             //!< <uint32> Creation date
00349                 OP_IMD_COMMENT = 0x85              //!< <string> Comment
00350         };
00351 }
00352 
00353 //! Image meta data
00354 class DLLEXPORT ImageMetaData {
00355 public:
00356         ImageMetaData();                            //!< Default constructor
00357         ImageMetaData(std::istream &i);             //!< Construct & load
00358 
00359         /**
00360          * @name Setters
00361          */
00362         //@{
00363         void setFormat(uint32_t format)      { m_format = format;   }
00364         void setWidth(uint32_t width)        { m_width = width;     }
00365         void setHeight(uint32_t height)      { m_height = height;   }
00366         void setCreated(uint32_t created)    { m_created = created; }
00367         void setComment(const char *comment) {
00368                 Utils::copyString(comment, m_comment);
00369         }
00370         //@}
00371 
00372         /**
00373          * @name Getters
00374          */
00375         //@{
00376         uint32_t          getFormat()  const { return m_format;  }
00377         uint32_t          getWidth()   const { return m_width;   }
00378         uint32_t          getHeight()  const { return m_height;  }
00379         std::string       getComment() const { return m_comment; }
00380         uint32_t          getCreated() const { return m_created; }
00381         //@}
00382 
00383 private:
00384         friend class MetaData;
00385         ~ImageMetaData() {
00386                 if (m_comment) { free(m_comment); }
00387         }
00388         ImageMetaData(const ImageMetaData&);            //!< Copying forbidden
00389         ImageMetaData& operator=(const ImageMetaData&); //!< Assign forbidden
00390 
00391         uint32_t m_format;                          //!< Format, e.g png/jpg etc
00392         uint32_t m_width;                           //!< Image width
00393         uint32_t m_height;                          //!< Image height
00394         char* m_comment;                            //!< Image comment
00395         uint32_t m_created;                         //!< Image creation date
00396 
00397         //! Output operator for streams
00398         friend std::ostream& operator<<(
00399                 std::ostream &o, const ImageMetaData &imd
00400         );
00401         //! In testsuite
00402         friend void test_imagedata();
00403 };
00404 
00405 //! Event emitted by MetaData object
00406 enum MDEvent {
00407         MD_ADDED_FILENAME = 1,  //!< A file name has been added
00408         MD_ADDED_HASHSET,       //!< A Hashset has been added
00409         MD_ADDED_VIDEO,         //!< Video data has been added
00410         MD_ADDED_AUDIO,         //!< Audio data has been added
00411         MD_ADDED_ARCHIVE,       //!< Archive data has been added
00412         MD_ADDED_IMAGE          //!< Image data has been added
00413 };
00414 
00415 namespace CGComm {
00416         //! MetaData opcodes
00417         enum MetaDataOpCodes {
00418                 OP_METADATA       = 0x90, //!< MetaData
00419                 OP_MD_FILENAME    = 0x91, //!< <string> File Name
00420                 OP_MD_FILESIZE    = 0x92, //!< <uint64> size
00421                 OP_MD_MODDATE     = 0x93, //!< <uint32> modification date
00422                 OP_MD_FILETYPE    = 0x94, //!< <uint32> file type
00423                 OP_MD_TYPEGUESSED = 0x95  //!< <bool> if type has been guessed
00424         };
00425 }
00426 
00427 class HashSetBase;
00428 
00429 /**
00430  * MetaData container which can contain any number of any type of different
00431  * Metadata-like objects. By default none of the memory-heavy structures
00432  * are created - they are stored as smart pointers.
00433  *
00434  * This class also submits events when file names, hashests and so on are added
00435  * to it. Refer to MDEvt documentation on event types submitted from this class,
00436  * and EventTable documentation on how to handle events.
00437  *
00438  * The objects of this class are owned by MetaDb and the destructor has been
00439  * protected. As such, you cannot create MetaData objects on stack, and if
00440  * you create them on heap, you MUST submit them to MetaDb because you are not
00441  * able to delete them yourself.
00442  */
00443 class DLLEXPORT MetaData {
00444 public:
00445         DECLARE_EVENT_TABLE(MetaData*, int);
00446 
00447         //! Constructor
00448         MetaData(
00449                 uint64_t fileSize, FileType type = FT_UNKNOWN,
00450                 bool typeGuessed = true
00451         );
00452 
00453         /**
00454          * Construct by reading data from input stream.
00455          */
00456         MetaData(std::istream &ifs);
00457 
00458         //! Default constructor
00459         MetaData();
00460 
00461         /**
00462          * Destructor is exposed to allow more generic usage of the object.
00463          * While the main purpose of this object was to remain hidden inside
00464          * MetaDb and owned only by MetaDb, practice has shown this object
00465          * is useful outside the MetaDb context also, and thus the destructor
00466          * has been exposed. This does open a possibility of abuse though by
00467          * objects using MetaData pointers given out by MetaDb.
00468          */
00469         ~MetaData();
00470 
00471         /**
00472          * @name Setters
00473          */
00474         //@{
00475         void addVideoData(VideoMetaData *vmd) {
00476                 m_videoData.push_back(vmd);
00477                 getEventTable().postEvent(this, MD_ADDED_VIDEO);
00478         }
00479         void addAudioData(AudioMetaData *amd) {
00480                 m_audioData.push_back(amd);
00481                 getEventTable().postEvent(this, MD_ADDED_AUDIO);
00482         }
00483         void setArchiveData(ArchiveMetaData *amd) {
00484                 m_archiveData = amd;
00485                 getEventTable().postEvent(this, MD_ADDED_ARCHIVE);
00486         }
00487         void setImageData(ImageMetaData *imd) {
00488                 m_imageData = imd;
00489                 getEventTable().postEvent(this, MD_ADDED_IMAGE);
00490         }
00491         void addFileName(const std::string &name) {
00492                 m_fileNames.push_back(name);
00493                 getEventTable().postEvent(this, MD_ADDED_FILENAME);
00494         }
00495         void addHashSet(HashSetBase *hashset) {
00496                 m_hashsets.push_back(hashset);
00497                 getEventTable().postEvent(this, MD_ADDED_HASHSET);
00498         }
00499         void setFileSize(uint64_t size)   { m_fileSize = size;       }
00500         void setModDate(uint32_t date)    { m_modDate = date;        }
00501         void setFileType(FileType type)   { m_fileType = type;       }
00502         void setTypeGuessed(bool guessed) { m_typeGuessed = guessed; }
00503         //@}
00504 
00505         /**
00506          * @name Getters
00507          */
00508         //@{
00509         uint32_t getVideoDataCount() const { return m_videoData.size(); }
00510         VideoMetaData *const getVideoData(uint32_t num) {
00511                 return m_videoData.at(num);
00512         }
00513 
00514         uint32_t getAudioDataCount() const { return m_audioData.size(); }
00515         AudioMetaData *const getAudioData(uint32_t num) const {
00516                 return m_audioData.at(num);
00517         }
00518 
00519         ArchiveMetaData *const getArchiveData() const {
00520                 if (!m_archiveData) {
00521                         throw std::runtime_error("No archive data available.");
00522                 }
00523                 return m_archiveData;
00524         }
00525 
00526         ImageMetaData *const getImageData() const {
00527                 if (!m_imageData) {
00528                         throw std::runtime_error("No image data available.");
00529                 }
00530                 return m_imageData;
00531         }
00532 
00533         uint32_t getHashSetCount() const { return m_hashsets.size(); }
00534         HashSetBase *const getHashSet(uint32_t num) const {
00535                 return m_hashsets.at(num);
00536         }
00537 
00538         uint32_t getFileNameCount() const { return m_fileNames.size(); }
00539         std::string getFileName(uint32_t num) const {
00540                 return m_fileNames.at(num);
00541         }
00542 
00543         uint64_t getFileSize()    const { return m_fileSize;    }
00544         uint32_t getModDate()     const { return m_modDate;     }
00545         FileType getFileType()    const { return m_fileType;    }
00546         bool     getTypeGuessed() const { return m_typeGuessed; }
00547         //@}
00548 
00549 private:
00550         MetaData(const MetaData &md);             //!< Copy construct forbidden
00551         MetaData& operator=(const MetaData&);     //!< Assignment forbidden
00552 
00553         //! Video data streams
00554         std::vector<VideoMetaData*> m_videoData;
00555         typedef std::vector<VideoMetaData*>::const_iterator CVMDIter;
00556 
00557         //! Audio data streams
00558         std::vector<AudioMetaData*> m_audioData;
00559         typedef std::vector<AudioMetaData*>::const_iterator CAMDIter;
00560 
00561         //! Archive data
00562         ArchiveMetaData *m_archiveData;
00563 
00564         //! Image data
00565         ImageMetaData *m_imageData;
00566 
00567         //! Hash sets
00568         std::vector<HashSetBase*> m_hashsets;
00569         typedef std::vector<HashSetBase*>::const_iterator CHIter;
00570 
00571         std::vector<std::string> m_fileNames;       //!< All known file names
00572         uint64_t m_fileSize;                        //!< File size
00573         uint32_t m_modDate;                         //!< File modification date
00574         FileType m_fileType;                        //!< File type
00575         bool m_typeGuessed;                         //!< If type was guessed
00576 
00577         //! Output operator for streams
00578         friend std::ostream& operator<<(std::ostream &o, const MetaData &md);
00579 };
00580 
00581 #endif