Skip to content

Commit c1b8944

Browse files
committed
Add config::version (4 segment uint32_t).
1 parent ddc9e0c commit c1b8944

File tree

10 files changed

+524
-1
lines changed

10 files changed

+524
-1
lines changed

Makefile.am

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ src_libbitcoin_system_la_SOURCES = \
8282
src/config/transaction.cpp \
8383
src/config/url.cpp \
8484
src/config/utilities.cpp \
85+
src/config/version.cpp \
8586
src/crypto/aes256.cpp \
8687
src/crypto/der_parser.cpp \
8788
src/crypto/ec_context.cpp \
@@ -261,6 +262,7 @@ test_libbitcoin_system_test_SOURCES = \
261262
test/config/printer.cpp \
262263
test/config/url.cpp \
263264
test/config/utilities.cpp \
265+
test/config/version.cpp \
264266
test/crypto/aes256.cpp \
265267
test/crypto/elliptic_curve.cpp \
266268
test/crypto/pseudo_random.cpp \
@@ -533,7 +535,8 @@ include_bitcoin_system_config_HEADERS = \
533535
include/bitcoin/system/config/script.hpp \
534536
include/bitcoin/system/config/transaction.hpp \
535537
include/bitcoin/system/config/url.hpp \
536-
include/bitcoin/system/config/utilities.hpp
538+
include/bitcoin/system/config/utilities.hpp \
539+
include/bitcoin/system/config/version.hpp
537540

538541
include_bitcoin_system_cryptodir = ${includedir}/bitcoin/system/crypto
539542
include_bitcoin_system_crypto_HEADERS = \

