LCOV - lcov.info - ept/core/desktop.h

LTP GCOV extension - code coverage report
Current view: | directory - ept/core - desktop.h
Test: | lcov.info
Date: | 2008-08-14 |  | Instrumented lines: | 103
Code covered: | 94.2 % |  | Executed lines: | 97

           1                 : /// -*- C++ -*- (c) 2006, 2007 Petr Rockai <me@mornfall.net>
           2                 :
           3                 : #include <wibble/string.h>
           4                 :
           5                 : #include <ept/token.h>
           6                 : #include <ept/core/desktopfile.h>
           7                 : #include <ept/core/source.h>
           8                 :
           9                 : #include <set>
          10                 : #include <vector>
          11                 : #include <fstream>
          12                 : #include <sstream>
          13                 : #include <iterator>
          14                 : #include <functional>
          15                 :
          16                 : #include <dirent.h>
          17                 :
          18                 : #ifndef EPT_CORE_DESKTOP_H
          19                 : #define EPT_CORE_DESKTOP_H
          20                 :
          21                 : namespace ept {
          22                 : namespace core {
          23                 : namespace desktop {
          24                 :
          25                 : typedef enum { Name, Group, ShortDescription, Package, Icon } PropertyId;
          26                 :
          27                 : template< PropertyId > struct PropertyType {};
          28                 : template<> struct PropertyType< Name > { typedef std::string T; };
          29                 : template<> struct PropertyType< Group > { typedef std::string T; };
          30                 : template<> struct PropertyType< ShortDescription > { typedef std::string T; };
          31                 : template<> struct PropertyType< Package > { typedef ept::Token T; };
          32                 : template<> struct PropertyType< Icon > { typedef std::string T; };
          33                 :
          34                 : typedef std::set< std::string > Categories;
          35                 :
          36              64 : struct Category {
          37                 :     std::string name;
          38             112 :     operator std::string() const { return name; }
          39                 : };
          40                 :
          41              80 : inline std::istream &operator >>( std::istream &i, Category &cat ) {
          42                 :     char c;
          43              80 :     cat.name = "";
          44             468 :     while ( i.peek() != EOF ) {
          45             356 :         c = i.get();
          46             356 :         if ( c == ';' ) return i;
          47             308 :         cat.name += c;
          48                 :     }
          49              32 :     return i;
          50                 : }
          51                 :
          52             567 : struct Entry : wibble::mixin::Comparable< Entry > {
          53              18 :     Entry() {}
          54                 :     Entry( std::string n, std::string g,
          55                 :            std::string p, std::string d , std::string i )
          56                 :         : m_name( n ),
          57                 :           m_package( p ),
          58                 :           m_description( d ),
          59                 :           m_icon( i )
          60                 :     { setCategories( g ); }
          61                 :
          62              16 :     void load( std::string file ) {
          63              16 :         m_id = file;
          64              16 :         std::ifstream i( file.c_str() );
          65              16 :         if ( !i.is_open() )
          66               0 :             return; // throw?
          67              16 :         desktop::File e;
          68              16 :         i >> e;
          69              16 :         i.close();
          70              16 :         desktop::File::Group &g = e.group( "Desktop Entry" );
          71              32 :         m_name = g.entry( "Name" ).value;
          72              32 :         m_description = g.entry( "Comment" ).value;
          73              32 :         if ( m_description == "" )
          74               8 :             m_description = g.entry( "GenericName" ).value;
          75              16 :         m_package = g.entry( "X-AppInstall-Package" ).value;
          76                 :         // m_group = g.entry( "Categories" ).value;
          77              32 :         m_icon = g.entry( "Icon" ).value;
          78              32 :         setCategories( g.entry( "Categories" ).value );
          79                 :     }
          80                 :
          81              16 :     void setCategories( std::string s ) {
          82              16 :         std::istringstream i( s );
          83              16 :         m_categories.clear();
          84                 :         std::remove_copy_if(
          85                 :             std::istream_iterator< Category >( i ),
          86                 :             std::istream_iterator< Category >(),
          87                 :             std::inserter( m_categories, m_categories.begin() ),
          88              16 :             std::bind1st( std::equal_to< std::string >(), "" ) );
          89              16 :     }
          90                 :
          91              16 :     Categories categories() const { return m_categories; }
          92                 :     bool inCategory( std::string c ) const {
          93                 :         return m_categories.find( c ) != m_categories.end();
          94                 :     }
          95              34 :     std::string id() const { return m_id; }
          96               6 :     std::string name() const { return m_name; }
          97                 :     std::string package() const { return m_package; }
          98                 :     std::string description() const { return m_description; }
          99                 :     std::string icon() const { return m_icon; }
         100                 :     bool operator< ( const Entry &o ) const {
         101                 :         if ( m_name < o.m_name ) return true;
         102                 :         if ( m_name == o.m_name )
         103                 :             if ( m_package < o.m_package ) return true;
         104                 :         return false;
         105                 :     }
         106                 : protected:
         107                 :     std::string m_name, m_package, m_description, m_icon, m_id;
         108                 :     bool m_supported, m_free;
         109                 :     Categories m_categories;
         110                 : };
         111                 :
         112             450 : struct InternalList {
         113                 :     std::string dir;
         114                 :     std::string current;
         115                 :     mutable Entry entry;
         116                 :     off_t offset;
         117                 :     mutable bool loaded;
         118                 :
         119               9 :     InternalList() : dir( "" ), offset( -2 ), loaded( false ) {}
         120               4 :     InternalList( std::string d ) : dir( d ), offset( -1 ), loaded( false )
         121                 :     {
         122               4 :         firstFile();
         123               4 :     }
         124                 :
         125              56 :     Entry head() const {
         126              56 :         if (!loaded)
         127              16 :             entry.load( current );
         128              56 :         loaded = true;
         129              56 :         return entry;
         130                 :     }
         131                 :
         132              33 :     bool empty() const {
         133              33 :         return (offset == -2);
         134                 :     }
         135                 :
         136               4 :     void firstFile() {
         137               4 :         offset = -1;
         138               4 :         nextFile();
         139               4 :     }
         140                 :
         141              16 :     InternalList tail() const {
         142              16 :         InternalList r = *this;
         143              16 :         r.nextFile();
         144               0 :         return r;
         145                 :     }
         146                 :
         147              20 :     void nextFile() {
         148              20 :         loaded = false;
         149              20 :         DIR *d = opendir( dir.c_str() );
         150              20 :         if ( !d ) {
         151               0 :             offset = -2;
         152               0 :             closedir( d );
         153               0 :             return;
         154                 :         }
         155                 :
         156              20 :         if ( offset != -1 )
         157              16 :             seekdir( d, offset );
         158                 :
         159              20 :         dirent *ent = 0;
         160              48 :         while ( ( ent = readdir( d ) ) != 0 ) {
         161              24 :             std::string name( ent->d_name );
         162              48 :             if ( name == "." || name == ".." )
         163               8 :                 continue;
         164              16 :             if ( !wibble::str::endsWith( name, ".desktop" ) )
         165                 :                 continue;
         166              16 :             current = dir + "/" + name;
         167              16 :             offset = telldir( d );
         168              16 :             closedir( d );
         169              16 :             return;
         170                 :         }
         171               4 :         closedir( d );
         172               4 :         offset = -2;
         173                 :     }
         174                 : };
         175                 :
         176                 : struct Setup {
         177                 :     typedef ept::Token Token;
         178                 :     typedef Entry Internal;
         179                 :     typedef desktop::PropertyId PropertyId;
         180                 :     typedef desktop::InternalList InternalList;
         181                 : };
         182                 :
         183               5 : struct GroupPolicy {
         184              16 :     virtual std::string group( const Entry &e )
         185                 :     {
         186              16 :         return wibble::str::fmt( e.categories() );
         187                 :     }
         188               5 :     virtual ~GroupPolicy() {}
         189                 : };
         190                 :
         191                 : struct Source : core::Source< Source, Setup, PropertyType >
         192               5 : {
         193                 :     std::string m_dir;
         194                 :
         195                 :     GroupPolicy m_defaultPolicy;
         196                 :     GroupPolicy *m_policy;
         197                 :
         198               5 :     Source( std::string dir ) : m_dir( dir ),
         199               5 :                                 m_policy( &m_defaultPolicy ) {}
         200                 :
         201               4 :     InternalList listInternal() {
         202               4 :         return InternalList( m_dir );
         203                 :     }
         204                 :
         205              34 :     Token getToken( Entry i ) {
         206              34 :         Token t;
         207              34 :         t._id = std::string( "desktop:" ) + i.id();
         208               0 :         return t;
         209                 :     }
         210                 :
         211                 :     Entry lookupToken( Token t ) {
         212                 :         Entry e;
         213                 :         e.load( t.desktop() );
         214                 :         return e;
         215                 :     }
         216                 :
         217                 :     void setGroupPolicy( GroupPolicy *p ) {
         218                 :         m_policy = p;
         219                 :     }
         220                 :
         221                 :     template< PropertyId p >
         222                 :     typename PropertyType< p >::T getInternal( Entry );
         223                 :
         224              56 :     struct IsInGroup {
         225                 :         std::string g;
         226               2 :         IsInGroup( std::string _g = "" ) : g( _g ) {}
         227               8 :         bool operator()( Token, std::string gr ) const {
         228               8 :             return gr == g;
         229                 :         }
         230                 :     };
         231                 :
         232               1 :     PropertyFilter< Group, IsInGroup >::T group( std::string id )
         233                 :     {
         234               1 :         return propertyFilter< Group >( IsInGroup( id ) );
         235                 :     }
         236                 :
         237               4 :     static std::string projectGroup( ComposedList< Name > t ) {
         238               4 :         return t.get< Group >();
         239                 :     }
         240                 :
         241                 :     list::Unique< list::Sorted<
         242                 :                       list::Map< ComposedList< Name >,
         243                 :                                  __typeof( std::ptr_fun( &projectGroup ) ) > > >
         244               1 :     groupList() {
         245                 :         return list::unique(
         246                 :             list::sort( list::map( list< Name >(),
         247               1 :                                    std::ptr_fun( &projectGroup ) ) ) );
         248                 :     }
         249                 : };
         250                 :
         251               6 : template<> inline std::string Source::getInternal< Name >( Entry e ) {
         252               6 :     return e.name();
         253                 : }
         254                 :
         255                 : template<> inline std::string Source::getInternal< Icon >( Entry e ) {
         256                 :     return e.icon();
         257                 : }
         258                 :
         259                 : template<> inline ept::Token Source::getInternal< Package >( Entry e ) {
         260                 :     ept::Token t;
         261                 :     t._id = e.package();
         262                 :     return t;
         263                 : }
         264                 :
         265              16 : template<> inline std::string Source::getInternal< Group >( Entry e ) {
         266              16 :     return m_policy->group( e );
         267                 : }
         268                 :
         269                 : template<> inline std::string Source::getInternal< ShortDescription >( Entry e ) {
         270                 :     return e.description();
         271                 : }
         272                 :
         273                 : }
         274                 : }
         275                 : }
         276                 :
         277                 : #endif

Generated by: LTP GCOV extension version 1.6