a5204d1205121bac583fcb841fec1559a876c114
[platform/upstream/libzypp.git] / zypp / CpeId.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/CpeId.h
10  */
11 #ifndef ZYPP_CPEID_H
12 #define ZYPP_CPEID_H
13
14 #include <iosfwd>
15 #include <string>
16
17 #include "zypp/base/PtrTypes.h"
18 #include "zypp/base/Flags.h"
19 #include "zypp/base/EnumClass.h"
20 #include "zypp/base/SetRelationMixin.h"
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 {
25   ///////////////////////////////////////////////////////////////////
26   /// \class CpeId
27   /// \brief Common Platform Enumearation (2.3)
28   /// See http://cpe.mitre.org/ for more information on the
29   /// Common Platform Enumearation.
30   ///////////////////////////////////////////////////////////////////
31   class CpeId : public base::SetRelationMixin<CpeId>
32   {
33   public:
34     /** WFN attribute value */
35     class Value;
36
37   public:
38     /** WFN attributes (use like 'enum class \ref Attribute') */
39     struct _AttributeDef {
40       enum Enum {
41         part,           //< attribute (2.2)
42         vendor,         //< attribute (2.2)
43         product,        //< attribute (2.2)
44         version,        //< attribute (2.2)
45         update,         //< attribute (2.2)
46         edition,        //< attribute (2.2)
47         language,       //< attribute (2.2)
48         sw_edition,     //< extended attribute (2.3)
49         target_sw,      //< extended attribute (2.3)
50         target_hw,      //< extended attribute (2.3)
51         other           //< extended attribute (2.3)
52       };
53       static constexpr unsigned numAttributes = other+1;        ///< number of attributes
54       static const std::string & asString( Enum val_r );        ///< string representantion
55     };
56     typedef base::EnumClass<_AttributeDef> Attribute;   ///< 'enum class Attribute'
57
58   public:
59     /** Indicator type for non-trowing ctor. */
60     struct NoThrowType { static std::string lastMalformed; };
61     /** Indicator argument for non-trowing ctor. */
62     static constexpr NoThrowType noThrow = NoThrowType();
63
64   public:
65     /** Default ctor: ANY-Cpeid, all attribute values are ANY */
66     CpeId();
67
68     /** Ctor parsing from string representation (empty or URI or FS)
69      * \throws std::invalid_argument if string is malformed
70      */
71     explicit CpeId( const std::string & cpe_r );
72
73     /** Ctor parsing from string representation (empty or URI or FS)
74      * \throws std::invalid_argument if string is malformed
75      */
76     explicit CpeId( const char * cpe_r )
77       : CpeId( std::string( cpe_r ? cpe_r : "" ) )
78     {}
79
80     /** Ctor parsing from string (empty or URI or FS, non throwing)
81      * Creates an empty CpeId if string is malformed.
82      */
83     CpeId( const std::string & cpe_r, NoThrowType );
84
85     /** Dtor */
86     ~CpeId();
87
88   public:
89     /**  Evaluate in boolean context: not an ANY-CpeId */
90     explicit operator bool() const;
91
92     /** Default string representation [\ref asFS]. */
93     std::string asString() const
94     { return asFs(); }
95
96     /** String representation as Formated-String (in/out).
97      * \code
98      * cpe:2.3:a:opensuse:libzypp:14.16.0:beta:*:*:*:*:*:*
99      * \endcode
100      */
101     std::string asFs() const;
102
103     /** String representation as URI (in/out).
104      * \code
105      * cpe:/a:opensuse:libzypp:14.16.0:beta
106      * \endcode
107      */
108     std::string asUri() const;
109
110     /** String representation as Well-Formed-Name (internal format, out only).
111      * \code
112      * wfn:[part="a",vendor="opensuse",product="libzypp", version="14\.16\.0",update="beta"]
113      * \endcode
114      */
115     std::string asWfn() const;
116
117   private:
118     friend SetCompare base::SetRelationMixin<CpeId>::compare( const CpeId & ) const;
119     /** CPE name matching hook for \ref SetRelationMixin */
120     SetCompare setRelationMixinCompare( const CpeId & trg ) const;
121
122   public:
123     class Impl;                 ///< Implementation class.
124   private:
125     RWCOW_pointer<Impl> _pimpl; ///< Pointer to implementation.
126   };
127
128   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( CpeId, const char * );
129   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( CpeId, const std::string & );
130
131   /** \relates CpeId Stream output */
132   inline std::ostream & operator<<( std::ostream & str, const CpeId & obj )
133   { return str << obj.asString(); }
134
135   /** \relates CpeId::Attribute Stream output */
136   inline std::ostream & operator<<( std::ostream & str, const CpeId::Attribute & obj )
137   { return str << CpeId::Attribute::asString( obj.asEnum() ); }
138
139
140   ///////////////////////////////////////////////////////////////////
141   /// \class CpeId::Value
142   /// \brief WFN attribute value
143   ///
144   /// Valid WFN string values are not empty, contain alphanumeric chars, underscore,
145   /// no whitespace, printable non-alphanumeric characters must be quoted by a
146   /// backslash.
147   ///
148   /// Unescaped asterisk and question mark are special characters and may occur at
149   /// the beginning and or end of the string. The asterisk must not be used more than
150   /// once in asequense. The question mark may be used more than once in a sequence.
151   ///
152   /// A single asterisk must not be used as attribute value, nor a single quoted hyphen.
153   ///
154   /// A single question mark may be used as value.
155   ///
156   /// \see http://cpe.mitre.org/ for more information on the Common Platform Enumeration.
157   ///////////////////////////////////////////////////////////////////
158   class CpeId::Value : public base::SetRelationMixin<Value>
159   {
160   public:
161     /** Logical value matching ANY value. */
162     static const Value ANY;
163
164     /** Logical value indicating “not applicable/not used" */
165     static const Value NA;
166
167   public:
168     /** Indicator type for ctor arg in FS format. */
169     struct FsFormatType {};
170     /** Indicator argument for ctor arg in FS format. */
171     static constexpr FsFormatType fsFormat = FsFormatType();
172
173     /** Indicator type for ctor arg in URI format. */
174     struct UriFormatType {};
175     /** Indicator argument for ctor arg in URI format. */
176     static constexpr UriFormatType uriFormat = UriFormatType();
177
178   public:
179     /** Default ctor: ANY */
180     Value()
181     {}
182
183     /** Ctor from string (WFN format; \c "*" represents ANY; \c "" represents NA)
184      * \throws std::invalid_argument if string is malformed (\see \ref isValidWfn).
185      */
186     explicit Value( const std::string & value_r );
187
188     /** Ctor from char* (WFN format; \c nullptr or \c "*" represent ANY; \c "" represents NA)
189      * \throws std::invalid_argument if string is malformed (\see \ref isValidWfn).
190      */
191     explicit Value( const char * value_r )
192     : Value( std::string( value_r ? value_r : "*" ) )
193     {}
194
195     /** Ctor from string (FS format, \c "*" represents ANY; \c "-" represents NA)
196      * \throws std::invalid_argument if string is malformed.
197      */
198      Value( const std::string & encoded_r, FsFormatType );
199
200     /** Ctor from string (URI format, \c "" represents ANY; \c "-" represents NA)
201      * \throws std::invalid_argument if string is malformed.
202      */
203      Value( const std::string & encoded_r, UriFormatType );
204
205   public:
206     /** Classification of \ref Value types mostly for \ref match (use like 'enum class \ref Type') */
207     struct _TypeDef {
208       enum Enum {
209         ANY,
210         NA,
211         wildcardfree,
212         wildcarded,
213       };
214     };
215     typedef base::EnumClass<_TypeDef> Type;     ///< 'enum class Type'
216
217     /** Return the \ref Type of this \ref Value. */
218     Type type() const
219     {
220       if ( !_value ) return Type::ANY;
221       if ( _value->empty() ) return Type::NA;
222       return( isWildcarded() ? Type::wildcarded : Type::wildcardfree );
223     }
224
225     /** Whether value is ANY. ) */
226     bool isANY() const
227     { return !_value; }
228
229     /** Whether value is NA. ) */
230     bool isNA() const
231     { return _value && _value->empty(); }
232
233     /** Whether it's a logical value (ANY|NA). */
234     bool isLogical() const
235     { return !_value || _value->empty(); }
236     /** \overload for Type */
237     bool isLogical( Type type_r ) const
238     { return( type_r == Type::ANY || type_r == Type::NA ); }
239
240     /** Whether it's an attribute value string (not logical value). */
241     bool isString() const
242     { return _value && !_value->empty(); }
243     /** \overload for Type */
244     bool isString( Type type_r ) const
245     { return( type_r == Type::wildcardfree || type_r == Type::wildcarded ); }
246
247     /** An attribute value string without wildcards (<tt>[*?]</tt> at begin and/or end) */
248     bool isWildcardfree() const
249     { return isString() && ! containsWildcard(); }
250
251     /** An attribute value string with wildcards (<tt>[*?]</tt> at begin and/or end) */
252     bool isWildcarded() const
253     { return isString() && containsWildcard(); }
254
255   public:
256     /** Default string representation [\ref asWfn]. */
257     std::string asString() const
258     { return asWfn(); }
259
260     /** String representation as in Well-Formed-Name (ANY:"*", NA:"").
261      * \code
262      * wfn:[part="a",vendor="opensuse",product="libzypp", version="14\.16\.0",update="beta"]
263      * \endcode
264      */
265     std::string asWfn() const;
266
267     /** String representation as in Formated-String (ANY:"*", NA:"-")
268      * \code
269      * cpe:2.3:a:opensuse:libzypp:14.16.0:beta:*:*:*:*:*:*
270      * \endcode
271      */
272     std::string asFs() const;
273
274     /** String representation as in URI (ANY:"", NA:"-")
275      * \code
276      * cpe:/a:opensuse:libzypp:14.16.0:beta
277      * \endcode
278      */
279     std::string asUri() const;
280
281   private:
282     friend SetCompare base::SetRelationMixin<Value>::compare( const Value & ) const;
283     /** CPE name matching hook for \ref SetRelationMixin */
284     SetCompare setRelationMixinCompare( const Value & trg ) const;
285
286     /** HAs unquoted <tt>[*?]</tt> at begin and/or end of value.
287      * \note \ref isString() must be asserted!
288      */
289     bool containsWildcard() const;
290
291   private:
292     RWCOW_pointer<std::string> _value;
293   };
294
295   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( CpeId::Value, const char * );
296   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( CpeId::Value, const std::string & );
297
298   /** \relates CpeId::Value Stream output */
299   std::ostream & operator<<( std::ostream & str, const CpeId::Value & obj );
300
301 } // namespace zypp
302 ///////////////////////////////////////////////////////////////////
303 #endif // ZYPP_CPEID_H