builds/cmake/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ add_library( ${CANONICAL_LIB_NAME}
515515
"../../src/config/transaction.cpp"
516516
"../../src/config/url.cpp"
517517
"../../src/config/utilities.cpp"
518+
"../../src/config/version.cpp"
518519
"../../src/crypto/aes256.cpp"
519520
"../../src/crypto/der_parser.cpp"
520521
"../../src/crypto/ec_context.cpp"
@@ -740,6 +741,7 @@ if (with-tests)
740741
"../../test/config/printer.cpp"
741742
"../../test/config/url.cpp"
742743
"../../test/config/utilities.cpp"
744+
"../../test/config/version.cpp"
743745
"../../test/crypto/aes256.cpp"
744746
"../../test/crypto/elliptic_curve.cpp"
745747
"../../test/crypto/pseudo_random.cpp"

builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
<ClCompile Include="..\..\..\..\test\config\printer.cpp" />
162162
<ClCompile Include="..\..\..\..\test\config\url.cpp" />
163163
<ClCompile Include="..\..\..\..\test\config\utilities.cpp" />
164+
<ClCompile Include="..\..\..\..\test\config\version.cpp" />
164165
<ClCompile Include="..\..\..\..\test\constants.cpp" />
165166
<ClCompile Include="..\..\..\..\test\constraints.cpp" />
166167
<ClCompile Include="..\..\..\..\test\crypto\aes256.cpp" />

builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@
219219
<ClCompile Include="..\..\..\..\test\config\utilities.cpp">
220220
<Filter>src\config</Filter>
221221
</ClCompile>
222+
<ClCompile Include="..\..\..\..\test\config\version.cpp">
223+
<Filter>src\config</Filter>
224+
</ClCompile>
222225
<ClCompile Include="..\..\..\..\test\constants.cpp">
223226
<Filter>src</Filter>
224227
</ClCompile>

builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
</ClCompile>
196196
<ClCompile Include="..\..\..\..\src\config\url.cpp" />
197197
<ClCompile Include="..\..\..\..\src\config\utilities.cpp" />
198+
<ClCompile Include="..\..\..\..\src\config\version.cpp" />
198199
<ClCompile Include="..\..\..\..\src\crypto\aes256.cpp" />
199200
<ClCompile Include="..\..\..\..\src\crypto\der_parser.cpp" />
200201
<ClCompile Include="..\..\..\..\src\crypto\ec_context.cpp" />
@@ -357,6 +358,7 @@
357358
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\transaction.hpp" />
358359
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\url.hpp" />
359360
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\utilities.hpp" />
361+
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\version.hpp" />
360362
<ClInclude Include="..\..\..\..\include\bitcoin\system\constants.hpp" />
361363
<ClInclude Include="..\..\..\..\include\bitcoin\system\constraints.hpp" />
362364
<ClInclude Include="..\..\..\..\include\bitcoin\system\crypto\aes256.hpp" />

builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@
381381
<ClCompile Include="..\..\..\..\src\config\utilities.cpp">
382382
<Filter>src\config</Filter>
383383
</ClCompile>
384+
<ClCompile Include="..\..\..\..\src\config\version.cpp">
385+
<Filter>src\config</Filter>
386+
</ClCompile>
384387
<ClCompile Include="..\..\..\..\src\crypto\aes256.cpp">
385388
<Filter>src\crypto</Filter>
386389
</ClCompile>
@@ -821,6 +824,9 @@
821824
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\utilities.hpp">
822825
<Filter>include\bitcoin\system\config</Filter>
823826
</ClInclude>
827+
<ClInclude Include="..\..\..\..\include\bitcoin\system\config\version.hpp">
828+
<Filter>include\bitcoin\system\config</Filter>
829+
</ClInclude>
824830
<ClInclude Include="..\..\..\..\include\bitcoin\system\constants.hpp">
825831
<Filter>include\bitcoin\system</Filter>
826832
</ClInclude>

include/bitcoin/system/config/config.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@
4141
#include <bitcoin/system/config/transaction.hpp>
4242
#include <bitcoin/system/config/url.hpp>
4343
#include <bitcoin/system/config/utilities.hpp>
44+
#include <bitcoin/system/config/version.hpp>
4445

4546
#endif
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
3+
*
4+
* This file is part of libbitcoin.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
#ifndef LIBBITCOIN_SYSTEM_CONFIG_VERSION_HPP
20+
#define LIBBITCOIN_SYSTEM_CONFIG_VERSION_HPP
21+
22+
#include <memory>
23+
#include <bitcoin/system/define.hpp>
24+
25+
namespace libbitcoin {
26+
namespace system {
27+
namespace config {
28+
29+
/// Container for a protocol version tuple with up to four segments.
30+
/// Segments are non-negative integers, padded with zeros for fewer than four.
31+
/// The format is major.minor[.subminor[.patch]] with at least one dot.
32+
class BC_API version
33+
{
34+
public:
35+
typedef std::shared_ptr<version> ptr;
36+
37+
DEFAULT_COPY_MOVE_DESTRUCT(version);
38+
39+
version() NOEXCEPT;
40+
41+
/// Deserialize from dotted string (throws on invalid format).
42+
version(const std::string& version_str) THROWS;
43+
44+
/// Construct from individual segments (2 to 4, pads with zeros).
45+
version(uint32_t major, uint32_t minor, uint32_t subminor={},
46+
uint32_t patch={}) NOEXCEPT;
47+
48+
/// Properties.
49+
/// -----------------------------------------------------------------------
50+
51+
/// Access to the internal segments array.
52+
const std::array<uint32_t, 4>& segments() const NOEXCEPT;
53+
54+
/// Methods.
55+
/// -----------------------------------------------------------------------
56+
57+
/// Serialize to dot string, omitting trailing zero segments (minimum 2).
58+
std::string to_string() const NOEXCEPT;
59+
60+
/// Operators.
61+
/// -----------------------------------------------------------------------
62+
63+
/// Deserialize from input stream (throws on invalid format).
64+
friend std::istream& operator>>(std::istream& input, version& argument) THROWS;
65+
66+
/// Serialize to output stream.
67+
friend std::ostream& operator<<(std::ostream& output,
68+
const version& argument) NOEXCEPT;
69+
70+
private:
71+
// This is not thread safe.
72+
std::array<uint32_t, 4> segments_;
73+
};
74+
75+
/// Lexicographical comparison.
76+
BC_API bool operator==(const version& left, const version& right) NOEXCEPT;
77+
BC_API bool operator!=(const version& left, const version& right) NOEXCEPT;
78+
BC_API bool operator<(const version& left, const version& right) NOEXCEPT;
79+
BC_API bool operator<=(const version& left, const version& right) NOEXCEPT;
80+
BC_API bool operator>(const version& left, const version& right) NOEXCEPT;
81+
BC_API bool operator>=(const version& left, const version& right) NOEXCEPT;
82+
83+
typedef std::vector<version> versions;
84+
85+
} // namespace config
86+
} // namespace system
87+
} // namespace libbitcoin
88+
89+
namespace std
90+
{
91+
template<>
92+
struct hash<bc::system::config::version>
93+
{
94+
size_t operator()(const bc::system::config::version& value) const NOEXCEPT
95+
{
96+
return std::hash<std::string>{}(value.to_string());
97+
}
98+
};
99+
} // namespace std
100+
101+
#endif

src/config/version.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
3+
*
4+
* This file is part of libbitcoin.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
#include <bitcoin/system/config/version.hpp>
20+
21+
#include <algorithm>
22+
#include <sstream>
23+
#include <bitcoin/system/data/data.hpp>
24+
#include <bitcoin/system/define.hpp>
25+
#include <bitcoin/system/math/math.hpp>
26+
#include <bitcoin/system/serial/serial.hpp>
27+
28+
namespace libbitcoin {
29+
namespace system {
30+
namespace config {
31+
32+
// Contructors.
33+
// ----------------------------------------------------------------------------
34+
35+
// Default version is 0.0.0.0 and serializes as "0.0".
36+
version::version() NOEXCEPT
37+
: segments_{ 0, 0, 0, 0 }
38+
{
39+
}
40+
41+
version::version(const std::string& version) THROWS
42+
{
43+
std::istringstream(version) >> (*this);
44+
}
45+
46+
version::version(uint32_t major, uint32_t minor, uint32_t subminor,
47+
uint32_t patch) NOEXCEPT
48+
: segments_{ major, minor, subminor, patch }
49+
{
50+
}
51+
52+
// Properties.
53+
// ----------------------------------------------------------------------------
54+
55+
const std::array<uint32_t, 4>& version::segments() const NOEXCEPT
56+
{
57+
return segments_;
58+
}
59+
60+
// Methods.
61+
// ----------------------------------------------------------------------------
62+
63+
std::string version::to_string() const NOEXCEPT
64+
{
65+
std::ostringstream value{};
66+
value << (*this);
67+
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
68+
return value.str();
69+
BC_POP_WARNING()
70+
}
71+
72+
// Operators.
73+
// ----------------------------------------------------------------------------
74+
75+
bool operator==(const version& left, const version& right) NOEXCEPT
76+
{
77+
return left.segments() == right.segments();
78+
}
79+
80+
bool operator!=(const version& left, const version& right) NOEXCEPT
81+
{
82+
return !(left == right);
83+
}
84+
85+
bool operator<(const version& left, const version& right) NOEXCEPT
86+
{
87+
return std::lexicographical_compare(
88+
left.segments().begin(), left.segments().end(),
89+
right.segments().begin(), right.segments().end());
90+
}
91+
92+
bool operator<=(const version& left, const version& right) NOEXCEPT
93+
{
94+
return left < right || left == right;
95+
}
96+
97+
bool operator>(const version& left, const version& right) NOEXCEPT
98+
{
99+
return right < left;
100+
}
101+
102+
bool operator>=(const version& left, const version& right) NOEXCEPT
103+
{
104+
return right <= left;
105+
}
106+
107+
std::istream& operator>>(std::istream& input,
108+
version& argument) THROWS
109+
{
110+
std::string value;
111+
input >> value;
112+
113+
using namespace system;
114+
const auto tokens = system::split(value, ".");
115+
const auto count = tokens.size();
116+
if (count < 2u || count > 4u)
117+
throw istream_exception(value);
118+
119+
for (size_t index{}; index < count; ++index)
120+
if (!deserialize(argument.segments_.at(index), tokens.at(index)))
121+
throw istream_exception(value);
122+
123+
return input;
124+
}
125+
126+
std::ostream& operator<<(std::ostream& output,
127+
const version& argument) NOEXCEPT
128+
{
129+
size_t last{ 3 };
130+
while (last > 1u && is_zero(argument.segments_.at(last)))
131+
--last;
132+
133+
for (size_t index{}; index <= last; ++index)
134+
{
135+
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
136+
if (!is_zero(index)) output << '.';
137+
output << argument.segments_.at(index);
138+
BC_POP_WARNING()
139+
}
140+
141+
return output;
142+
}
143+
144+
} // namespace config
145+
} // namespace system
146+
} // namespace libbitcoin

0 commit comments

Comments
 (0)