41a6b743114b71956529a33bfe5bb4842b02aee7
[platform/upstream/libzypp.git] / zypp / ContentType.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ContentType.h
10  */
11 #ifndef ZYPP_CONTENTTYPE_H
12 #define ZYPP_CONTENTTYPE_H
13
14 #include <iosfwd>
15 #include <string>
16
17 ///////////////////////////////////////////////////////////////////
18 namespace zypp
19 {
20   ///////////////////////////////////////////////////////////////////
21   /// \class ContentType
22   /// \brief Mime type like \c 'type/subtype' classification of content
23   ///
24   /// Used e.g. in \ref callback::UserData to describe the kind of
25   /// user data passed as \c void* to a callback. Neither type nor
26   /// subtype may contain a '/'.
27   ///////////////////////////////////////////////////////////////////
28   class ContentType
29   {
30   public:
31     /** Default ctor: empty */
32     ContentType()
33     {}
34
35     /** Ctor taking <tt>"type[/subtype]"</tt>
36      * \throws std::invalid_argument if string is malformed
37      */
38     explicit ContentType( const std::string & type_r )
39     {
40       std::string::size_type pos = type_r.find( "/" );
41       if ( pos == std::string::npos )
42       {
43         testAndSet( _type, type_r );
44       }
45       else
46       {
47         testAndSet( _type,    type_r.substr( 0, pos ) );
48         testAndSet( _subtype, type_r.substr( pos+1 ) );
49       }
50     }
51
52     /** Ctor taking type and subtype
53      * \throws std::invalid_argument if string is malformed
54      */
55     ContentType( const std::string & type_r, const std::string & subtype_r )
56     {
57       testAndSet( _type,    type_r );
58       testAndSet( _subtype, subtype_r );
59     }
60
61   public:
62     /** Get type */
63     const std::string & type() const
64     { return _type; }
65
66     /** Set type
67      * \throws std::invalid_argument if string is malformed
68      */
69     void type( const std::string & type_r )
70     { _type = type_r; }
71
72     /**  Get subtype */
73     const std::string & subtype() const
74     { return _subtype; }
75
76     /**  Set subtype
77      * \throws std::invalid_argument if string is malformed
78      */
79     void subtype( const std::string & subtype_r )
80     { _subtype = subtype_r; }
81
82   public:
83     /** Whether type and subtype are empty */
84     bool empty() const
85     { return emptyType() && emptySubtype(); }
86     /** Whether type is empty */
87     bool emptyType() const
88     { return _type.empty(); }
89     /** Whether subtype is empty */
90     bool emptySubtype() const
91     { return _subtype.empty(); }
92
93     /** Validate object in a boolean context: !empty */
94     explicit operator bool () const
95     { return !empty(); }
96
97     /** String representation <tt>"type[/subtype]"</tt> */
98     std::string asString() const
99     { std::string ret( type() ); if ( ! emptySubtype() ) { ret += "/"; ret += subtype(); } return ret; }
100
101   private:
102     void testAndSet( std::string & var_r, const std::string & val_r )
103     {
104       if ( val_r.find_first_of( "/ \t\r\n" ) != std::string::npos )
105         throw std::invalid_argument( "ContentType: illegal char in '" + val_r + "'" );
106       var_r = val_r;
107     }
108   private:
109     std::string _type;
110     std::string _subtype;
111   };
112
113   /** \relates ContentType Stream output */
114   inline std::ostream & operator<<( std::ostream & str, const ContentType & obj )
115   { return str << obj.asString(); }
116
117   /** \relates ContentType */
118   inline bool operator==( const ContentType & lhs, const ContentType & rhs )
119   { return lhs.type() == rhs.type() && lhs.subtype() == rhs.subtype(); }
120
121   /** \relates ContentType */
122   inline bool operator!=( const ContentType & lhs, const ContentType & rhs )
123   { return !( lhs == rhs ); }
124
125   /** \relates ContentType */
126   inline bool operator<( const ContentType & lhs, const ContentType & rhs )
127   { int cmp = lhs.type().compare( rhs.type() ); return cmp < 0 || ( cmp == 0 && lhs.subtype() < rhs.subtype() ); }
128
129   /** \relates ContentType */
130   inline bool operator<=( const ContentType & lhs, const ContentType & rhs )
131   { return lhs < rhs || lhs == rhs; }
132
133   /** \relates ContentType */
134   inline bool operator>( const ContentType & lhs, const ContentType & rhs )
135   { return !( lhs <= rhs ); }
136
137   /** \relates ContentType */
138   inline bool operator>=( const ContentType & lhs, const ContentType & rhs )
139   { return !( lhs < rhs ); }
140
141
142 } // namespace zypp
143 ///////////////////////////////////////////////////////////////////
144 #endif // ZYPP_CONTENTTYPE_H