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