1 /******************************************************************************
3 * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License *
7 * as published by the Free Software Foundation; either version 2 *
8 * of the License, or (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software Foundation *
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ******************************************************************************/
20 #include "base/object-packer.hpp"
21 #include "base/value.hpp"
22 #include "base/string.hpp"
23 #include "base/array.hpp"
24 #include "base/dictionary.hpp"
25 #include <BoostTestTargetConfig.h>
27 #include <initializer_list>
31 using namespace icinga;
34 union CharU2SConverter
47 * Avoid implementation-defined overflows during unsigned to signed casts
49 static inline char UIntToByte(unsigned i)
54 CharU2SConverter converter;
62 union CharS2UConverter
75 * Avoid implementation-defined underflows during signed to unsigned casts
77 static inline unsigned ByteToUInt(char c)
82 CharS2UConverter converter;
90 * Compare the expected output with the actual output
92 static inline bool ComparePackObjectResult(const String& actualOutput, const std::initializer_list<int>& out)
94 if (actualOutput.GetLength() != out.size())
97 auto actualOutputPos = actualOutput.Begin();
98 for (auto byte : out) {
99 if (*actualOutputPos != UIntToByte(byte))
109 * Pack the given input and compare with the expected output
111 static inline bool AssertPackObjectResult(Value in, std::initializer_list<int> out)
113 auto actualOutput = PackObject(in);
114 bool equal = ComparePackObjectResult(actualOutput, out);
117 std::ostringstream buf;
118 buf << std::setw(2) << std::setfill('0') << std::setbase(16);
127 for (char c : actualOutput) {
128 buf << ByteToUInt(c);
132 BOOST_TEST_MESSAGE(buf.str());
138 BOOST_AUTO_TEST_SUITE(object_packer)
140 BOOST_AUTO_TEST_CASE(pack_null)
142 BOOST_CHECK(AssertPackObjectResult(Empty, {0}));
145 BOOST_AUTO_TEST_CASE(pack_false)
147 BOOST_CHECK(AssertPackObjectResult(false, {1}));
150 BOOST_AUTO_TEST_CASE(pack_true)
152 BOOST_CHECK(AssertPackObjectResult(true, {2}));
155 BOOST_AUTO_TEST_CASE(pack_number)
157 BOOST_CHECK(AssertPackObjectResult(42.125, {
161 64, 69, 16, 0, 0, 0, 0, 0
165 BOOST_AUTO_TEST_CASE(pack_string)
167 BOOST_CHECK(AssertPackObjectResult(
170 "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
171 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
172 "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
173 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
174 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
175 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
176 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
177 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
178 // some keyboard-independent non-ASCII unicode characters
185 0, 0, 0, 0, 0, 0, 0, 137,
187 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
188 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
189 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
190 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
191 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
192 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
193 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
194 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
196 195, 161, 195, 169, 195, 173, 195, 179, 195, 186
201 BOOST_AUTO_TEST_CASE(pack_array)
203 BOOST_CHECK(AssertPackObjectResult(
204 (Array::Ptr)new Array({Empty, false, true, 42.125, "foobar"}),
209 0, 0, 0, 0, 0, 0, 0, 5,
218 64, 69, 16, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 6,
222 102, 111, 111, 98, 97, 114
227 BOOST_AUTO_TEST_CASE(pack_object)
229 BOOST_CHECK(AssertPackObjectResult(
230 (Dictionary::Ptr)new Dictionary({
235 {"foobar", "foobar"},
236 {"[]", (Array::Ptr)new Array()}
242 0, 0, 0, 0, 0, 0, 0, 6,
244 0, 0, 0, 0, 0, 0, 0, 6,
245 52, 50, 46, 49, 50, 53,
248 64, 69, 16, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 2,
252 // (Array::Ptr)new Array()
254 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 5,
257 102, 97, 108, 115, 101,
261 0, 0, 0, 0, 0, 0, 0, 6,
262 102, 111, 111, 98, 97, 114,
265 0, 0, 0, 0, 0, 0, 0, 6,
266 102, 111, 111, 98, 97, 114,
268 0, 0, 0, 0, 0, 0, 0, 4,
273 0, 0, 0, 0, 0, 0, 0, 4,
281 BOOST_AUTO_TEST_SUITE_END()