1 /*
2  * Copyright (C) 2011-2019 Daniel Scharrer
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the author(s) be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  */
20 
21 /*!
22  * \file
23  *
24  * Inno Setup version number utilities.
25  */
26 #ifndef INNOEXTRACT_SETUP_VERSION_HPP
27 #define INNOEXTRACT_SETUP_VERSION_HPP
28 
29 #include <iosfwd>
30 #include <exception>
31 
32 #include <boost/cstdint.hpp>
33 
34 #include "util/flags.hpp"
35 
36 namespace setup {
37 
38 struct version_error : public std::exception { };
39 
40 typedef boost::uint32_t version_constant;
41 #define INNO_VERSION_EXT(a, b, c, d) ( \
42 	  (::setup::version_constant(a) << 24) \
43 	| (::setup::version_constant(b) << 16) \
44 	| (::setup::version_constant(c) <<  8) \
45 	| (::setup::version_constant(d) <<  0) \
46 )
47 #define INNO_VERSION(a, b, c) INNO_VERSION_EXT(a, b, c, 0)
48 
49 struct version {
50 
51 	FLAGS(flags,
52 		Bits16,
53 		Unicode,
54 		ISX
55 	);
56 
57 	version_constant value;
58 
59 	flags variant;
60 
61 	bool known;
62 
versionsetup::version63 	version() : value(0), variant(0), known(false) { }
64 
versionsetup::version65 	version(version_constant v, flags type = 0, bool is_known = false)
66 		: value(v), variant(type), known(is_known) { }
67 
68 
versionsetup::version69 	version(boost::uint8_t a, boost::uint8_t b, boost::uint8_t c, boost::uint8_t d = 0,
70 	        flags type = 0, bool is_known = false)
71 		: value(INNO_VERSION_EXT(a, b, c, d)), variant(type), known(is_known) { }
72 
asetup::version73 	unsigned int a() const { return  value >> 24;         }
bsetup::version74 	unsigned int b() const { return (value >> 16) & 0xff; }
csetup::version75 	unsigned int c() const { return (value >>  8) & 0xff; }
dsetup::version76 	unsigned int d() const { return  value        & 0xff; }
77 
78 	void load(std::istream & is);
79 
bitssetup::version80 	boost::uint16_t bits() const { return (variant & Bits16) ? 16 : 32; }
is_unicodesetup::version81 	bool is_unicode() const { return (variant & Unicode) != 0; }
is_isxsetup::version82 	bool is_isx() const { return (variant & ISX) != 0; }
83 
84 	//! \return true if the version stored might not be correct
85 	bool is_ambiguous() const;
86 
operator version_constantsetup::version87 	operator version_constant() const {
88 		return value;
89 	}
90 
91 	version_constant next();
92 
93 };
94 
95 std::ostream & operator<<(std::ostream & os, const version & version);
96 
97 } // namespace setup
98 
99 #endif // INNOEXTRACT_SETUP_VERSION_HPP
100