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