Hazelcast C++ Client
Hazelcast C++ Client Library
Loading...
Searching...
No Matches
compact.cpp
1/*
2 * Copyright (c) 2008-2025, Hazelcast, Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <utility>
18#include <algorithm>
19#include <thread>
20#include <chrono>
21#include <functional>
22
23#include <boost/property_tree/json_parser.hpp>
24
25#include "hazelcast/client/serialization/serialization.h"
26#include "hazelcast/client/serialization/field_kind.h"
27#include "hazelcast/client/serialization/pimpl/compact/schema.h"
28#include "hazelcast/client/serialization/generic_record_builder.h"
29#include "hazelcast/client/serialization/generic_record.h"
30#include "hazelcast/client/protocol/codec/codecs.h"
31#include "hazelcast/client/spi/impl/ClientInvocation.h"
32#include "hazelcast/client/spi/ClientContext.h"
33#include "hazelcast/client/cluster.h"
34#include "hazelcast/client/spi/impl/ClientExecutionServiceImpl.h"
35#include "hazelcast/util/Bits.h"
36#include "hazelcast/client/client_properties.h"
37
38namespace hazelcast {
39namespace client {
40namespace serialization {
41namespace pimpl {
42
43field_descriptor::field_descriptor(field_kind k, int32_t i, int32_t o, int8_t b)
44 : kind{ k }
45 , index{ i }
46 , offset{ o }
47 , bit_offset{ b }
48{
49}
50
51bool
52operator==(const field_descriptor& x, const field_descriptor& y)
53{
54 return x.kind == y.kind;
55}
56
57std::ostream&
58operator<<(std::ostream& os, const field_descriptor& fd)
59{
60 return os << "FieldDescriptor{"
61 << "kind=" << fd.kind << ", index=" << fd.index
62 << ", offset=" << fd.offset << ", bitOffset=" << fd.bit_offset
63 << '}';
64}
65
66} // namespace pimpl
67} // namespace serialization
68} // namespace client
69} // namespace hazelcast
70
71namespace hazelcast {
72namespace client {
73namespace serialization {
74namespace generic_record {
75
77generic_record_builder::set_string(std::string field_name, const char* cstr)
78{
79 return set_string(field_name,
80 cstr ? boost::optional<std::string>{ std::string{ cstr } }
81 : boost::none);
82}
83
85 : strategy_{ strategy::default_builder }
86 , already_built_{ false }
87 , writer_or_schema_{ pimpl::schema_writer{ std::move(type_name) } }
88{
89}
90
91generic_record_builder::generic_record_builder(std::shared_ptr<pimpl::schema> record_schema)
92 : strategy_{ strategy::schema_bounded }
93 , already_built_{ false }
94 , writer_or_schema_{ std::move(record_schema) }
95{
96}
97
99 std::shared_ptr<pimpl::schema> record_schema,
100 std::unordered_map<std::string, boost::any> objects)
101 : strategy_{ strategy::cloner }
102 , already_built_{ false }
103 , objects_{ std::move(objects) }
104 , writer_or_schema_{ std::move(record_schema) }
105{
106}
107
108void
109generic_record_builder::check_type_with_schema(const pimpl::schema& schema,
110 const std::string& field_name,
111 field_kind kind) const
112{
113 boost::optional<pimpl::field_descriptor> fd = schema.get_field(field_name);
114
115 if (!fd) {
116 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization{
117 boost::str(boost::format("Invalid field name: '%1%' for %2%") %
118 field_name % schema) });
119 }
120
121 if (fd->kind != kind) {
122 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization{ boost::str(
123 boost::format(
124 "Invalid field kind: '%1%' for %2%, expected : %3%, given : %4%") %
125 field_name % schema % fd->kind % kind) });
126 }
127}
128
131{
132 if (strategy_ == strategy::default_builder) {
133 pimpl::schema_writer& writer =
134 boost::get<pimpl::schema_writer>(writer_or_schema_);
135
136 already_built_ = true;
137 return generic_record{ std::make_shared<pimpl::schema>(std::move(writer).build()), std::move(objects_) };
138 } else {
139 std::shared_ptr<pimpl::schema> schema = boost::get<std::shared_ptr<pimpl::schema>>(writer_or_schema_);
140
141 if (strategy_ == strategy::schema_bounded) {
142 const auto& fields = schema->fields();
143
144 for (const auto& p : fields) {
145 const std::string& field_name = p.first;
146
147 if (objects_.find(field_name) == end(objects_)) {
148 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization{
149 "Found an unset field " + field_name +
150 ". All the fields must be set before build" });
151 }
152 }
153 }
154
155 already_built_ = true;
156 return generic_record{ std::move(schema), std::move(objects_) };
157 }
158}
159
161generic_record_builder::set_boolean(std::string field_name, bool value)
162{
163 return write(std::move(field_name), value, field_kind::BOOLEAN);
164}
165
167generic_record_builder::set_int8(std::string field_name, int8_t value)
168{
169 return write(std::move(field_name), value, field_kind::INT8);
170}
171
173generic_record_builder::set_int16(std::string field_name, int16_t value)
174{
175 return write(std::move(field_name), value, field_kind::INT16);
176}
177
179generic_record_builder::set_int32(std::string field_name, int32_t value)
180{
181 return write(std::move(field_name), value, field_kind::INT32);
182}
183
185generic_record_builder::set_int64(std::string field_name, int64_t value)
186{
187 return write(std::move(field_name), value, field_kind::INT64);
188}
189
191generic_record_builder::set_float32(std::string field_name, float value)
192{
193 return write(std::move(field_name), value, field_kind::FLOAT32);
194}
195
197generic_record_builder::set_float64(std::string field_name, double value)
198{
199 return write(std::move(field_name), value, field_kind::FLOAT64);
200}
201
204 boost::optional<bool> value)
205{
206 return write(std::move(field_name), value, field_kind::NULLABLE_BOOLEAN);
207}
208
211 boost::optional<int8_t> value)
212{
213 return write(std::move(field_name), value, field_kind::NULLABLE_INT8);
214}
215
218 boost::optional<int16_t> value)
219{
220 return write(std::move(field_name), value, field_kind::NULLABLE_INT16);
221}
222
225 boost::optional<int32_t> value)
226{
227 return write(std::move(field_name), value, field_kind::NULLABLE_INT32);
228}
229
232 boost::optional<int64_t> value)
233{
234 return write(std::move(field_name), value, field_kind::NULLABLE_INT64);
235}
236
239 boost::optional<float> value)
240{
241 return write(std::move(field_name), value, field_kind::NULLABLE_FLOAT32);
242}
243
246 boost::optional<double> value)
247{
248 return write(std::move(field_name), value, field_kind::NULLABLE_FLOAT64);
249}
250
253 std::string field_name,
254 boost::optional<generic_record> value)
255{
256 return write(std::move(field_name), std::move(value), field_kind::COMPACT);
257}
258
261 boost::optional<big_decimal> value)
262{
263 return write(std::move(field_name), value, field_kind::DECIMAL);
264}
265
267generic_record_builder::set_time(std::string field_name,
268 boost::optional<local_time> value)
269{
270 return write(std::move(field_name), value, field_kind::TIME);
271}
272
274generic_record_builder::set_date(std::string field_name,
275 boost::optional<local_date> value)
276{
277 return write(std::move(field_name), value, field_kind::DATE);
278}
279
282 boost::optional<local_date_time> value)
283{
284 return write(std::move(field_name), value, field_kind::TIMESTAMP);
285}
286
289 std::string field_name,
290 boost::optional<offset_date_time> value)
291{
292 return write(std::move(field_name), value, field_kind::TIMESTAMP_WITH_TIMEZONE);
293}
294
297 boost::optional<std::string> value)
298{
299 return write(std::move(field_name), std::move(value), field_kind::STRING);
300}
301
304 std::string field_name,
305 boost::optional<std::vector<bool>> value)
306{
307 return write(
308 std::move(field_name), std::move(value), field_kind::ARRAY_OF_BOOLEAN);
309}
310
313 std::vector<bool> value)
314{
316 std::move(field_name), boost::optional<std::vector<bool>>(std::move(value)));
317}
318
321 std::initializer_list<bool> value)
322{
324 std::move(field_name), std::vector<bool>(value));
325}
326
329 std::string field_name,
330 boost::optional<std::vector<int8_t>> value)
331{
332 return write(std::move(field_name), std::move(value), field_kind::ARRAY_OF_INT8);
333}
334
337 std::vector<int8_t> value)
338{
339 return set_array_of_int8(std::move(field_name),
340 boost::optional<std::vector<int8_t>>(std::move(value)));
341}
342
345 std::initializer_list<int8_t> value)
346{
347 return set_array_of_int8(std::move(field_name),
348 std::vector<int8_t>(value));
349}
350
353 std::string field_name,
354 boost::optional<std::vector<int16_t>> value)
355{
356 return write(
357 std::move(field_name), std::move(value), field_kind::ARRAY_OF_INT16);
358}
359
362 std::vector<int16_t> value)
363{
364 return set_array_of_int16(
365 std::move(field_name), boost::optional<std::vector<int16_t>>(std::move(value)));
366}
367
370 std::initializer_list<int16_t> value)
371{
372 return set_array_of_int16(
373 std::move(field_name), std::vector<int16_t>(value));
374}
375
378 std::string field_name,
379 boost::optional<std::vector<int32_t>> value)
380{
381 return write(
382 std::move(field_name), std::move(value), field_kind::ARRAY_OF_INT32);
383}
384
387 std::vector<int32_t> value)
388{
389 return set_array_of_int32(
390 std::move(field_name), boost::optional<std::vector<int32_t>>(std::move(value)));
391}
392
395 std::initializer_list<int32_t> value)
396{
397 return set_array_of_int32(
398 std::move(field_name), std::vector<int32_t>(value));
399}
400
403 std::string field_name,
404 boost::optional<std::vector<int64_t>> value)
405{
406 return write(
407 std::move(field_name), std::move(value), field_kind::ARRAY_OF_INT64);
408}
409
412 std::vector<int64_t> value)
413{
414 return set_array_of_int64(
415 std::move(field_name), boost::optional<std::vector<int64_t>>(std::move(value)));
416}
417
420 std::initializer_list<int64_t> value)
421{
422 return set_array_of_int64(
423 std::move(field_name), std::vector<int64_t>(value));
424}
425
428 std::string field_name,
429 boost::optional<std::vector<float>> value)
430{
431 return write(
432 std::move(field_name), std::move(value), field_kind::ARRAY_OF_FLOAT32);
433}
434
437 std::vector<float> value)
438{
440 std::move(field_name), boost::optional<std::vector<float>>(std::move(value)));
441}
442
445 std::initializer_list<float> value)
446{
448 std::move(field_name), std::vector<float>(value));
449}
450
453 std::string field_name,
454 boost::optional<std::vector<double>> value)
455{
456 return write(
457 std::move(field_name), std::move(value), field_kind::ARRAY_OF_FLOAT64);
458}
459
462 std::vector<double> value)
463{
465 std::move(field_name), boost::optional<std::vector<double>>(std::move(value)));
466}
467
470 std::initializer_list<double> value)
471{
473 std::move(field_name), std::vector<double>(value));
474}
475
476template<typename T>
477std::vector<boost::optional<T>>
478to_nullable(std::vector<T> value)
479{
480 std::vector<boost::optional<T>> value_opt;
481
482 value_opt.reserve(value.size());
483
484 transform(begin(value), end(value), back_inserter(value_opt), [](T value) {
485 return boost::optional<T>{ value };
486 });
487
488 return value_opt;
489}
490
491generic_record_builder&
493 std::string field_name,
494 boost::optional<std::vector<boost::optional<bool>>> value)
495{
496 return write(std::move(field_name),
497 std::move(value),
498 field_kind::ARRAY_OF_NULLABLE_BOOLEAN);
499}
500
503 std::vector<bool> value)
504{
505 return set_array_of_nullable_boolean(std::move(field_name),
506 to_nullable(std::move(value)));
507}
508
511 std::initializer_list<bool> value)
512{
513 return set_array_of_nullable_boolean(std::move(field_name),
514 std::vector<bool>(value));
515}
516
519 std::string field_name,
520 boost::optional<std::vector<boost::optional<int8_t>>> value)
521{
522 return write(
523 std::move(field_name), std::move(value), field_kind::ARRAY_OF_NULLABLE_INT8);
524}
525
528 std::vector<int8_t> value)
529{
530 return set_array_of_nullable_int8(std::move(field_name),
531 to_nullable(std::move(value)));
532}
533
536 std::initializer_list<int8_t> value)
537{
538 return set_array_of_nullable_int8(std::move(field_name),
539 std::vector<int8_t>(value));
540}
541
544 std::string field_name,
545 boost::optional<std::vector<boost::optional<int16_t>>> value)
546{
547 return write(
548 std::move(field_name), std::move(value), field_kind::ARRAY_OF_NULLABLE_INT16);
549}
550
553 std::vector<int16_t> value)
554{
555 return set_array_of_nullable_int16(std::move(field_name),
556 to_nullable(std::move(value)));
557}
558
561 std::initializer_list<int16_t> value)
562{
563 return set_array_of_nullable_int16(std::move(field_name),
564 std::vector<int16_t>(value));
565}
566
569 std::string field_name,
570 boost::optional<std::vector<boost::optional<int32_t>>> value)
571{
572 return write(
573 std::move(field_name), std::move(value), field_kind::ARRAY_OF_NULLABLE_INT32);
574}
575
578 std::vector<int32_t> value)
579{
580 return set_array_of_nullable_int32(std::move(field_name),
581 to_nullable(std::move(value)));
582}
583
586 std::initializer_list<int32_t> value)
587{
588 return set_array_of_nullable_int32(std::move(field_name),
589 std::vector<int32_t>(value));
590}
591
594 std::string field_name,
595 boost::optional<std::vector<boost::optional<int64_t>>> value)
596{
597 return write(
598 std::move(field_name), std::move(value), field_kind::ARRAY_OF_NULLABLE_INT64);
599}
600
603 std::vector<int64_t> value)
604{
605 return set_array_of_nullable_int64(std::move(field_name),
606 to_nullable(std::move(value)));
607}
608
611 std::initializer_list<int64_t> value)
612{
613 return set_array_of_nullable_int64(std::move(field_name),
614 std::vector<int64_t>(value));
615}
616
619 std::string field_name,
620 boost::optional<std::vector<boost::optional<float>>> value)
621{
622 return write(std::move(field_name),
623 std::move(value),
624 field_kind::ARRAY_OF_NULLABLE_FLOAT32);
625}
626
629 std::vector<float> value)
630{
631 return set_array_of_nullable_float32(std::move(field_name),
632 to_nullable(std::move(value)));
633}
634
637 std::initializer_list<float> value)
638{
639 return set_array_of_nullable_float32(std::move(field_name),
640 std::vector<float>(value));
641}
642
645 std::string field_name,
646 boost::optional<std::vector<boost::optional<double>>> value)
647{
648 return write(std::move(field_name),
649 std::move(value),
650 field_kind::ARRAY_OF_NULLABLE_FLOAT64);
651}
652
655 std::vector<double> value)
656{
657 return set_array_of_nullable_float64(std::move(field_name),
658 to_nullable(std::move(value)));
659}
660
663 std::initializer_list<double> value)
664{
665 return set_array_of_nullable_float64(std::move(field_name),
666 std::vector<double>(value));
667}
668
671 std::string field_name,
672 boost::optional<std::vector<boost::optional<std::string>>> value)
673{
674 return write(
675 std::move(field_name), std::move(value), field_kind::ARRAY_OF_STRING);
676}
677
680 std::string field_name,
681 boost::optional<std::vector<boost::optional<big_decimal>>> value)
682{
683 return write(
684 std::move(field_name), std::move(value), field_kind::ARRAY_OF_DECIMAL);
685}
686
689 std::string field_name,
690 boost::optional<std::vector<boost::optional<local_time>>> value)
691{
692 return write(std::move(field_name), std::move(value), field_kind::ARRAY_OF_TIME);
693}
694
697 std::string field_name,
698 boost::optional<std::vector<boost::optional<local_date>>> value)
699{
700 return write(std::move(field_name), std::move(value), field_kind::ARRAY_OF_DATE);
701}
702
705 std::string field_name,
706 boost::optional<std::vector<boost::optional<local_date_time>>> value)
707{
708 return write(
709 std::move(field_name), std::move(value), field_kind::ARRAY_OF_TIMESTAMP);
710}
711
714 std::string field_name,
715 boost::optional<std::vector<boost::optional<offset_date_time>>> value)
716{
717 return write(std::move(field_name),
718 std::move(value),
719 field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE);
720}
721
724 std::string field_name,
725 boost::optional<std::vector<boost::optional<generic_record>>> value)
726{
727 return write(
728 std::move(field_name), std::move(value), field_kind::ARRAY_OF_COMPACT);
729}
730
731generic_record::generic_record(
732 std::shared_ptr<pimpl::schema> s,
733 std::unordered_map<std::string, boost::any> objects)
734 : schema_{ std::move(s) }
735 , objects_{ std::move(objects) }
736{
737}
738
739const pimpl::schema&
740generic_record::get_schema() const
741{
742 return *schema_;
743}
744
745generic_record_builder
747{
748 return generic_record_builder{ schema_ };
749}
750
753{
754 return generic_record_builder{ schema_, objects_ };
755}
756
757std::unordered_set<std::string>
759{
760 std::unordered_set<std::string> field_names;
761
762 const auto& fields = schema_->fields();
763
764 transform(begin(fields),
765 end(fields),
766 inserter(field_names, end(field_names)),
767 [](const std::pair<std::string, pimpl::field_descriptor>& p) {
768 return p.first;
769 });
770
771 return field_names;
772}
773
774field_kind
775generic_record::get_field_kind(const std::string& field_name) const
776{
777 auto descriptor = schema_->get_field(field_name);
778
779 if (!descriptor) {
780 return field_kind::NOT_AVAILABLE;
781 }
782
783 return descriptor->kind;
784}
785
786bool
787generic_record::has_field(std::string field_name) const
788{
789 return objects_.find(field_name) != end(objects_);
790}
791
792bool
793generic_record::get_boolean(const std::string& field_name) const
794{
795 return get_non_null<bool>(
796 field_name, field_kind::BOOLEAN, field_kind::NULLABLE_BOOLEAN, "Boolean");
797}
798
799bool&
800generic_record::get_boolean(const std::string& field_name)
801{
802 return get_non_null<bool>(
803 field_name, field_kind::BOOLEAN, field_kind::NULLABLE_BOOLEAN, "Boolean");
804}
805
806int8_t
807generic_record::get_int8(const std::string& field_name) const
808{
809 return get_non_null<int8_t>(
810 field_name, field_kind::INT8, field_kind::NULLABLE_INT8, "Int8");
811}
812
813int8_t&
814generic_record::get_int8(const std::string& field_name)
815{
816 return get_non_null<int8_t>(
817 field_name, field_kind::INT8, field_kind::NULLABLE_INT8, "Int8");
818}
819
820int16_t
821generic_record::get_int16(const std::string& field_name) const
822{
823 return get_non_null<int16_t>(
824 field_name, field_kind::INT16, field_kind::NULLABLE_INT16, "Int16");
825}
826
827int16_t&
828generic_record::get_int16(const std::string& field_name)
829{
830 return get_non_null<int16_t>(
831 field_name, field_kind::INT16, field_kind::NULLABLE_INT16, "Int16");
832}
833
834int32_t
835generic_record::get_int32(const std::string& field_name) const
836{
837 return get_non_null<int32_t>(
838 field_name, field_kind::INT32, field_kind::NULLABLE_INT32, "Int32");
839}
840
841int32_t&
842generic_record::get_int32(const std::string& field_name)
843{
844 return get_non_null<int32_t>(
845 field_name, field_kind::INT32, field_kind::NULLABLE_INT32, "Int32");
846}
847
848int64_t
849generic_record::get_int64(const std::string& field_name) const
850{
851 return get_non_null<int64_t>(
852 field_name, field_kind::INT64, field_kind::NULLABLE_INT64, "Int64");
853}
854
855int64_t&
856generic_record::get_int64(const std::string& field_name)
857{
858 return get_non_null<int64_t>(
859 field_name, field_kind::INT64, field_kind::NULLABLE_INT64, "Int64");
860}
861
862float
863generic_record::get_float32(const std::string& field_name) const
864{
865 return get_non_null<float>(
866 field_name, field_kind::FLOAT32, field_kind::NULLABLE_FLOAT32, "Float32");
867}
868
869float&
870generic_record::get_float32(const std::string& field_name)
871{
872 return get_non_null<float>(
873 field_name, field_kind::FLOAT32, field_kind::NULLABLE_FLOAT32, "Float32");
874}
875
876double
877generic_record::get_float64(const std::string& field_name) const
878{
879 return get_non_null<double>(
880 field_name, field_kind::FLOAT64, field_kind::NULLABLE_FLOAT64, "Float64");
881}
882
883double&
884generic_record::get_float64(const std::string& field_name)
885{
886 return get_non_null<double>(
887 field_name, field_kind::FLOAT64, field_kind::NULLABLE_FLOAT64, "Float64");
888}
889
890boost::optional<bool>
891generic_record::get_nullable_boolean(const std::string& field_name) const
892{
893 return get<boost::optional<bool>>(field_name, field_kind::NULLABLE_BOOLEAN);
894}
895
896boost::optional<bool>&
897generic_record::get_nullable_boolean(const std::string& field_name)
898{
899 return get<boost::optional<bool>>(field_name, field_kind::NULLABLE_BOOLEAN);
900}
901
902boost::optional<int8_t>
903generic_record::get_nullable_int8(const std::string& field_name) const
904{
905 return get<boost::optional<int8_t>>(field_name, field_kind::NULLABLE_INT8);
906}
907
908boost::optional<int8_t>&
909generic_record::get_nullable_int8(const std::string& field_name)
910{
911 return get<boost::optional<int8_t>>(field_name, field_kind::NULLABLE_INT8);
912}
913
914boost::optional<int16_t>
915generic_record::get_nullable_int16(const std::string& field_name) const
916{
917 return get<boost::optional<int16_t>>(field_name,
918 field_kind::NULLABLE_INT16);
919}
920
921boost::optional<int16_t>&
922generic_record::get_nullable_int16(const std::string& field_name)
923{
924 return get<boost::optional<int16_t>>(field_name,
925 field_kind::NULLABLE_INT16);
926}
927
928boost::optional<int32_t>
929generic_record::get_nullable_int32(const std::string& field_name) const
930{
931 return get<boost::optional<int32_t>>(field_name,
932 field_kind::NULLABLE_INT32);
933}
934
935boost::optional<int32_t>&
936generic_record::get_nullable_int32(const std::string& field_name)
937{
938 return get<boost::optional<int32_t>>(field_name,
939 field_kind::NULLABLE_INT32);
940}
941
942boost::optional<int64_t>
943generic_record::get_nullable_int64(const std::string& field_name) const
944{
945 return get<boost::optional<int64_t>>(field_name,
946 field_kind::NULLABLE_INT64);
947}
948
949boost::optional<int64_t>&
950generic_record::get_nullable_int64(const std::string& field_name)
951{
952 return get<boost::optional<int64_t>>(field_name,
953 field_kind::NULLABLE_INT64);
954}
955
956boost::optional<float>
957generic_record::get_nullable_float32(const std::string& field_name) const
958{
959 return get<boost::optional<float>>(field_name,
960 field_kind::NULLABLE_FLOAT32);
961}
962
963boost::optional<float>&
964generic_record::get_nullable_float32(const std::string& field_name)
965{
966 return get<boost::optional<float>>(field_name,
967 field_kind::NULLABLE_FLOAT32);
968}
969
970boost::optional<double>
971generic_record::get_nullable_float64(const std::string& field_name) const
972{
973 return get<boost::optional<double>>(field_name,
974 field_kind::NULLABLE_FLOAT64);
975}
976
977boost::optional<double>&
978generic_record::get_nullable_float64(const std::string& field_name)
979{
980 return get<boost::optional<double>>(field_name,
981 field_kind::NULLABLE_FLOAT64);
982}
983
984const boost::optional<std::string>&
985generic_record::get_string(const std::string& field_name) const
986{
987 return get<boost::optional<std::string>>(field_name, field_kind::STRING);
988}
989
990boost::optional<std::string>&
991generic_record::get_string(const std::string& field_name)
992{
993 return get<boost::optional<std::string>>(field_name, field_kind::STRING);
994}
995
996const boost::optional<generic_record>&
997generic_record::get_generic_record(const std::string& field_name) const
998{
999 return get<boost::optional<generic_record>>(field_name,
1000 field_kind::COMPACT);
1001}
1002
1003boost::optional<generic_record>&
1004generic_record::get_generic_record(const std::string& field_name)
1005{
1006 return get<boost::optional<generic_record>>(field_name,
1007 field_kind::COMPACT);
1008}
1009
1010const boost::optional<big_decimal>&
1011generic_record::get_decimal(const std::string& field_name) const
1012{
1013 return get<boost::optional<big_decimal>>(field_name, field_kind::DECIMAL);
1014}
1015
1016boost::optional<big_decimal>&
1017generic_record::get_decimal(const std::string& field_name)
1018{
1019 return get<boost::optional<big_decimal>>(field_name, field_kind::DECIMAL);
1020}
1021
1022const boost::optional<local_time>&
1023generic_record::get_time(const std::string& field_name) const
1024{
1025 return get<boost::optional<local_time>>(field_name, field_kind::TIME);
1026}
1027
1028boost::optional<local_time>&
1029generic_record::get_time(const std::string& field_name)
1030{
1031 return get<boost::optional<local_time>>(field_name, field_kind::TIME);
1032}
1033
1034const boost::optional<local_date>&
1035generic_record::get_date(const std::string& field_name) const
1036{
1037 return get<boost::optional<local_date>>(field_name, field_kind::DATE);
1038}
1039
1040boost::optional<local_date>&
1041generic_record::get_date(const std::string& field_name)
1042{
1043 return get<boost::optional<local_date>>(field_name, field_kind::DATE);
1044}
1045
1046const boost::optional<local_date_time>&
1047generic_record::get_timestamp(const std::string& field_name) const
1048{
1049 return get<boost::optional<local_date_time>>(field_name,
1050 field_kind::TIMESTAMP);
1051}
1052
1053boost::optional<local_date_time>&
1054generic_record::get_timestamp(const std::string& field_name)
1055{
1056 return get<boost::optional<local_date_time>>(field_name,
1057 field_kind::TIMESTAMP);
1058}
1059
1060const boost::optional<offset_date_time>&
1061generic_record::get_timestamp_with_timezone(const std::string& field_name) const
1062{
1063 return get<boost::optional<offset_date_time>>(
1064 field_name, field_kind::TIMESTAMP_WITH_TIMEZONE);
1065}
1066
1067boost::optional<offset_date_time>&
1069{
1070 return get<boost::optional<offset_date_time>>(
1071 field_name, field_kind::TIMESTAMP_WITH_TIMEZONE);
1072}
1073
1074const boost::optional<std::vector<bool>>&
1075generic_record::get_array_of_boolean(const std::string& field_name) const
1076{
1077 return get_array_of_primitive<bool>(field_name,
1078 field_kind::ARRAY_OF_BOOLEAN,
1079 field_kind::ARRAY_OF_NULLABLE_BOOLEAN,
1080 "boolean");
1081}
1082
1083boost::optional<std::vector<bool>>&
1084generic_record::get_array_of_boolean(const std::string& field_name)
1085{
1086 return get_array_of_primitive<bool>(field_name,
1087 field_kind::ARRAY_OF_BOOLEAN,
1088 field_kind::ARRAY_OF_NULLABLE_BOOLEAN,
1089 "boolean");
1090}
1091
1092const boost::optional<std::vector<int8_t>>&
1093generic_record::get_array_of_int8(const std::string& field_name) const
1094{
1095 return get_array_of_primitive<int8_t>(field_name,
1096 field_kind::ARRAY_OF_INT8,
1097 field_kind::ARRAY_OF_NULLABLE_INT8,
1098 "int8");
1099}
1100
1101boost::optional<std::vector<int8_t>>&
1102generic_record::get_array_of_int8(const std::string& field_name)
1103{
1104 return get_array_of_primitive<int8_t>(field_name,
1105 field_kind::ARRAY_OF_INT8,
1106 field_kind::ARRAY_OF_NULLABLE_INT8,
1107 "int8");
1108}
1109
1110const boost::optional<std::vector<int16_t>>&
1111generic_record::get_array_of_int16(const std::string& field_name) const
1112{
1113 return get_array_of_primitive<int16_t>(field_name,
1114 field_kind::ARRAY_OF_INT16,
1115 field_kind::ARRAY_OF_NULLABLE_INT16,
1116 "int16");
1117}
1118
1119boost::optional<std::vector<int16_t>>&
1120generic_record::get_array_of_int16(const std::string& field_name)
1121{
1122 return get_array_of_primitive<int16_t>(field_name,
1123 field_kind::ARRAY_OF_INT16,
1124 field_kind::ARRAY_OF_NULLABLE_INT16,
1125 "int16");
1126}
1127
1128const boost::optional<std::vector<int32_t>>&
1129generic_record::get_array_of_int32(const std::string& field_name) const
1130{
1131 return get_array_of_primitive<int32_t>(field_name,
1132 field_kind::ARRAY_OF_INT32,
1133 field_kind::ARRAY_OF_NULLABLE_INT32,
1134 "int32");
1135}
1136
1137boost::optional<std::vector<int32_t>>&
1138generic_record::get_array_of_int32(const std::string& field_name)
1139{
1140 return get_array_of_primitive<int32_t>(field_name,
1141 field_kind::ARRAY_OF_INT32,
1142 field_kind::ARRAY_OF_NULLABLE_INT32,
1143 "int32");
1144}
1145
1146const boost::optional<std::vector<int64_t>>&
1147generic_record::get_array_of_int64(const std::string& field_name) const
1148{
1149 return get_array_of_primitive<int64_t>(field_name,
1150 field_kind::ARRAY_OF_INT64,
1151 field_kind::ARRAY_OF_NULLABLE_INT64,
1152 "int64");
1153}
1154
1155boost::optional<std::vector<int64_t>>&
1156generic_record::get_array_of_int64(const std::string& field_name)
1157{
1158 return get_array_of_primitive<int64_t>(field_name,
1159 field_kind::ARRAY_OF_INT64,
1160 field_kind::ARRAY_OF_NULLABLE_INT64,
1161 "int64");
1162}
1163
1164const boost::optional<std::vector<float>>&
1165generic_record::get_array_of_float32(const std::string& field_name) const
1166{
1167 return get_array_of_primitive<float>(field_name,
1168 field_kind::ARRAY_OF_FLOAT32,
1169 field_kind::ARRAY_OF_NULLABLE_FLOAT32,
1170 "float32");
1171}
1172
1173boost::optional<std::vector<float>>&
1174generic_record::get_array_of_float32(const std::string& field_name)
1175{
1176 return get_array_of_primitive<float>(field_name,
1177 field_kind::ARRAY_OF_FLOAT32,
1178 field_kind::ARRAY_OF_NULLABLE_FLOAT32,
1179 "float32");
1180}
1181
1182const boost::optional<std::vector<double>>&
1183generic_record::get_array_of_float64(const std::string& field_name) const
1184{
1185 return get_array_of_primitive<double>(field_name,
1186 field_kind::ARRAY_OF_FLOAT64,
1187 field_kind::ARRAY_OF_NULLABLE_FLOAT64,
1188 "float64");
1189}
1190
1191boost::optional<std::vector<double>>&
1192generic_record::get_array_of_float64(const std::string& field_name)
1193{
1194 return get_array_of_primitive<double>(field_name,
1195 field_kind::ARRAY_OF_FLOAT64,
1196 field_kind::ARRAY_OF_NULLABLE_FLOAT64,
1197 "float64");
1198}
1199
1200const boost::optional<std::vector<boost::optional<bool>>>&
1202 const std::string& field_name) const
1203{
1204 return get_array_of_nullable<bool>(field_name,
1205 field_kind::ARRAY_OF_BOOLEAN,
1206 field_kind::ARRAY_OF_NULLABLE_BOOLEAN,
1207 "boolean");
1208}
1209
1210boost::optional<std::vector<boost::optional<bool>>>&
1212{
1213 return get_array_of_nullable<bool>(field_name,
1214 field_kind::ARRAY_OF_BOOLEAN,
1215 field_kind::ARRAY_OF_NULLABLE_BOOLEAN,
1216 "boolean");
1217}
1218
1219const boost::optional<std::vector<boost::optional<int8_t>>>&
1220generic_record::get_array_of_nullable_int8(const std::string& field_name) const
1221{
1222 return get_array_of_nullable<int8_t>(field_name,
1223 field_kind::ARRAY_OF_INT8,
1224 field_kind::ARRAY_OF_NULLABLE_INT8,
1225 "int8");
1226}
1227
1228boost::optional<std::vector<boost::optional<int8_t>>>&
1230{
1231 return get_array_of_nullable<int8_t>(field_name,
1232 field_kind::ARRAY_OF_INT8,
1233 field_kind::ARRAY_OF_NULLABLE_INT8,
1234 "int8");
1235}
1236
1237const boost::optional<std::vector<boost::optional<int16_t>>>&
1238generic_record::get_array_of_nullable_int16(const std::string& field_name) const
1239{
1240 return get_array_of_nullable<int16_t>(field_name,
1241 field_kind::ARRAY_OF_INT16,
1242 field_kind::ARRAY_OF_NULLABLE_INT16,
1243 "int16");
1244}
1245
1246boost::optional<std::vector<boost::optional<int16_t>>>&
1248{
1249 return get_array_of_nullable<int16_t>(field_name,
1250 field_kind::ARRAY_OF_INT16,
1251 field_kind::ARRAY_OF_NULLABLE_INT16,
1252 "int16");
1253}
1254
1255const boost::optional<std::vector<boost::optional<int32_t>>>&
1256generic_record::get_array_of_nullable_int32(const std::string& field_name) const
1257{
1258 return get_array_of_nullable<int32_t>(field_name,
1259 field_kind::ARRAY_OF_INT32,
1260 field_kind::ARRAY_OF_NULLABLE_INT32,
1261 "int32");
1262}
1263
1264boost::optional<std::vector<boost::optional<int32_t>>>&
1266{
1267 return get_array_of_nullable<int32_t>(field_name,
1268 field_kind::ARRAY_OF_INT32,
1269 field_kind::ARRAY_OF_NULLABLE_INT32,
1270 "int32");
1271}
1272
1273const boost::optional<std::vector<boost::optional<int64_t>>>&
1274generic_record::get_array_of_nullable_int64(const std::string& field_name) const
1275{
1276 return get_array_of_nullable<int64_t>(field_name,
1277 field_kind::ARRAY_OF_INT64,
1278 field_kind::ARRAY_OF_NULLABLE_INT64,
1279 "int64");
1280}
1281
1282boost::optional<std::vector<boost::optional<int64_t>>>&
1284{
1285 return get_array_of_nullable<int64_t>(field_name,
1286 field_kind::ARRAY_OF_INT64,
1287 field_kind::ARRAY_OF_NULLABLE_INT64,
1288 "int64");
1289}
1290
1291const boost::optional<std::vector<boost::optional<float>>>&
1293 const std::string& field_name) const
1294{
1295 return get_array_of_nullable<float>(field_name,
1296 field_kind::ARRAY_OF_FLOAT32,
1297 field_kind::ARRAY_OF_NULLABLE_FLOAT32,
1298 "float32");
1299}
1300
1301boost::optional<std::vector<boost::optional<float>>>&
1303{
1304 return get_array_of_nullable<float>(field_name,
1305 field_kind::ARRAY_OF_FLOAT32,
1306 field_kind::ARRAY_OF_NULLABLE_FLOAT32,
1307 "float32");
1308}
1309
1310const boost::optional<std::vector<boost::optional<double>>>&
1312 const std::string& field_name) const
1313{
1314 return get_array_of_nullable<double>(field_name,
1315 field_kind::ARRAY_OF_FLOAT64,
1316 field_kind::ARRAY_OF_NULLABLE_FLOAT64,
1317 "float64");
1318}
1319
1320boost::optional<std::vector<boost::optional<double>>>&
1322{
1323 return get_array_of_nullable<double>(field_name,
1324 field_kind::ARRAY_OF_FLOAT64,
1325 field_kind::ARRAY_OF_NULLABLE_FLOAT64,
1326 "float64");
1327}
1328
1329const boost::optional<std::vector<boost::optional<std::string>>>&
1330generic_record::get_array_of_string(const std::string& field_name) const
1331{
1332 return get<boost::optional<std::vector<boost::optional<std::string>>>>(
1333 field_name, field_kind::ARRAY_OF_STRING);
1334}
1335
1336boost::optional<std::vector<boost::optional<std::string>>>&
1337generic_record::get_array_of_string(const std::string& field_name)
1338{
1339 return get<boost::optional<std::vector<boost::optional<std::string>>>>(
1340 field_name, field_kind::ARRAY_OF_STRING);
1341}
1342
1343const boost::optional<std::vector<boost::optional<big_decimal>>>&
1344generic_record::get_array_of_decimal(const std::string& field_name) const
1345{
1346 return get<boost::optional<std::vector<boost::optional<big_decimal>>>>(
1347 field_name, field_kind::ARRAY_OF_DECIMAL);
1348}
1349
1350boost::optional<std::vector<boost::optional<big_decimal>>>&
1351generic_record::get_array_of_decimal(const std::string& field_name)
1352{
1353 return get<boost::optional<std::vector<boost::optional<big_decimal>>>>(
1354 field_name, field_kind::ARRAY_OF_DECIMAL);
1355}
1356
1357const boost::optional<std::vector<boost::optional<local_time>>>&
1358generic_record::get_array_of_time(const std::string& field_name) const
1359{
1360 return get<boost::optional<std::vector<boost::optional<local_time>>>>(
1361 field_name, field_kind::ARRAY_OF_TIME);
1362}
1363
1364boost::optional<std::vector<boost::optional<local_time>>>&
1365generic_record::get_array_of_time(const std::string& field_name)
1366{
1367 return get<boost::optional<std::vector<boost::optional<local_time>>>>(
1368 field_name, field_kind::ARRAY_OF_TIME);
1369}
1370
1371const boost::optional<std::vector<boost::optional<local_date>>>&
1372generic_record::get_array_of_date(const std::string& field_name) const
1373{
1374 return get<boost::optional<std::vector<boost::optional<local_date>>>>(
1375 field_name, field_kind::ARRAY_OF_DATE);
1376}
1377
1378boost::optional<std::vector<boost::optional<local_date>>>&
1379generic_record::get_array_of_date(const std::string& field_name)
1380{
1381 return get<boost::optional<std::vector<boost::optional<local_date>>>>(
1382 field_name, field_kind::ARRAY_OF_DATE);
1383}
1384
1385const boost::optional<std::vector<boost::optional<local_date_time>>>&
1386generic_record::get_array_of_timestamp(const std::string& field_name) const
1387{
1388 return get<boost::optional<std::vector<boost::optional<local_date_time>>>>(
1389 field_name, field_kind::ARRAY_OF_TIMESTAMP);
1390}
1391
1392boost::optional<std::vector<boost::optional<local_date_time>>>&
1393generic_record::get_array_of_timestamp(const std::string& field_name)
1394{
1395 return get<boost::optional<std::vector<boost::optional<local_date_time>>>>(
1396 field_name, field_kind::ARRAY_OF_TIMESTAMP);
1397}
1398
1399const boost::optional<std::vector<boost::optional<offset_date_time>>>&
1401 const std::string& field_name) const
1402{
1403 return get<boost::optional<std::vector<boost::optional<offset_date_time>>>>(
1404 field_name, field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE);
1405}
1406
1407boost::optional<std::vector<boost::optional<offset_date_time>>>&
1409 const std::string& field_name)
1410{
1411 return get<boost::optional<std::vector<boost::optional<offset_date_time>>>>(
1412 field_name, field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE);
1413}
1414
1415const boost::optional<std::vector<boost::optional<generic_record>>>&
1416generic_record::get_array_of_generic_record(const std::string& field_name) const
1417{
1418 return get<boost::optional<std::vector<boost::optional<generic_record>>>>(
1419 field_name, field_kind::ARRAY_OF_COMPACT);
1420}
1421
1422boost::optional<std::vector<boost::optional<generic_record>>>&
1424{
1425 return get<boost::optional<std::vector<boost::optional<generic_record>>>>(
1426 field_name, field_kind::ARRAY_OF_COMPACT);
1427}
1428
1429boost::property_tree::ptree
1430write_generic_record(const generic_record& record)
1431{
1432 boost::property_tree::ptree node;
1433
1434 for (const std::pair<const std::string, boost::any>& p : record.objects_) {
1435 const std::string& field_name = p.first;
1436
1437 field_kind kind = record.get_schema().get_field(field_name)->kind;
1438
1439 pimpl::field_operations::get(kind).write_json_formatted_field(
1440 node, record, field_name);
1441 }
1442
1443 return node;
1444}
1445
1446std::ostream&
1447operator<<(std::ostream& os, const generic_record& record)
1448{
1449 boost::property_tree::ptree pt;
1450
1451 pt.put_child(record.get_schema().type_name(), write_generic_record(record));
1452
1453 boost::property_tree::write_json(os, pt);
1454
1455 return os;
1456}
1457
1458bool
1459operator==(const generic_record& x, const generic_record& y)
1460{
1461 static const std::function<bool(const boost::any&, const boost::any&)>
1462 COMPARATORS[] = {
1463 [](const boost::any&, const boost::any&) {
1464 return false;
1465 }, //[0] NOT_AVAILABLE
1466 [](const boost::any& x, const boost::any& y) { //[1] BOOLEAN
1467 return boost::any_cast<bool>(x) == boost::any_cast<bool>(y);
1468 },
1469 [](const boost::any& x, const boost::any& y) { //[2] ARRAY_OF_BOOLEAN
1470 return boost::any_cast<boost::optional<std::vector<bool>>>(x) ==
1471 boost::any_cast<boost::optional<std::vector<bool>>>(y);
1472 },
1473 [](const boost::any& x, const boost::any& y) { //[3] INT8
1474 return boost::any_cast<int8_t>(x) == boost::any_cast<int8_t>(y);
1475 },
1476 [](const boost::any& x, const boost::any& y) { //[4] ARRAY_OF_INT8
1477 return boost::any_cast<boost::optional<std::vector<int8_t>>>(x) ==
1478 boost::any_cast<boost::optional<std::vector<int8_t>>>(y);
1479 },
1480 [](const boost::any&, const boost::any&) { return false; }, // [5]
1481 [](const boost::any&, const boost::any&) { return false; }, // [6]
1482 [](const boost::any& x, const boost::any& y) { //[7] INT16
1483 return boost::any_cast<int16_t>(x) == boost::any_cast<int16_t>(y);
1484 },
1485 [](const boost::any& x, const boost::any& y) { //[8] ARRAY_OF_INT16
1486 return boost::any_cast<boost::optional<std::vector<int16_t>>>(
1487 x) ==
1488 boost::any_cast<boost::optional<std::vector<int16_t>>>(y);
1489 },
1490 [](const boost::any& x, const boost::any& y) { //[9] INT32
1491 return boost::any_cast<int32_t>(x) == boost::any_cast<int32_t>(y);
1492 },
1493 [](const boost::any& x, const boost::any& y) { //[10] ARRAY_OF_INT32
1494 return boost::any_cast<boost::optional<std::vector<int32_t>>>(
1495 x) ==
1496 boost::any_cast<boost::optional<std::vector<int32_t>>>(y);
1497 },
1498 [](const boost::any& x, const boost::any& y) { //[11] INT64
1499 return boost::any_cast<int64_t>(x) == boost::any_cast<int64_t>(y);
1500 },
1501 [](const boost::any& x, const boost::any& y) { //[12] ARRAY_OF_INT64
1502 return boost::any_cast<boost::optional<std::vector<int64_t>>>(
1503 x) ==
1504 boost::any_cast<boost::optional<std::vector<int64_t>>>(y);
1505 },
1506 [](const boost::any& x, const boost::any& y) { //[13] FLOAT32
1507 return boost::any_cast<float>(x) == boost::any_cast<float>(y);
1508 },
1509 [](const boost::any& x, const boost::any& y) { //[14] ARRAY_OF_FLOAT32
1510 return boost::any_cast<boost::optional<std::vector<float>>>(x) ==
1511 boost::any_cast<boost::optional<std::vector<float>>>(y);
1512 },
1513 [](const boost::any& x, const boost::any& y) { //[15] FLOAT64
1514 return boost::any_cast<double>(x) == boost::any_cast<double>(y);
1515 },
1516 [](const boost::any& x, const boost::any& y) { //[16] ARRAY_OF_FLOAT64
1517 return boost::any_cast<boost::optional<std::vector<double>>>(x) ==
1518 boost::any_cast<boost::optional<std::vector<double>>>(y);
1519 },
1520 [](const boost::any& x, const boost::any& y) { //[17] STRING
1521 return boost::any_cast<boost::optional<std::string>>(x) ==
1522 boost::any_cast<boost::optional<std::string>>(y);
1523 },
1524 [](const boost::any& x, const boost::any& y) { //[18] ARRAY_OF_STRING
1525 return boost::any_cast<boost::optional<
1526 std::vector<boost::optional<std::string>>>>(x) ==
1527 boost::any_cast<boost::optional<
1528 std::vector<boost::optional<std::string>>>>(y);
1529 },
1530 [](const boost::any& x, const boost::any& y) { //[19] DECIMAL
1531 return boost::any_cast<boost::optional<big_decimal>>(x) ==
1532 boost::any_cast<boost::optional<big_decimal>>(y);
1533 },
1534 [](const boost::any& x, const boost::any& y) { //[20] ARRAY_OF_DECIMAL
1535 return boost::any_cast<boost::optional<
1536 std::vector<boost::optional<big_decimal>>>>(x) ==
1537 boost::any_cast<boost::optional<
1538 std::vector<boost::optional<big_decimal>>>>(y);
1539 },
1540 [](const boost::any& x, const boost::any& y) { //[21] TIME
1541 return boost::any_cast<boost::optional<local_time>>(x) ==
1542 boost::any_cast<boost::optional<local_time>>(y);
1543 },
1544 [](const boost::any& x, const boost::any& y) { //[22] ARRAY_OF_TIME
1545 return boost::any_cast<boost::optional<
1546 std::vector<boost::optional<local_time>>>>(x) ==
1547 boost::any_cast<boost::optional<
1548 std::vector<boost::optional<local_time>>>>(y);
1549 },
1550 [](const boost::any& x, const boost::any& y) { //[23] DATE
1551 return boost::any_cast<boost::optional<local_date>>(x) ==
1552 boost::any_cast<boost::optional<local_date>>(y);
1553 },
1554 [](const boost::any& x, const boost::any& y) { //[24] ARRAY_OF_DATE
1555 return boost::any_cast<boost::optional<
1556 std::vector<boost::optional<local_date>>>>(x) ==
1557 boost::any_cast<boost::optional<
1558 std::vector<boost::optional<local_date>>>>(y);
1559 },
1560 [](const boost::any& x, const boost::any& y) { //[25] TIMESTAMP
1561 return boost::any_cast<boost::optional<local_date_time>>(x) ==
1562 boost::any_cast<boost::optional<local_date_time>>(y);
1563 },
1564 [](const boost::any& x,
1565 const boost::any& y) { //[26] ARRAY_OF_TIMESTAMP
1566 return boost::any_cast<boost::optional<
1567 std::vector<boost::optional<local_date_time>>>>(x) ==
1568 boost::any_cast<boost::optional<
1569 std::vector<boost::optional<local_date_time>>>>(y);
1570 },
1571 [](const boost::any& x,
1572 const boost::any& y) { //[27] TIMESTAMP_WITH_TIMEZONE
1573 return boost::any_cast<boost::optional<offset_date_time>>(x) ==
1574 boost::any_cast<boost::optional<offset_date_time>>(y);
1575 },
1576 [](const boost::any& x,
1577 const boost::any& y) { //[28] ARRAY_OF_TIMESTAMP_WITH_TIMEZON
1578 return boost::any_cast<boost::optional<
1579 std::vector<boost::optional<offset_date_time>>>>(x) ==
1580 boost::any_cast<boost::optional<
1581 std::vector<boost::optional<offset_date_time>>>>(y);
1582 },
1583 [](const boost::any& x, const boost::any& y) { //[29] COMPACT
1584 return boost::any_cast<boost::optional<generic_record>>(x) ==
1585 boost::any_cast<boost::optional<generic_record>>(y);
1586 },
1587 [](const boost::any& x, const boost::any& y) { //[30] ARRAY_OF_COMPACT
1588 return boost::any_cast<boost::optional<
1589 std::vector<boost::optional<generic_record>>>>(x) ==
1590 boost::any_cast<boost::optional<
1591 std::vector<boost::optional<generic_record>>>>(y);
1592 },
1593 [](const boost::any& /*x*/, const boost::any& /*y*/) { return false; }, //[31]
1594 [](const boost::any& /*x*/, const boost::any& /*y*/) { return false; }, //[32]
1595 [](const boost::any& x, const boost::any& y) { //[33] NULLABLE_BOOLEAN
1596 return boost::any_cast<boost::optional<bool>>(x) ==
1597 boost::any_cast<boost::optional<bool>>(y);
1598 },
1599 [](const boost::any& x,
1600 const boost::any& y) { //[34] ARRAY_OF_NULLABLE_BOOLEAN
1601 return boost::any_cast<
1602 boost::optional<std::vector<boost::optional<bool>>>>(
1603 x) ==
1604 boost::any_cast<
1605 boost::optional<std::vector<boost::optional<bool>>>>(y);
1606 },
1607 [](const boost::any& x, const boost::any& y) { //[35] NULLABLE_INT8
1608 return boost::any_cast<boost::optional<int8_t>>(x) ==
1609 boost::any_cast<boost::optional<int8_t>>(y);
1610 },
1611 [](const boost::any& x,
1612 const boost::any& y) { //[36] ARRAY_OF_NULLABLE_INT8
1613 return boost::any_cast<
1614 boost::optional<std::vector<boost::optional<int8_t>>>>(
1615 x) ==
1616 boost::any_cast<
1617 boost::optional<std::vector<boost::optional<int8_t>>>>(
1618 y);
1619 },
1620 [](const boost::any& x, const boost::any& y) { //[37] NULLABLE_INT16
1621 return boost::any_cast<boost::optional<int16_t>>(x) ==
1622 boost::any_cast<boost::optional<int16_t>>(y);
1623 },
1624 [](const boost::any& x,
1625 const boost::any& y) { //[38] ARRAY_OF_NULLABLE_INT16
1626 return boost::any_cast<
1627 boost::optional<std::vector<boost::optional<int16_t>>>>(
1628 x) ==
1629 boost::any_cast<
1630 boost::optional<std::vector<boost::optional<int16_t>>>>(
1631 y);
1632 },
1633 [](const boost::any& x, const boost::any& y) { //[39] NULLABLE_INT32
1634 return boost::any_cast<boost::optional<int32_t>>(x) ==
1635 boost::any_cast<boost::optional<int32_t>>(y);
1636 },
1637 [](const boost::any& x,
1638 const boost::any& y) { //[40] ARRAY_OF_NULLABLE_INT32
1639 return boost::any_cast<
1640 boost::optional<std::vector<boost::optional<int32_t>>>>(
1641 x) ==
1642 boost::any_cast<
1643 boost::optional<std::vector<boost::optional<int32_t>>>>(
1644 y);
1645 },
1646 [](const boost::any& x, const boost::any& y) { //[41] NULLABLE_INT64
1647 return boost::any_cast<boost::optional<int64_t>>(x) ==
1648 boost::any_cast<boost::optional<int64_t>>(y);
1649 },
1650 [](const boost::any& x,
1651 const boost::any& y) { //[42] ARRAY_OF_NULLABLE_INT64
1652 return boost::any_cast<
1653 boost::optional<std::vector<boost::optional<int64_t>>>>(
1654 x) ==
1655 boost::any_cast<
1656 boost::optional<std::vector<boost::optional<int64_t>>>>(
1657 y);
1658 },
1659 [](const boost::any& x, const boost::any& y) { //[43] NULLABLE_FLOAT32
1660 return boost::any_cast<boost::optional<float>>(x) ==
1661 boost::any_cast<boost::optional<float>>(y);
1662 },
1663 [](const boost::any& x,
1664 const boost::any& y) { //[44] ARRAY_OF_NULLABLE_FLOAT32
1665 return boost::any_cast<
1666 boost::optional<std::vector<boost::optional<float>>>>(
1667 x) ==
1668 boost::any_cast<
1669 boost::optional<std::vector<boost::optional<float>>>>(y);
1670 },
1671 [](const boost::any& x, const boost::any& y) { //[45] NULLABLE_FLOAT64
1672 return boost::any_cast<boost::optional<double>>(x) ==
1673 boost::any_cast<boost::optional<double>>(y);
1674 },
1675 [](const boost::any& x,
1676 const boost::any& y) { //[46] ARRAY_OF_NULLABLE_FLOAT64
1677 return boost::any_cast<
1678 boost::optional<std::vector<boost::optional<double>>>>(
1679 x) ==
1680 boost::any_cast<
1681 boost::optional<std::vector<boost::optional<double>>>>(
1682 y);
1683 }
1684 };
1685
1686 const pimpl::schema& xs = x.get_schema();
1687 const pimpl::schema& ys = y.get_schema();
1688
1689 if (xs != ys)
1690 return false;
1691
1692 for (const std::pair<const std::string, boost::any>& xp : x.objects_) {
1693 const std::string& field_name = xp.first;
1694 const boost::any& value_of_x = xp.second;
1695 const boost::any& value_of_y = y.objects_.at(field_name);
1696
1697 boost::optional<pimpl::field_descriptor> kind_opt =
1698 xs.get_field(field_name);
1699
1700 if (!COMPARATORS[std::size_t(kind_opt->kind)](value_of_x, value_of_y))
1701 return false;
1702 }
1703
1704 return true;
1705}
1706
1707bool
1708operator!=(const generic_record& x, const generic_record& y)
1709{
1710 return !(x == y);
1711}
1712} // namespace generic_record
1713
1714std::ostream&
1715operator<<(std::ostream& os, field_kind kind)
1716{
1717 switch (kind) {
1718 case field_kind::NOT_AVAILABLE:
1719 os << "NOT_AVAILABLE";
1720 break;
1721 case field_kind::BOOLEAN:
1722 os << "BOOLEAN";
1723 break;
1724 case field_kind::ARRAY_OF_BOOLEAN:
1725 os << "ARRAY_OF_BOOLEAN";
1726 break;
1727 case field_kind::INT8:
1728 os << "INT8";
1729 break;
1730 case field_kind::ARRAY_OF_INT8:
1731 os << "ARRAY_OF_INT8";
1732 break;
1733 case field_kind::INT16:
1734 os << "INT16";
1735 break;
1736 case field_kind::ARRAY_OF_INT16:
1737 os << "ARRAY_OF_INT16";
1738 break;
1739 case field_kind::INT32:
1740 os << "INT32";
1741 break;
1742 case field_kind::ARRAY_OF_INT32:
1743 os << "ARRAY_OF_INT32";
1744 break;
1745 case field_kind::INT64:
1746 os << "INT64";
1747 break;
1748 case field_kind::ARRAY_OF_INT64:
1749 os << "ARRAY_OF_INT64";
1750 break;
1751 case field_kind::FLOAT32:
1752 os << "FLOAT32";
1753 break;
1754 case field_kind::ARRAY_OF_FLOAT32:
1755 os << "ARRAY_OF_FLOAT32";
1756 break;
1757 case field_kind::FLOAT64:
1758 os << "FLOAT64";
1759 break;
1760 case field_kind::ARRAY_OF_FLOAT64:
1761 os << "ARRAY_OF_FLOAT64";
1762 break;
1763 case field_kind::STRING:
1764 os << "STRING";
1765 break;
1766 case field_kind::ARRAY_OF_STRING:
1767 os << "ARRAY_OF_STRING";
1768 break;
1769 case field_kind::DECIMAL:
1770 os << "DECIMAL";
1771 break;
1772 case field_kind::ARRAY_OF_DECIMAL:
1773 os << "ARRAY_OF_DECIMAL";
1774 break;
1775 case field_kind::TIME:
1776 os << "TIME";
1777 break;
1778 case field_kind::ARRAY_OF_TIME:
1779 os << "ARRAY_OF_TIME";
1780 break;
1781 case field_kind::DATE:
1782 os << "DATE";
1783 break;
1784 case field_kind::ARRAY_OF_DATE:
1785 os << "ARRAY_OF_DATE";
1786 break;
1787 case field_kind::TIMESTAMP:
1788 os << "TIMESTAMP";
1789 break;
1790 case field_kind::ARRAY_OF_TIMESTAMP:
1791 os << "ARRAY_OF_TIMESTAMP";
1792 break;
1793 case field_kind::TIMESTAMP_WITH_TIMEZONE:
1794 os << "TIMESTAMP_WITH_TIMEZONE";
1795 break;
1796 case field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE:
1797 os << "ARRAY_OF_TIMESTAMP_WITH_TIMEZONE";
1798 break;
1799 case field_kind::COMPACT:
1800 os << "COMPACT";
1801 break;
1802 case field_kind::ARRAY_OF_COMPACT:
1803 os << "ARRAY_OF_COMPACT";
1804 break;
1805 case field_kind::NULLABLE_BOOLEAN:
1806 os << "NULLABLE_BOOLEAN";
1807 break;
1808 case field_kind::ARRAY_OF_NULLABLE_BOOLEAN:
1809 os << "ARRAY_OF_NULLABLE_BOOLEAN";
1810 break;
1811 case field_kind::NULLABLE_INT8:
1812 os << "NULLABLE_INT8";
1813 break;
1814 case field_kind::ARRAY_OF_NULLABLE_INT8:
1815 os << "ARRAY_OF_NULLABLE_INT8";
1816 break;
1817 case field_kind::NULLABLE_INT16:
1818 os << "NULLABLE_INT16";
1819 break;
1820 case field_kind::ARRAY_OF_NULLABLE_INT16:
1821 os << "ARRAY_OF_NULLABLE_INT16";
1822 break;
1823 case field_kind::NULLABLE_INT32:
1824 os << "NULLABLE_INT32";
1825 break;
1826 case field_kind::ARRAY_OF_NULLABLE_INT32:
1827 os << "ARRAY_OF_NULLABLE_INT32";
1828 break;
1829 case field_kind::NULLABLE_INT64:
1830 os << "NULLABLE_INT64";
1831 break;
1832 case field_kind::ARRAY_OF_NULLABLE_INT64:
1833 os << "ARRAY_OF_NULLABLE_INT64";
1834 break;
1835 case field_kind::NULLABLE_FLOAT32:
1836 os << "NULLABLE_FLOAT32";
1837 break;
1838 case field_kind::ARRAY_OF_NULLABLE_FLOAT32:
1839 os << "ARRAY_OF_NULLABLE_FLOAT32";
1840 break;
1841 case field_kind::NULLABLE_FLOAT64:
1842 os << "NULLABLE_FLOAT64";
1843 break;
1844 case field_kind::ARRAY_OF_NULLABLE_FLOAT64:
1845 os << "ARRAY_OF_NULLABLE_FLOAT64";
1846 break;
1847 }
1848
1849 return os;
1850}
1851
1852} // namespace serialization
1853} // namespace client
1854} // namespace hazelcast
1855
1856namespace hazelcast {
1857namespace client {
1858namespace serialization {
1859namespace compact {
1860
1861compact_writer::compact_writer(
1862 pimpl::default_compact_writer* default_compact_writer)
1863 : default_compact_writer(default_compact_writer)
1864 , schema_writer(nullptr)
1865{}
1866
1867compact_writer::compact_writer(pimpl::schema_writer* schema_writer)
1868 : default_compact_writer(nullptr)
1869 , schema_writer(schema_writer)
1870{}
1871
1872void
1873compact_writer::write_boolean(const std::string& field_name, bool value)
1874{
1875 if (default_compact_writer) {
1876 default_compact_writer->write_boolean(field_name, value);
1877 } else {
1878 schema_writer->add_field(field_name, field_kind::BOOLEAN);
1879 }
1880}
1881void
1882compact_writer::write_int8(const std::string& field_name, int8_t value)
1883{
1884 if (default_compact_writer) {
1885 default_compact_writer->write_int8(field_name, value);
1886 } else {
1887 schema_writer->add_field(field_name, field_kind::INT8);
1888 }
1889}
1890
1891void
1892compact_writer::write_int16(const std::string& field_name, int16_t value)
1893{
1894 if (default_compact_writer) {
1895 default_compact_writer->write_int16(field_name, value);
1896 } else {
1897 schema_writer->add_field(field_name, field_kind::INT16);
1898 }
1899}
1900
1901void
1902compact_writer::write_int32(const std::string& field_name, int32_t value)
1903{
1904 if (default_compact_writer != nullptr) {
1905 default_compact_writer->write_int32(field_name, value);
1906 } else {
1907 schema_writer->add_field(field_name, field_kind::INT32);
1908 }
1909}
1910
1911void
1912compact_writer::write_int64(const std::string& field_name, int64_t value)
1913{
1914 if (default_compact_writer != nullptr) {
1915 default_compact_writer->write_int64(field_name, value);
1916 } else {
1917 schema_writer->add_field(field_name, field_kind::INT64);
1918 }
1919}
1920
1921void
1922compact_writer::write_float32(const std::string& field_name, float value)
1923{
1924 if (default_compact_writer != nullptr) {
1925 default_compact_writer->write_float32(field_name, value);
1926 } else {
1927 schema_writer->add_field(field_name, field_kind::FLOAT32);
1928 }
1929}
1930
1931void
1932compact_writer::write_float64(const std::string& field_name, double value)
1933{
1934 if (default_compact_writer != nullptr) {
1935 default_compact_writer->write_float64(field_name, value);
1936 } else {
1937 schema_writer->add_field(field_name, field_kind::FLOAT64);
1938 }
1939}
1940
1941void
1942compact_writer::write_string(const std::string& field_name,
1943 const boost::optional<std::string>& value)
1944{
1945 if (default_compact_writer != nullptr) {
1946 default_compact_writer->write_string(field_name, value);
1947 } else {
1948 schema_writer->add_field(field_name, field_kind::STRING);
1949 }
1950}
1951
1952void
1953compact_writer::write_decimal(const std::string& field_name,
1954 const boost::optional<big_decimal>& value)
1955{
1956 if (default_compact_writer != nullptr) {
1957 default_compact_writer->write_decimal(field_name, value);
1958 } else {
1959 schema_writer->add_field(field_name, field_kind::DECIMAL);
1960 }
1961}
1962
1963void
1964compact_writer::write_time(
1965 const std::string& field_name,
1966 const boost::optional<hazelcast::client::local_time>& value)
1967{
1968 if (default_compact_writer != nullptr) {
1969 default_compact_writer->write_time(field_name, value);
1970 } else {
1971 schema_writer->add_field(field_name, field_kind::TIME);
1972 }
1973}
1974
1975void
1976compact_writer::write_date(
1977 const std::string& field_name,
1978 const boost::optional<hazelcast::client::local_date>& value)
1979{
1980 if (default_compact_writer != nullptr) {
1981 default_compact_writer->write_date(field_name, value);
1982 } else {
1983 schema_writer->add_field(field_name, field_kind::DATE);
1984 }
1985}
1986
1987void
1988compact_writer::write_timestamp(
1989 const std::string& field_name,
1990 const boost::optional<hazelcast::client::local_date_time>& value)
1991{
1992 if (default_compact_writer != nullptr) {
1993 default_compact_writer->write_timestamp(field_name, value);
1994 } else {
1995 schema_writer->add_field(field_name, field_kind::TIMESTAMP);
1996 }
1997}
1998
1999void
2000compact_writer::write_timestamp_with_timezone(
2001 const std::string& field_name,
2002 const boost::optional<hazelcast::client::offset_date_time>& value)
2003{
2004 if (default_compact_writer != nullptr) {
2005 default_compact_writer->write_timestamp_with_timezone(field_name,
2006 value);
2007 } else {
2008 schema_writer->add_field(field_name,
2009 field_kind::TIMESTAMP_WITH_TIMEZONE);
2010 }
2011}
2012
2013void
2014compact_writer::write_array_of_boolean(
2015 const std::string& field_name,
2016 const boost::optional<std::vector<bool>>& value)
2017{
2018 if (default_compact_writer != nullptr) {
2019 default_compact_writer->write_array_of_boolean(field_name, value);
2020 } else {
2021 schema_writer->add_field(field_name, field_kind::ARRAY_OF_BOOLEAN);
2022 }
2023}
2024
2025void
2026compact_writer::write_array_of_int8(
2027 const std::string& field_name,
2028 const boost::optional<std::vector<int8_t>>& value)
2029{
2030 if (default_compact_writer != nullptr) {
2031 default_compact_writer->write_array_of_int8(field_name, value);
2032 } else {
2033 schema_writer->add_field(field_name, field_kind::ARRAY_OF_INT8);
2034 }
2035}
2036
2037void
2038compact_writer::write_array_of_int16(
2039 const std::string& field_name,
2040 const boost::optional<std::vector<int16_t>>& value)
2041{
2042 if (default_compact_writer != nullptr) {
2043 default_compact_writer->write_array_of_int16(field_name, value);
2044 } else {
2045 schema_writer->add_field(field_name, field_kind::ARRAY_OF_INT16);
2046 }
2047}
2048
2049void
2050compact_writer::write_array_of_int32(
2051 const std::string& field_name,
2052 const boost::optional<std::vector<int32_t>>& value)
2053{
2054 if (default_compact_writer != nullptr) {
2055 default_compact_writer->write_array_of_int32(field_name, value);
2056 } else {
2057 schema_writer->add_field(field_name, field_kind::ARRAY_OF_INT32);
2058 }
2059}
2060
2061void
2062compact_writer::write_array_of_int64(
2063 const std::string& field_name,
2064 const boost::optional<std::vector<int64_t>>& value)
2065{
2066 if (default_compact_writer != nullptr) {
2067 default_compact_writer->write_array_of_int64(field_name, value);
2068 } else {
2069 schema_writer->add_field(field_name, field_kind::ARRAY_OF_INT64);
2070 }
2071}
2072
2073void
2074compact_writer::write_array_of_float32(
2075 const std::string& field_name,
2076 const boost::optional<std::vector<float>>& value)
2077{
2078 if (default_compact_writer != nullptr) {
2079 default_compact_writer->write_array_of_float32(field_name, value);
2080 } else {
2081 schema_writer->add_field(field_name, field_kind::ARRAY_OF_FLOAT32);
2082 }
2083}
2084
2085void
2086compact_writer::write_array_of_float64(
2087 const std::string& field_name,
2088 const boost::optional<std::vector<double>>& value)
2089{
2090 if (default_compact_writer != nullptr) {
2091 default_compact_writer->write_array_of_float64(field_name, value);
2092 } else {
2093 schema_writer->add_field(field_name, field_kind::ARRAY_OF_FLOAT64);
2094 }
2095}
2096
2097void
2098compact_writer::write_array_of_string(
2099 const std::string& field_name,
2100 const boost::optional<std::vector<boost::optional<std::string>>>& value)
2101{
2102 if (default_compact_writer != nullptr) {
2103 default_compact_writer->write_array_of_string(field_name, value);
2104 } else {
2105 schema_writer->add_field(field_name, field_kind::ARRAY_OF_STRING);
2106 }
2107}
2108
2109void
2110compact_writer::write_array_of_decimal(
2111 const std::string& field_name,
2112 const boost::optional<std::vector<boost::optional<big_decimal>>>& value)
2113{
2114 if (default_compact_writer != nullptr) {
2115 default_compact_writer->write_array_of_decimal(field_name, value);
2116 } else {
2117 schema_writer->add_field(field_name, field_kind::ARRAY_OF_DECIMAL);
2118 }
2119}
2120
2121void
2122compact_writer::write_array_of_time(
2123 const std::string& field_name,
2124 const boost::optional<std::vector<boost::optional<local_time>>>& value)
2125{
2126 if (default_compact_writer != nullptr) {
2127 default_compact_writer->write_array_of_time(field_name, value);
2128 } else {
2129 schema_writer->add_field(field_name, field_kind::ARRAY_OF_TIME);
2130 }
2131}
2132
2133void
2134compact_writer::write_array_of_date(
2135 const std::string& field_name,
2136 const boost::optional<std::vector<boost::optional<local_date>>>& value)
2137{
2138 if (default_compact_writer != nullptr) {
2139 default_compact_writer->write_array_of_date(field_name, value);
2140 } else {
2141 schema_writer->add_field(field_name, field_kind::ARRAY_OF_DATE);
2142 }
2143}
2144
2145void
2146compact_writer::write_array_of_timestamp(
2147 const std::string& field_name,
2148 const boost::optional<std::vector<boost::optional<local_date_time>>>& value)
2149{
2150 if (default_compact_writer != nullptr) {
2151 default_compact_writer->write_array_of_timestamp(field_name, value);
2152 } else {
2153 schema_writer->add_field(field_name, field_kind::ARRAY_OF_TIMESTAMP);
2154 }
2155}
2156
2157void
2158compact_writer::write_array_of_timestamp_with_timezone(
2159 const std::string& field_name,
2160 const boost::optional<std::vector<boost::optional<offset_date_time>>>& value)
2161{
2162 if (default_compact_writer != nullptr) {
2163 default_compact_writer->write_array_of_timestamp_with_timezone(
2164 field_name, value);
2165 } else {
2166 schema_writer->add_field(field_name,
2167 field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE);
2168 }
2169}
2170
2171void
2172compact_writer::write_nullable_boolean(const std::string& field_name,
2173 const boost::optional<bool>& value)
2174{
2175 if (default_compact_writer != nullptr) {
2176 default_compact_writer->write_nullable_boolean(field_name, value);
2177 } else {
2178 schema_writer->add_field(field_name, field_kind::NULLABLE_BOOLEAN);
2179 }
2180}
2181
2182void
2183compact_writer::write_nullable_int8(const std::string& field_name,
2184 const boost::optional<int8_t>& value)
2185{
2186 if (default_compact_writer != nullptr) {
2187 default_compact_writer->write_nullable_int8(field_name, value);
2188 } else {
2189 schema_writer->add_field(field_name, field_kind::NULLABLE_INT8);
2190 }
2191}
2192
2193void
2194compact_writer::write_nullable_int16(const std::string& field_name,
2195 const boost::optional<int16_t>& value)
2196{
2197 if (default_compact_writer != nullptr) {
2198 default_compact_writer->write_nullable_int16(field_name, value);
2199 } else {
2200 schema_writer->add_field(field_name, field_kind::NULLABLE_INT16);
2201 }
2202}
2203
2204void
2205compact_writer::write_nullable_int32(const std::string& field_name,
2206 const boost::optional<int32_t>& value)
2207{
2208 if (default_compact_writer != nullptr) {
2209 default_compact_writer->write_nullable_int32(field_name, value);
2210 } else {
2211 schema_writer->add_field(field_name, field_kind::NULLABLE_INT32);
2212 }
2213}
2214
2215void
2216compact_writer::write_nullable_int64(const std::string& field_name,
2217 const boost::optional<int64_t>& value)
2218{
2219 if (default_compact_writer != nullptr) {
2220 default_compact_writer->write_nullable_int64(field_name, value);
2221 } else {
2222 schema_writer->add_field(field_name, field_kind::NULLABLE_INT64);
2223 }
2224}
2225
2226void
2227compact_writer::write_nullable_float32(const std::string& field_name,
2228 const boost::optional<float>& value)
2229{
2230 if (default_compact_writer != nullptr) {
2231 default_compact_writer->write_nullable_float32(field_name, value);
2232 } else {
2233 schema_writer->add_field(field_name, field_kind::NULLABLE_FLOAT32);
2234 }
2235}
2236
2237void
2238compact_writer::write_nullable_float64(const std::string& field_name,
2239 const boost::optional<double>& value)
2240{
2241 if (default_compact_writer != nullptr) {
2242 default_compact_writer->write_nullable_float64(field_name, value);
2243 } else {
2244 schema_writer->add_field(field_name, field_kind::NULLABLE_FLOAT64);
2245 }
2246}
2247
2248void
2249compact_writer::write_array_of_nullable_boolean(
2250 const std::string& field_name,
2251 const boost::optional<std::vector<boost::optional<bool>>>& value)
2252{
2253 if (default_compact_writer != nullptr) {
2254 default_compact_writer->write_array_of_nullable_boolean(field_name,
2255 value);
2256 } else {
2257 schema_writer->add_field(field_name,
2258 field_kind::ARRAY_OF_NULLABLE_BOOLEAN);
2259 }
2260}
2261
2262void
2263compact_writer::write_array_of_nullable_int8(
2264 const std::string& field_name,
2265 const boost::optional<std::vector<boost::optional<int8_t>>>& value)
2266{
2267 if (default_compact_writer != nullptr) {
2268 default_compact_writer->write_array_of_nullable_int8(field_name, value);
2269 } else {
2270 schema_writer->add_field(field_name,
2271 field_kind::ARRAY_OF_NULLABLE_INT8);
2272 }
2273}
2274
2275void
2276compact_writer::write_array_of_nullable_int16(
2277 const std::string& field_name,
2278 const boost::optional<std::vector<boost::optional<int16_t>>>& value)
2279{
2280 if (default_compact_writer != nullptr) {
2281 default_compact_writer->write_array_of_nullable_int16(field_name,
2282 value);
2283 } else {
2284 schema_writer->add_field(field_name,
2285 field_kind::ARRAY_OF_NULLABLE_INT16);
2286 }
2287}
2288
2289void
2290compact_writer::write_array_of_nullable_int32(
2291 const std::string& field_name,
2292 const boost::optional<std::vector<boost::optional<int32_t>>>& value)
2293{
2294 if (default_compact_writer != nullptr) {
2295 default_compact_writer->write_array_of_nullable_int32(field_name,
2296 value);
2297 } else {
2298 schema_writer->add_field(field_name,
2299 field_kind::ARRAY_OF_NULLABLE_INT32);
2300 }
2301}
2302
2303void
2304compact_writer::write_array_of_nullable_int64(
2305 const std::string& field_name,
2306 const boost::optional<std::vector<boost::optional<int64_t>>>& value)
2307{
2308 if (default_compact_writer != nullptr) {
2309 default_compact_writer->write_array_of_nullable_int64(field_name,
2310 value);
2311 } else {
2312 schema_writer->add_field(field_name,
2313 field_kind::ARRAY_OF_NULLABLE_INT64);
2314 }
2315}
2316
2317void
2318compact_writer::write_array_of_nullable_float32(
2319 const std::string& field_name,
2320 const boost::optional<std::vector<boost::optional<float>>>& value)
2321{
2322 if (default_compact_writer != nullptr) {
2323 default_compact_writer->write_array_of_nullable_float32(field_name,
2324 value);
2325 } else {
2326 schema_writer->add_field(field_name,
2327 field_kind::ARRAY_OF_NULLABLE_FLOAT32);
2328 }
2329}
2330
2331void
2332compact_writer::write_array_of_nullable_float64(
2333 const std::string& field_name,
2334 const boost::optional<std::vector<boost::optional<double>>>& value)
2335{
2336 if (default_compact_writer != nullptr) {
2337 default_compact_writer->write_array_of_nullable_float64(field_name,
2338 value);
2339 } else {
2340 schema_writer->add_field(field_name,
2341 field_kind::ARRAY_OF_NULLABLE_FLOAT64);
2342 }
2343}
2344
2345} // namespace compact
2346
2347namespace pimpl {
2348
2349compact::compact_reader
2350create_compact_reader(
2351 pimpl::compact_stream_serializer& compact_stream_serializer,
2352 object_data_input& object_data_input,
2353 const pimpl::schema& schema)
2354{
2355 return compact::compact_reader{ compact_stream_serializer,
2356 object_data_input,
2357 schema };
2358}
2359
2360} // namespace pimpl
2361
2362namespace compact {
2363
2364const compact_reader::offset_func compact_reader::BYTE_OFFSET_READER =
2365 pimpl::offset_reader::get_offset<int8_t>;
2366const compact_reader::offset_func compact_reader::SHORT_OFFSET_READER =
2367 pimpl::offset_reader::get_offset<int16_t>;
2368const compact_reader::offset_func compact_reader::INT_OFFSET_READER =
2369 pimpl::offset_reader::get_offset<int32_t>;
2370
2371compact_reader::compact_reader(
2372 pimpl::compact_stream_serializer& compact_stream_serializer,
2373 serialization::object_data_input& object_data_input,
2374 const pimpl::schema& schema)
2375 : compact_stream_serializer(compact_stream_serializer)
2376 , object_data_input(object_data_input)
2377 , schema(schema)
2378{
2379 size_t final_position;
2380 size_t number_of_var_size_fields = schema.number_of_var_size_fields();
2381 if (number_of_var_size_fields != 0) {
2382 uint32_t data_length = object_data_input.read<int32_t>();
2383 data_start_position = object_data_input.position();
2384 variable_offsets_position = data_start_position + data_length;
2385 if (data_length < pimpl::offset_reader::BYTE_OFFSET_READER_RANGE) {
2386 get_offset = BYTE_OFFSET_READER;
2387 final_position =
2388 variable_offsets_position + number_of_var_size_fields;
2389 } else if (data_length <
2390 pimpl::offset_reader::SHORT_OFFSET_READER_RANGE) {
2391 get_offset = SHORT_OFFSET_READER;
2392 final_position =
2393 variable_offsets_position +
2394 (number_of_var_size_fields * util::Bits::SHORT_SIZE_IN_BYTES);
2395 } else {
2396 get_offset = INT_OFFSET_READER;
2397 final_position =
2398 variable_offsets_position +
2399 (number_of_var_size_fields * util::Bits::INT_SIZE_IN_BYTES);
2400 }
2401 } else {
2402 get_offset = INT_OFFSET_READER;
2403 variable_offsets_position = 0;
2404 data_start_position = object_data_input.position();
2405 final_position =
2406 data_start_position + schema.fixed_size_fields_length();
2407 }
2408 // set the position to final so that the next one to read something from
2409 // `in` can start from correct position
2410 object_data_input.position(static_cast<int>(final_position));
2411}
2412
2413bool
2414compact_reader::is_field_exists(const std::string& field_name,
2415 field_kind kind) const
2416{
2417 const auto& fields = schema.fields();
2418 const auto& field_descriptor = fields.find(field_name);
2419 if (field_descriptor == fields.end()) {
2420 return false;
2421 }
2422 return field_descriptor->second.kind == kind;
2423}
2424
2425const pimpl::field_descriptor&
2426compact_reader::get_field_descriptor(const std::string& field_name) const
2427{
2428 const auto& fields = schema.fields();
2429 const auto& field_descriptor = fields.find(field_name);
2430 if (field_descriptor == fields.end()) {
2431 BOOST_THROW_EXCEPTION(unknown_field(field_name));
2432 }
2433 return field_descriptor->second;
2434}
2435
2436const pimpl::field_descriptor&
2437compact_reader::get_field_descriptor(const std::string& field_name,
2438 field_kind kind) const
2439{
2440 const auto& field_descriptor = get_field_descriptor(field_name);
2441 if (field_descriptor.kind != kind) {
2442 BOOST_THROW_EXCEPTION(
2443 unexpected_field_kind(field_descriptor.kind, field_name));
2444 }
2445 return field_descriptor;
2446}
2447
2448std::function<int32_t(serialization::object_data_input&, uint32_t, uint32_t)>
2449compact_reader::get_offset_reader(int32_t data_length)
2450{
2451 if (data_length < pimpl::offset_reader::BYTE_OFFSET_READER_RANGE) {
2452 return BYTE_OFFSET_READER;
2453 } else if (data_length < pimpl::offset_reader::SHORT_OFFSET_READER_RANGE) {
2454 return SHORT_OFFSET_READER;
2455 } else {
2456 return INT_OFFSET_READER;
2457 }
2458}
2459
2460exception::hazelcast_serialization
2461compact_reader::unexpected_null_value_in_array(const std::string& field_name,
2462 const std::string& method_suffix)
2463{
2464 return {
2465 "compact_reader",
2466 (boost::format(
2467 "Error while reading %1%. Array with null items can not be read via "
2468 "read_array_of_%2% methods. Use read_array_of_nullable_%2% "
2469 "instead") %
2470 field_name % method_suffix)
2471 .str()
2472 };
2473}
2474exception::hazelcast_serialization
2475compact_reader::unknown_field(const std::string& field_name) const
2476{
2477 return { "compact_reader",
2478 (boost::format("Unknown field name %1% on %2% ") % field_name %
2479 schema)
2480 .str() };
2481}
2482
2483exception::hazelcast_serialization
2484compact_reader::unexpected_field_kind(field_kind kind,
2485 const std::string& field_name) const
2486{
2487 return { "compact_reader",
2488 (boost::format("Unexpected fieldKind %1% for %2% on %3%") % kind %
2489 field_name % schema)
2490 .str() };
2491}
2492
2493exception::hazelcast_serialization
2494compact_reader::unexpected_null_value(const std::string& field_name,
2495 const std::string& method_suffix)
2496{
2497 return { "compact_reader",
2498 (boost::format(
2499 "Error while reading %1%. null value can not be read via "
2500 "read_%2% methods. Use read_nullable_%2% instead.") %
2501 field_name % method_suffix)
2502 .str() };
2503}
2504
2505size_t
2506compact_reader::read_fixed_size_position(
2507 const pimpl::field_descriptor& field_descriptor) const
2508{
2509 int32_t primitive_offset = field_descriptor.offset;
2510 return primitive_offset + data_start_position;
2511}
2512
2513int32_t
2514compact_reader::read_var_size_position(
2515 const pimpl::field_descriptor& field_descriptor) const
2516{
2517 int32_t index = field_descriptor.index;
2518 int32_t offset =
2519 get_offset(object_data_input, variable_offsets_position, index);
2520 return offset == pimpl::offset_reader::NULL_OFFSET
2521 ? pimpl::offset_reader::NULL_OFFSET
2522 : offset + data_start_position;
2523}
2524
2525field_kind
2526compact_reader::get_field_kind(const std::string& field_name)
2527{
2528 auto descriptor = schema.get_field(field_name);
2529
2530 if (!descriptor) {
2531 return field_kind::NOT_AVAILABLE;
2532 }
2533
2534 return descriptor->kind;
2535}
2536
2537bool
2538compact_reader::read_boolean(const std::string& fieldName)
2539{
2540 return read_primitive<bool>(
2541 fieldName, field_kind::BOOLEAN, field_kind::NULLABLE_BOOLEAN, "boolean");
2542}
2543
2544int8_t
2545compact_reader::read_int8(const std::string& fieldName)
2546{
2547 return read_primitive<int8_t>(
2548 fieldName, field_kind::INT8, field_kind::NULLABLE_INT8, "int8");
2549}
2550
2551int16_t
2552compact_reader::read_int16(const std::string& field_name)
2553{
2554 return read_primitive<int16_t>(
2555 field_name, field_kind::INT16, field_kind::NULLABLE_INT16, "int16");
2556}
2557
2558int32_t
2559compact_reader::read_int32(const std::string& field_name)
2560{
2561 return read_primitive<int32_t>(
2562 field_name, field_kind::INT32, field_kind::NULLABLE_INT32, "int32");
2563}
2564
2565int64_t
2566compact_reader::read_int64(const std::string& field_name)
2567{
2568 return read_primitive<int64_t>(
2569 field_name, field_kind::INT64, field_kind::NULLABLE_INT64, "int64");
2570}
2571
2572float
2573compact_reader::read_float32(const std::string& field_name)
2574{
2575 return read_primitive<float>(
2576 field_name, field_kind::FLOAT32, field_kind::NULLABLE_FLOAT32, "float32");
2577}
2578
2579double
2580compact_reader::read_float64(const std::string& field_name)
2581{
2582 return read_primitive<double>(
2583 field_name, field_kind::FLOAT64, field_kind::NULLABLE_FLOAT64, "float64");
2584}
2585
2586boost::optional<std::string>
2587compact_reader::read_string(const std::string& field_name)
2588{
2589 return read_variable_size<std::string>(field_name, field_kind::STRING);
2590}
2591
2592boost::optional<big_decimal>
2593compact_reader::read_decimal(const std::string& field_name)
2594{
2595 return read_variable_size<big_decimal>(field_name, field_kind::DECIMAL);
2596}
2597
2598boost::optional<hazelcast::client::local_time>
2599compact_reader::read_time(const std::string& field_name)
2600{
2601 return read_variable_size<hazelcast::client::local_time>(field_name,
2602 field_kind::TIME);
2603}
2604
2605boost::optional<hazelcast::client::local_date>
2606compact_reader::read_date(const std::string& field_name)
2607{
2608 return read_variable_size<hazelcast::client::local_date>(field_name,
2609 field_kind::DATE);
2610}
2611
2612boost::optional<hazelcast::client::local_date_time>
2613compact_reader::read_timestamp(const std::string& field_name)
2614{
2615 return read_variable_size<hazelcast::client::local_date_time>(
2616 field_name, field_kind::TIMESTAMP);
2617}
2618
2619boost::optional<hazelcast::client::offset_date_time>
2620compact_reader::read_timestamp_with_timezone(const std::string& field_name)
2621{
2622 return read_variable_size<hazelcast::client::offset_date_time>(
2623 field_name, field_kind::TIMESTAMP_WITH_TIMEZONE);
2624}
2625
2626boost::optional<std::vector<bool>>
2627compact_reader::read_array_of_boolean(const std::string& field_name)
2628{
2629 return read_array_of_primitive<std::vector<bool>>(
2630 field_name,
2631 field_kind::ARRAY_OF_BOOLEAN,
2632 field_kind::ARRAY_OF_NULLABLE_BOOLEAN,
2633 "boolean");
2634}
2635
2636boost::optional<std::vector<int8_t>>
2637compact_reader::read_array_of_int8(const std::string& field_name)
2638{
2639 return read_array_of_primitive<std::vector<int8_t>>(
2640 field_name,
2641 field_kind::ARRAY_OF_INT8,
2642 field_kind::ARRAY_OF_NULLABLE_INT8,
2643 "int8");
2644}
2645
2646boost::optional<std::vector<int16_t>>
2647compact_reader::read_array_of_int16(const std::string& field_name)
2648{
2649 return read_array_of_primitive<std::vector<int16_t>>(
2650 field_name,
2651 field_kind::ARRAY_OF_INT16,
2652 field_kind::ARRAY_OF_NULLABLE_INT16,
2653 "int16");
2654}
2655
2656boost::optional<std::vector<int32_t>>
2657compact_reader::read_array_of_int32(const std::string& field_name)
2658{
2659 return read_array_of_primitive<std::vector<int32_t>>(
2660 field_name,
2661 field_kind::ARRAY_OF_INT32,
2662 field_kind::ARRAY_OF_NULLABLE_INT32,
2663 "int32");
2664}
2665boost::optional<std::vector<int64_t>>
2666compact_reader::read_array_of_int64(const std::string& field_name)
2667{
2668 return read_array_of_primitive<std::vector<int64_t>>(
2669 field_name,
2670 field_kind::ARRAY_OF_INT64,
2671 field_kind::ARRAY_OF_NULLABLE_INT64,
2672 "int64");
2673}
2674
2675boost::optional<std::vector<float>>
2676compact_reader::read_array_of_float32(const std::string& field_name)
2677{
2678 return read_array_of_primitive<std::vector<float>>(
2679 field_name,
2680 field_kind::ARRAY_OF_FLOAT32,
2681 field_kind::ARRAY_OF_NULLABLE_FLOAT32,
2682 "float32");
2683}
2684
2685boost::optional<std::vector<double>>
2686compact_reader::read_array_of_float64(const std::string& field_name)
2687{
2688 return read_array_of_primitive<std::vector<double>>(
2689 field_name,
2690 field_kind::ARRAY_OF_FLOAT64,
2691 field_kind::ARRAY_OF_NULLABLE_FLOAT64,
2692 "float64");
2693}
2694
2695boost::optional<std::vector<boost::optional<std::string>>>
2696compact_reader::read_array_of_string(const std::string& field_name)
2697{
2698 const auto& descriptor =
2699 get_field_descriptor(field_name, field_kind::ARRAY_OF_STRING);
2700 return read_array_of_variable_size<std::string>(descriptor);
2701}
2702
2703boost::optional<std::vector<boost::optional<big_decimal>>>
2704compact_reader::read_array_of_decimal(const std::string& field_name)
2705{
2706 const auto& descriptor =
2707 get_field_descriptor(field_name, field_kind::ARRAY_OF_DECIMAL);
2708 return read_array_of_variable_size<big_decimal>(descriptor);
2709}
2710
2711boost::optional<std::vector<boost::optional<local_time>>>
2712compact_reader::read_array_of_time(const std::string& field_name)
2713{
2714 const auto& descriptor =
2715 get_field_descriptor(field_name, field_kind::ARRAY_OF_TIME);
2716 return read_array_of_variable_size<local_time>(descriptor);
2717}
2718
2719boost::optional<std::vector<boost::optional<local_date>>>
2720compact_reader::read_array_of_date(const std::string& field_name)
2721{
2722 const auto& descriptor =
2723 get_field_descriptor(field_name, field_kind::ARRAY_OF_DATE);
2724 return read_array_of_variable_size<local_date>(descriptor);
2725}
2726
2727boost::optional<std::vector<boost::optional<local_date_time>>>
2728compact_reader::read_array_of_timestamp(const std::string& field_name)
2729{
2730 const auto& descriptor =
2731 get_field_descriptor(field_name, field_kind::ARRAY_OF_TIMESTAMP);
2732 return read_array_of_variable_size<local_date_time>(descriptor);
2733}
2734
2735boost::optional<std::vector<boost::optional<offset_date_time>>>
2736compact_reader::read_array_of_timestamp_with_timezone(
2737 const std::string& field_name)
2738{
2739 const auto& descriptor = get_field_descriptor(
2740 field_name, field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE);
2741 return read_array_of_variable_size<offset_date_time>(descriptor);
2742}
2743
2744boost::optional<bool>
2745compact_reader::read_nullable_boolean(const std::string& field_name)
2746{
2747 return read_nullable_primitive<bool>(
2748 field_name, field_kind::BOOLEAN, field_kind::NULLABLE_BOOLEAN);
2749}
2750
2751boost::optional<int8_t>
2752compact_reader::read_nullable_int8(const std::string& field_name)
2753{
2754 return read_nullable_primitive<int8_t>(
2755 field_name, field_kind::INT8, field_kind::NULLABLE_INT8);
2756}
2757
2758boost::optional<int16_t>
2759compact_reader::read_nullable_int16(const std::string& field_name)
2760{
2761 return read_nullable_primitive<int16_t>(
2762 field_name, field_kind::INT16, field_kind::NULLABLE_INT16);
2763}
2764
2765boost::optional<int32_t>
2766compact_reader::read_nullable_int32(const std::string& field_name)
2767{
2768 return read_nullable_primitive<int32_t>(
2769 field_name, field_kind::INT32, field_kind::NULLABLE_INT32);
2770}
2771
2772boost::optional<int64_t>
2773compact_reader::read_nullable_int64(const std::string& field_name)
2774{
2775 return read_nullable_primitive<int64_t>(
2776 field_name, field_kind::INT64, field_kind::NULLABLE_INT64);
2777}
2778
2779boost::optional<float>
2780compact_reader::read_nullable_float32(const std::string& field_name)
2781{
2782 return read_nullable_primitive<float>(
2783 field_name, field_kind::FLOAT32, field_kind::NULLABLE_FLOAT32);
2784}
2785
2786boost::optional<double>
2787compact_reader::read_nullable_float64(const std::string& field_name)
2788{
2789 return read_nullable_primitive<double>(
2790 field_name, field_kind::FLOAT64, field_kind::NULLABLE_FLOAT64);
2791}
2792
2793boost::optional<std::vector<boost::optional<bool>>>
2794compact_reader::read_array_of_nullable_boolean(const std::string& field_name)
2795{
2796 return read_array_of_nullable<bool>(field_name,
2797 field_kind::ARRAY_OF_BOOLEAN,
2798 field_kind::ARRAY_OF_NULLABLE_BOOLEAN);
2799}
2800
2801boost::optional<std::vector<boost::optional<int8_t>>>
2802compact_reader::read_array_of_nullable_int8(const std::string& field_name)
2803{
2804 return read_array_of_nullable<int8_t>(field_name,
2805 field_kind::ARRAY_OF_INT8,
2806 field_kind::ARRAY_OF_NULLABLE_INT8);
2807}
2808
2809boost::optional<std::vector<boost::optional<int16_t>>>
2810compact_reader::read_array_of_nullable_int16(const std::string& field_name)
2811{
2812 return read_array_of_nullable<int16_t>(field_name,
2813 field_kind::ARRAY_OF_INT16,
2814 field_kind::ARRAY_OF_NULLABLE_INT16);
2815}
2816
2817boost::optional<std::vector<boost::optional<int32_t>>>
2818compact_reader::read_array_of_nullable_int32(const std::string& field_name)
2819{
2820 return read_array_of_nullable<int32_t>(field_name,
2821 field_kind::ARRAY_OF_INT32,
2822 field_kind::ARRAY_OF_NULLABLE_INT32);
2823}
2824
2825boost::optional<std::vector<boost::optional<int64_t>>>
2826compact_reader::read_array_of_nullable_int64(const std::string& field_name)
2827{
2828 return read_array_of_nullable<int64_t>(field_name,
2829 field_kind::ARRAY_OF_INT64,
2830 field_kind::ARRAY_OF_NULLABLE_INT64);
2831}
2832
2833boost::optional<std::vector<boost::optional<float>>>
2834compact_reader::read_array_of_nullable_float32(const std::string& field_name)
2835{
2836 return read_array_of_nullable<float>(field_name,
2837 field_kind::ARRAY_OF_FLOAT32,
2838 field_kind::ARRAY_OF_NULLABLE_FLOAT32);
2839}
2840
2841boost::optional<std::vector<boost::optional<double>>>
2842compact_reader::read_array_of_nullable_float64(const std::string& field_name)
2843{
2844 return read_array_of_nullable<double>(
2845 field_name,
2846 field_kind::ARRAY_OF_FLOAT64,
2847 field_kind::ARRAY_OF_NULLABLE_FLOAT64);
2848}
2849
2850} // namespace compact
2851
2852namespace pimpl {
2853
2854compact::compact_writer
2855create_compact_writer(pimpl::default_compact_writer* default_compact_writer)
2856{
2857 return compact::compact_writer{ default_compact_writer };
2858}
2859
2860compact::compact_writer
2861create_compact_writer(pimpl::schema_writer* schema_writer)
2862{
2863 return compact::compact_writer{ schema_writer };
2864}
2865
2866default_compact_writer::default_compact_writer(
2867 compact_stream_serializer& compact_stream_serializer,
2868 object_data_output& object_data_output,
2869 const schema& schema)
2870 : compact_stream_serializer_(compact_stream_serializer)
2871 , object_data_output_(object_data_output)
2872 , schema_(schema)
2873 , field_offsets(schema.number_of_var_size_fields())
2874{
2875 if (schema.number_of_var_size_fields() != 0) {
2876 data_start_position =
2877 object_data_output_.position() + util::Bits::INT_SIZE_IN_BYTES;
2878 // Skip for length and primitives.
2879 object_data_output_.write_zero_bytes(schema.fixed_size_fields_length() +
2880 util::Bits::INT_SIZE_IN_BYTES);
2881 } else {
2882 data_start_position = object_data_output_.position();
2883 // Skip for primitives. No need to write data length, when there is no
2884 // variable-size fields.
2885 object_data_output_.write_zero_bytes(schema.fixed_size_fields_length());
2886 }
2887}
2888
2889void
2890default_compact_writer::write_boolean(const std::string& field_name, bool value)
2891{
2892 field_descriptor descriptor =
2893 check_field_definition(field_name, field_kind::BOOLEAN);
2894 int32_t offset_in_bytes = descriptor.offset;
2895 int8_t offset_in_bits = descriptor.bit_offset;
2896 size_t write_offset = offset_in_bytes + data_start_position;
2897 object_data_output_.write_boolean_bit_at(
2898 write_offset, offset_in_bits, value);
2899}
2900
2901void
2902default_compact_writer::write_int8(const std::string& field_name, int8_t value)
2903{
2904 size_t position =
2905 get_fixed_size_field_position(field_name, field_kind::INT8);
2906 object_data_output_.write_at(position, value);
2907}
2908
2909void
2910default_compact_writer::write_int16(const std::string& field_name,
2911 int16_t value)
2912{
2913 size_t position =
2914 get_fixed_size_field_position(field_name, field_kind::INT16);
2915 object_data_output_.write_at(position, value);
2916}
2917
2918void
2919default_compact_writer::write_int32(const std::string& field_name,
2920 int32_t value)
2921{
2922 size_t position =
2923 get_fixed_size_field_position(field_name, field_kind::INT32);
2924 object_data_output_.write_at(position, value);
2925}
2926
2927void
2928default_compact_writer::write_int64(const std::string& field_name,
2929 int64_t value)
2930{
2931 size_t position =
2932 get_fixed_size_field_position(field_name, field_kind::INT64);
2933 object_data_output_.write_at(position, value);
2934}
2935
2936void
2937default_compact_writer::write_float32(const std::string& field_name,
2938 float value)
2939{
2940 size_t position =
2941 get_fixed_size_field_position(field_name, field_kind::FLOAT32);
2942 object_data_output_.write_at(position, value);
2943}
2944
2945void
2946default_compact_writer::write_float64(const std::string& field_name,
2947 double value)
2948{
2949 size_t position =
2950 get_fixed_size_field_position(field_name, field_kind::FLOAT64);
2951 object_data_output_.write_at(position, value);
2952}
2953
2954void
2955default_compact_writer::write_string(const std::string& field_name,
2956 const boost::optional<std::string>& value)
2957{
2958 write_variable_size_field(field_name, field_kind::STRING, value);
2959}
2960
2961void
2962default_compact_writer::write_decimal(const std::string& field_name,
2963 const boost::optional<big_decimal>& value)
2964{
2965 write_variable_size_field(field_name, field_kind::DECIMAL, value);
2966}
2967
2968void
2969default_compact_writer::write_time(
2970 const std::string& field_name,
2971 const boost::optional<hazelcast::client::local_time>& value)
2972{
2973 write_variable_size_field(field_name, field_kind::TIME, value);
2974}
2975void
2976default_compact_writer::write_date(
2977 const std::string& field_name,
2978 const boost::optional<hazelcast::client::local_date>& value)
2979{
2980 write_variable_size_field(field_name, field_kind::DATE, value);
2981}
2982
2983void
2984default_compact_writer::write_timestamp(
2985 const std::string& field_name,
2986 const boost::optional<hazelcast::client::local_date_time>& value)
2987{
2988 write_variable_size_field(field_name, field_kind::TIMESTAMP, value);
2989}
2990
2991void
2992default_compact_writer::write_timestamp_with_timezone(
2993 const std::string& field_name,
2994 const boost::optional<hazelcast::client::offset_date_time>& value)
2995{
2996 write_variable_size_field(
2997 field_name, field_kind::TIMESTAMP_WITH_TIMEZONE, value);
2998}
2999
3000void
3001default_compact_writer::write_array_of_boolean(
3002 const std::string& field_name,
3003 const boost::optional<std::vector<bool>>& value)
3004{
3005 write_variable_size_field(field_name, field_kind::ARRAY_OF_BOOLEAN, value);
3006}
3007
3008void
3009default_compact_writer::write_array_of_int8(
3010 const std::string& field_name,
3011 const boost::optional<std::vector<int8_t>>& value)
3012{
3013 write_variable_size_field(field_name, field_kind::ARRAY_OF_INT8, value);
3014}
3015
3016void
3017default_compact_writer::write_array_of_int16(
3018 const std::string& field_name,
3019 const boost::optional<std::vector<int16_t>>& value)
3020{
3021 write_variable_size_field(field_name, field_kind::ARRAY_OF_INT16, value);
3022}
3023
3024void
3025default_compact_writer::write_array_of_int32(
3026 const std::string& field_name,
3027 const boost::optional<std::vector<int32_t>>& value)
3028{
3029 write_variable_size_field(field_name, field_kind::ARRAY_OF_INT32, value);
3030}
3031
3032void
3033default_compact_writer::write_array_of_int64(
3034 const std::string& field_name,
3035 const boost::optional<std::vector<int64_t>>& value)
3036{
3037 write_variable_size_field(field_name, field_kind::ARRAY_OF_INT64, value);
3038}
3039
3040void
3041default_compact_writer::write_array_of_float32(
3042 const std::string& field_name,
3043 const boost::optional<std::vector<float>>& value)
3044{
3045 write_variable_size_field(field_name, field_kind::ARRAY_OF_FLOAT32, value);
3046}
3047
3048void
3049default_compact_writer::write_array_of_float64(
3050 const std::string& field_name,
3051 const boost::optional<std::vector<double>>& value)
3052{
3053 write_variable_size_field(field_name, field_kind::ARRAY_OF_FLOAT64, value);
3054}
3055
3056void
3057default_compact_writer::write_array_of_string(
3058 const std::string& field_name,
3059 const boost::optional<std::vector<boost::optional<std::string>>>& value)
3060{
3061 write_array_of_variable_size(
3062 field_name, field_kind::ARRAY_OF_STRING, value);
3063}
3064
3065void
3066default_compact_writer::write_array_of_decimal(
3067 const std::string& field_name,
3068 const boost::optional<std::vector<boost::optional<big_decimal>>>& value)
3069{
3070 write_array_of_variable_size(
3071 field_name, field_kind::ARRAY_OF_DECIMAL, value);
3072}
3073
3074void
3075default_compact_writer::write_array_of_time(
3076 const std::string& field_name,
3077 const boost::optional<std::vector<boost::optional<local_time>>>& value)
3078{
3079 write_array_of_variable_size(field_name, field_kind::ARRAY_OF_TIME, value);
3080}
3081
3082void
3083default_compact_writer::write_array_of_date(
3084 const std::string& field_name,
3085 const boost::optional<std::vector<boost::optional<local_date>>>& value)
3086{
3087 write_array_of_variable_size(field_name, field_kind::ARRAY_OF_DATE, value);
3088}
3089
3090void
3091default_compact_writer::write_array_of_timestamp(
3092 const std::string& field_name,
3093 const boost::optional<std::vector<boost::optional<local_date_time>>>& value)
3094{
3095 write_array_of_variable_size(
3096 field_name, field_kind::ARRAY_OF_TIMESTAMP, value);
3097}
3098
3099void
3100default_compact_writer::write_array_of_timestamp_with_timezone(
3101 const std::string& field_name,
3102 const boost::optional<std::vector<boost::optional<offset_date_time>>>& value)
3103{
3104 write_array_of_variable_size(
3105 field_name, field_kind::ARRAY_OF_TIMESTAMP_WITH_TIMEZONE, value);
3106}
3107
3108void
3109default_compact_writer::write_nullable_boolean(
3110 const std::string& field_name,
3111 const boost::optional<bool>& value)
3112{
3113 write_variable_size_field(field_name, field_kind::NULLABLE_BOOLEAN, value);
3114}
3115void
3116default_compact_writer::write_nullable_int8(
3117 const std::string& field_name,
3118 const boost::optional<int8_t>& value)
3119{
3120 write_variable_size_field(field_name, field_kind::NULLABLE_INT8, value);
3121}
3122void
3123default_compact_writer::write_nullable_int16(
3124 const std::string& field_name,
3125 const boost::optional<int16_t>& value)
3126{
3127 write_variable_size_field(field_name, field_kind::NULLABLE_INT16, value);
3128}
3129void
3130default_compact_writer::write_nullable_int32(
3131 const std::string& field_name,
3132 const boost::optional<int32_t>& value)
3133{
3134 write_variable_size_field(field_name, field_kind::NULLABLE_INT32, value);
3135}
3136void
3137default_compact_writer::write_nullable_int64(
3138 const std::string& field_name,
3139 const boost::optional<int64_t>& value)
3140{
3141 write_variable_size_field(field_name, field_kind::NULLABLE_INT64, value);
3142}
3143void
3144default_compact_writer::write_nullable_float32(
3145 const std::string& field_name,
3146 const boost::optional<float>& value)
3147{
3148 write_variable_size_field(field_name, field_kind::NULLABLE_FLOAT32, value);
3149}
3150void
3151default_compact_writer::write_nullable_float64(
3152 const std::string& field_name,
3153 const boost::optional<double>& value)
3154{
3155 write_variable_size_field(field_name, field_kind::NULLABLE_FLOAT64, value);
3156}
3157
3158void
3159default_compact_writer::write_array_of_nullable_boolean(
3160 const std::string& field_name,
3161 const boost::optional<std::vector<boost::optional<bool>>>& value)
3162{
3163 write_array_of_variable_size(
3164 field_name, field_kind::ARRAY_OF_NULLABLE_BOOLEAN, value);
3165}
3166
3167void
3168default_compact_writer::write_array_of_nullable_int8(
3169 const std::string& field_name,
3170 const boost::optional<std::vector<boost::optional<int8_t>>>& value)
3171{
3172 write_array_of_variable_size(
3173 field_name, field_kind::ARRAY_OF_NULLABLE_INT8, value);
3174}
3175
3176void
3177default_compact_writer::write_array_of_nullable_int16(
3178 const std::string& field_name,
3179 const boost::optional<std::vector<boost::optional<int16_t>>>& value)
3180{
3181 write_array_of_variable_size(
3182 field_name, field_kind::ARRAY_OF_NULLABLE_INT16, value);
3183}
3184
3185void
3186default_compact_writer::write_array_of_nullable_int32(
3187 const std::string& field_name,
3188 const boost::optional<std::vector<boost::optional<int32_t>>>& value)
3189{
3190 write_array_of_variable_size(
3191 field_name, field_kind::ARRAY_OF_NULLABLE_INT32, value);
3192}
3193
3194void
3195default_compact_writer::write_array_of_nullable_int64(
3196 const std::string& field_name,
3197 const boost::optional<std::vector<boost::optional<int64_t>>>& value)
3198{
3199 write_array_of_variable_size(
3200 field_name, field_kind::ARRAY_OF_NULLABLE_INT64, value);
3201}
3202
3203void
3204default_compact_writer::write_array_of_nullable_float32(
3205 const std::string& field_name,
3206 const boost::optional<std::vector<boost::optional<float>>>& value)
3207{
3208 write_array_of_variable_size(
3209 field_name, field_kind::ARRAY_OF_NULLABLE_FLOAT32, value);
3210}
3211
3212void
3213default_compact_writer::write_array_of_nullable_float64(
3214 const std::string& field_name,
3215 const boost::optional<std::vector<boost::optional<double>>>& value)
3216{
3217 write_array_of_variable_size(
3218 field_name, field_kind::ARRAY_OF_NULLABLE_FLOAT64, value);
3219}
3220
3221void
3222default_compact_writer::end()
3223{
3224 if (schema_.number_of_var_size_fields() == 0) {
3225 // There are no variable size fields
3226 return;
3227 }
3228 size_t position = object_data_output_.position();
3229 size_t data_length = position - data_start_position;
3230 write_offsets(data_length, field_offsets);
3231 // write dataLength
3232 object_data_output_.write_at(data_start_position -
3233 util::Bits::INT_SIZE_IN_BYTES,
3234 (int32_t)data_length);
3235}
3236
3237size_t
3238default_compact_writer::get_fixed_size_field_position(
3239 const std::string& field_name,
3240 enum field_kind field_kind) const
3241{
3242 const field_descriptor& field_descriptor =
3243 check_field_definition(field_name, field_kind);
3244 return field_descriptor.offset + data_start_position;
3245}
3246
3247const field_descriptor&
3248default_compact_writer::check_field_definition(const std::string& field_name,
3249 field_kind kind) const
3250{
3251 auto iterator = schema_.fields().find(field_name);
3252 if (iterator == schema_.fields().end()) {
3253 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
3254 "default_compact_writer",
3255 (boost::format("Invalid field name %1% for %2%") % field_name %
3256 schema_)
3257 .str()));
3258 }
3259 if (iterator->second.kind != kind) {
3260 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
3261 "default_compact_writer",
3262 (boost::format("Invalid field type %1% for %2%") % field_name %
3263 schema_)
3264 .str()));
3265 }
3266 return iterator->second;
3267}
3268
3269void
3270default_compact_writer::write_offsets(size_t data_length,
3271 const std::vector<int32_t>& offsets)
3272{
3273 if (data_length < offset_reader::BYTE_OFFSET_READER_RANGE) {
3274 for (int32_t offset : offsets) {
3275 object_data_output_.write<int8_t>(static_cast<int8_t>(offset));
3276 }
3277 } else if (data_length < offset_reader::SHORT_OFFSET_READER_RANGE) {
3278 for (int32_t offset : offsets) {
3279 object_data_output_.write<int16_t>(static_cast<int16_t>(offset));
3280 }
3281 } else {
3282 for (int32_t offset : offsets) {
3283 object_data_output_.write<int32_t>(offset);
3284 }
3285 }
3286}
3287
3288void
3289default_compact_writer::set_position(const std::string& field_name,
3290 enum field_kind field_kind)
3291{
3292 const auto& field_descriptor =
3293 check_field_definition(field_name, field_kind);
3294 size_t pos = object_data_output_.position();
3295 size_t fieldPosition = pos - data_start_position;
3296 int index = field_descriptor.index;
3297 field_offsets[index] = static_cast<int32_t>(fieldPosition);
3298}
3299
3300void
3301default_compact_writer::set_position_as_null(const std::string& field_name,
3302 enum field_kind field_kind)
3303{
3304 const auto& field_descriptor =
3305 check_field_definition(field_name, field_kind);
3306 int index = field_descriptor.index;
3307 field_offsets[index] = -1;
3308}
3309
3310std::array<uint64_t, 256>
3311init_fp_table()
3312{
3313 std::array<uint64_t, 256> FP_TABLE;
3314 for (int i = 0; i < 256; ++i) {
3315 uint64_t fp = i;
3316 for (int j = 0; j < 8; ++j) {
3317 fp = (fp >> 1) ^ (rabin_finger_print::INIT & -(fp & 1L));
3318 }
3319 FP_TABLE[i] = fp;
3320 }
3321 return FP_TABLE;
3322}
3323
3324constexpr uint64_t rabin_finger_print::INIT;
3325
3326uint64_t
3327rabin_finger_print::fingerprint64(uint64_t fp, byte b)
3328{
3329 static std::array<uint64_t, 256> FP_TABLE = init_fp_table();
3330 return (fp >> 8) ^ FP_TABLE[(int)(fp ^ b) & 0xff];
3331}
3332
3333uint64_t
3334rabin_finger_print::fingerprint64(uint64_t fp, int32_t v)
3335{
3336 fp = fingerprint64(fp, (byte)((v)&0xFF));
3337 fp = fingerprint64(fp, (byte)((v >> 8) & 0xFF));
3338 fp = fingerprint64(fp, (byte)((v >> 16) & 0xFF));
3339 fp = fingerprint64(fp, (byte)((v >> 24) & 0xFF));
3340 return fp;
3341}
3342
3343uint64_t
3344rabin_finger_print::fingerprint64(uint64_t fp, const std::string& value)
3345{
3346 fp = fingerprint64(fp, (int)value.size());
3347 for (const auto& item : value) {
3348 fp = fingerprint64(fp, (byte)item);
3349 }
3350 return fp;
3351}
3352
3356int64_t
3357rabin_finger_print::fingerprint64(
3358 const std::string& type_name,
3359 std::map<std::string, field_descriptor>& fields)
3360{
3361 uint64_t fingerPrint = fingerprint64(INIT, type_name);
3362 fingerPrint = fingerprint64(fingerPrint, (int)fields.size());
3363 for (const auto& entry : fields) {
3364 const field_descriptor& descriptor = entry.second;
3365 fingerPrint = fingerprint64(fingerPrint, entry.first);
3366 fingerPrint = fingerprint64(fingerPrint, (int)descriptor.kind);
3367 }
3368
3369 int64_t signed_fp{};
3370
3371 std::memcpy(&signed_fp, &fingerPrint, sizeof(uint64_t));
3372 return signed_fp;
3373}
3374
3375bool
3376kind_size_comparator(const field_descriptor* i, const field_descriptor* j)
3377{
3378 auto i_kind_size = field_operations::get(i->kind).kind_size_in_byte_func();
3379 auto j_kind_size = field_operations::get(j->kind).kind_size_in_byte_func();
3380 return i_kind_size > j_kind_size;
3381}
3382
3383schema::schema(
3384 std::string type_name,
3385 std::unordered_map<std::string, field_descriptor>&& field_definition_map)
3386 : type_name_(std::move(type_name))
3387 , field_definition_map_(std::move(field_definition_map))
3388{
3389 std::vector<field_descriptor*> fixed_size_fields;
3390 std::vector<field_descriptor*> boolean_fields;
3391 std::vector<field_descriptor*> variable_size_fields;
3392
3393 std::map<std::string, field_descriptor> sorted_fields(
3394 field_definition_map_.begin(), field_definition_map_.end());
3395 for (auto& item : sorted_fields) {
3396 field_descriptor& descriptor = item.second;
3397 field_kind kind = descriptor.kind;
3398 if (field_operations::get(kind).kind_size_in_byte_func() ==
3399 field_kind_based_operations::VARIABLE_SIZE) {
3400 variable_size_fields.push_back(&descriptor);
3401 } else if (kind == field_kind::BOOLEAN) {
3402 boolean_fields.push_back(&descriptor);
3403 } else {
3404 fixed_size_fields.push_back(&descriptor);
3405 }
3406 }
3407
3408 std::sort(
3409 fixed_size_fields.begin(), fixed_size_fields.end(), kind_size_comparator);
3410
3411 int offset = 0;
3412 for (auto descriptor : fixed_size_fields) {
3413 descriptor->offset = offset;
3414 offset +=
3415 field_operations::get(descriptor->kind).kind_size_in_byte_func();
3416 }
3417
3418 int8_t bit_offset = 0;
3419 for (auto descriptor : boolean_fields) {
3420 descriptor->offset = offset;
3421 descriptor->bit_offset =
3422 static_cast<int8_t>(bit_offset % util::Bits::BITS_IN_BYTE);
3423 bit_offset++;
3424 if (bit_offset % util::Bits::BITS_IN_BYTE == 0) {
3425 offset += 1;
3426 }
3427 }
3428 if (bit_offset % util::Bits::BITS_IN_BYTE != 0) {
3429 offset += 1;
3430 }
3431
3432 fixed_size_fields_length_ = offset;
3433
3434 int index = 0;
3435 for (auto descriptor : variable_size_fields) {
3436 descriptor->index = index;
3437 index++;
3438 }
3439
3440 for (auto& item : sorted_fields) {
3441 auto field = field_definition_map_.find(item.first);
3442
3443 assert(field != end(field_definition_map_));
3444 field->second = item.second;
3445 }
3446
3447 number_of_var_size_fields_ = index;
3448 schema_id_ = rabin_finger_print::fingerprint64(type_name_, sorted_fields);
3449}
3450
3451int64_t
3452schema::schema_id() const
3453{
3454 return schema_id_;
3455}
3456
3457size_t
3458schema::number_of_var_size_fields() const
3459{
3460 return number_of_var_size_fields_;
3461}
3462
3463size_t
3464schema::fixed_size_fields_length() const
3465{
3466 return fixed_size_fields_length_;
3467}
3468
3469const std::string&
3470schema::type_name() const
3471{
3472 return type_name_;
3473}
3474
3475const std::unordered_map<std::string, field_descriptor>&
3476schema::fields() const
3477{
3478 return field_definition_map_;
3479}
3480
3481boost::optional<field_descriptor>
3482schema::get_field(const std::string& field_name) const
3483{
3484 auto descriptor_itr = field_definition_map_.find(field_name);
3485
3486 if (descriptor_itr == end(field_definition_map_))
3487 return boost::none;
3488
3489 return descriptor_itr->second;
3490}
3491
3492bool
3493operator==(const schema& x, const schema& y)
3494{
3495 return x.number_of_var_size_fields() == y.number_of_var_size_fields() &&
3496 x.fixed_size_fields_length() == y.fixed_size_fields_length() &&
3497 x.schema_id() == y.schema_id() && x.type_name() == y.type_name() &&
3498 x.fields() == y.fields();
3499}
3500
3501bool
3502operator!=(const schema& x, const schema& y)
3503{
3504 return !(x == y);
3505}
3506
3507std::ostream&
3508operator<<(std::ostream& os, const schema& schema)
3509{
3510 os << "Schema { className = " << schema.type_name()
3511 << ", numberOfComplextFields = " << schema.number_of_var_size_fields()
3512 << ",primitivesLength = " << schema.fixed_size_fields_length()
3513 << ",fields {";
3514 for (const auto& item : schema.fields()) {
3515 os << item.first << " " << item.second << ",";
3516 }
3517 os << "}";
3518 return os;
3519}
3520
3521} // namespace pimpl
3522
3523namespace pimpl {
3524
3525exception::hazelcast_serialization
3526compact_util::exception_for_unexpected_null_value(
3527 const std::string& field_name,
3528 const std::string& method_prefix,
3529 const std::string& method_suffix)
3530{
3531 return exception::hazelcast_serialization{ boost::str(
3532 boost::format("Error while reading %1%. null value can not be read via "
3533 "%2%%3% methods. Use %2%Nullable%3% instead.") %
3534 field_name % method_prefix % method_suffix) };
3535}
3536
3537exception::hazelcast_serialization
3538compact_util::exception_for_unexpected_null_value_in_array(
3539 const std::string& field_name,
3540 const std::string& method_prefix,
3541 const std::string& method_suffix)
3542{
3543 return exception::hazelcast_serialization{ boost::str(
3544 boost::format(
3545 "Error while reading %1%. null value can not be read via %2%ArrayOf%3% "
3546 "methods. Use %2%ArrayOfNullable%3% instead.") %
3547 field_name % method_prefix % method_suffix) };
3548}
3549
3550schema_writer::schema_writer(std::string type_name)
3551 : type_name_(std::move(type_name))
3552{}
3553
3554void
3555schema_writer::add_field(std::string field_name, enum field_kind kind)
3556{
3557 if (field_definition_map_.find(field_name) != end(field_definition_map_)) {
3558 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization{
3559 "Field with the name '" + field_name + "' already exists." });
3560 }
3561
3562 field_definition_map_.emplace(std::move(field_name), field_descriptor{ kind });
3563}
3564
3565schema
3566schema_writer::build() &&
3567{
3568 return schema{ type_name_, std::move(field_definition_map_) };
3569}
3570
3571default_schema_service::default_schema_service(spi::ClientContext& context)
3572 : retry_pause_millis_{ context.get_client_properties().get_integer(
3573 context.get_client_properties().get_invocation_retry_pause_millis()) }
3574 , max_put_retry_count_{ context.get_client_properties().get_integer(
3575 client_property{ MAX_PUT_RETRY_COUNT, MAX_PUT_RETRY_COUNT_DEFAULT }) }
3576 , context_(context)
3577{
3578}
3579
3580std::shared_ptr<schema>
3581default_schema_service::get(int64_t schemaId)
3582{
3583 auto ptr = replicateds_.get(schemaId);
3584
3585 if (ptr) {
3586 return ptr;
3587 }
3588
3589 auto logger = context_.get_logger();
3590 if (logger.enabled(logger::level::finest)) {
3591 logger.log(
3592 logger::level::finest,
3593 boost::str(boost::format("Could not find schema id %1% locally, will "
3594 "search on the cluster %1%") %
3595 schemaId));
3596 }
3597
3598 using namespace protocol::codec;
3599
3600 auto request_message = client_fetchschema_encode(schemaId);
3601
3602 auto invocation = spi::impl::ClientInvocation::create(
3603 context_, request_message, SERVICE_NAME);
3604 auto message = invocation->invoke().get();
3605
3606 message.skip_frame();
3607 auto sch = message.get_nullable<schema>();
3608
3609 std::shared_ptr<schema> schema_ptr;
3610
3611 if (sch) {
3612 schema_ptr = std::make_shared<schema>(std::move(*sch));
3613 replicateds_.put_if_absent(schemaId, schema_ptr);
3614 }
3615
3616 return schema_ptr;
3617}
3618
3619void
3620default_schema_service::replicate_schema_in_cluster(schema s)
3621{
3622 using hazelcast::client::protocol::ClientMessage;
3623 using namespace protocol::codec;
3624
3625 for (int i = 0; i < max_put_retry_count_; ++i) {
3626 auto message = client_sendschema_encode(s);
3627
3628 auto invocation =
3629 spi::impl::ClientInvocation::create(context_, message, SERVICE_NAME);
3630
3631 auto response = invocation->invoke().get();
3632 auto replicated_member_uuids = send_schema_response_decode(response);
3633 auto members = context_.get_cluster().get_members();
3634
3635 bool contains;
3636 for (const member& member : members) {
3637
3638 contains = replicated_member_uuids.find(member.get_uuid()) !=
3639 end(replicated_member_uuids);
3640
3641 if (!contains) {
3642 if (i == (max_put_retry_count_ - 1)) {
3643 throw exception::illegal_state{
3644 "default_schema_service::replicate_schema_attempt",
3645 (boost::format("The schema %1% cannot be "
3646 "replicated in the cluster, after "
3647 "%2% retries. It might be the case "
3648 "that the client is experiencing a "
3649 "split-brain, and continue putting "
3650 "the data associated with that "
3651 "schema might result in data loss. "
3652 "It might be possible to replicate "
3653 "the schema after some time, when "
3654 "the cluster is healed.") %
3655 s % max_put_retry_count_)
3656 .str()
3657 };
3658 } else {
3659 std::this_thread::sleep_for(
3660 std::chrono::milliseconds{ retry_pause_millis_ });
3661
3662 if (!context_.get_lifecycle_service().is_running()) {
3663 return;
3664 }
3665
3666 break;
3667 }
3668 }
3669 }
3670
3671 if (contains) {
3672 put_if_absent(std::move(s));
3673
3674 break;
3675 }
3676 }
3677}
3678
3679bool
3680default_schema_service::is_schema_replicated(const schema& s)
3681{
3682 return bool(replicateds_.get(s.schema_id()));
3683}
3684
3685void
3686default_schema_service::put_if_absent(schema s)
3687{
3688 auto s_p = std::make_shared<schema>(std::move(s));
3689 auto existing = replicateds_.put_if_absent(s_p->schema_id(), s_p);
3690
3691 if (!existing) {
3692 return;
3693 }
3694
3695 if (*s_p != *existing) {
3696 throw exception::illegal_state{
3697 "default_schema_service::replicate_schema_attempt",
3698 (boost::format("Schema with schemaId %1% "
3699 "already exists. Existing "
3700 "schema %2%, new schema %3%") %
3701 s_p->schema_id() % *existing % *s_p)
3702 .str()
3703 };
3704 }
3705}
3706
3710std::unordered_set<boost::uuids::uuid, boost::hash<boost::uuids::uuid>>
3711default_schema_service::send_schema_response_decode(
3712 protocol::ClientMessage& message)
3713{
3714 message.skip_frame();
3715 return message.get<std::unordered_set<boost::uuids::uuid,
3716 boost::hash<boost::uuids::uuid>>>();
3717}
3718
3719bool
3720default_schema_service::has_any_schemas() const
3721{
3722 return replicateds_.size();
3723}
3724
3725std::ostream&
3726operator<<(std::ostream& os, const std::vector<schema>& schemas)
3727{
3728 os << "Schemas {";
3729
3730 for (const auto& s : schemas)
3731 os << s << " , ";
3732
3733 os << "}";
3734
3735 return os;
3736}
3737
3738void
3739default_schema_service::replicate_all_schemas()
3740{
3741 using level = hazelcast::logger::level;
3742 using namespace protocol::codec;
3743
3744 auto logger = context_.get_logger();
3745 if (replicateds_.empty()) {
3746 if (logger.enabled(level::finest)) {
3747 logger.log(level::finest,
3748 "There is no schema to send to the cluster.");
3749 }
3750
3751 return;
3752 }
3753
3754 std::vector<std::shared_ptr<schema>> schemas_sptr = replicateds_.values();
3755 std::vector<schema> all_schemas;
3756
3757 all_schemas.reserve(schemas_sptr.size());
3758
3759 transform(begin(schemas_sptr),
3760 end(schemas_sptr),
3761 back_inserter(all_schemas),
3762 [](const std::shared_ptr<schema>& s) { return *s; });
3763
3764 if (logger.enabled(level::finest)) {
3765 logger.log(
3766 level::finest,
3767 (boost::format("Sending schemas to the cluster %1%") % all_schemas)
3768 .str());
3769 }
3770
3771 auto message = client_sendallschemas_encode(all_schemas);
3772
3773 auto invocation =
3774 spi::impl::ClientInvocation::create(context_, message, SERVICE_NAME);
3775
3776 invocation->invoke_urgent().get();
3777}
3778
3779compact_stream_serializer::compact_stream_serializer(
3780 default_schema_service& service)
3781 : schema_service(service)
3782{
3783}
3784
3785generic_record::generic_record
3786compact_stream_serializer::read_generic_record(object_data_input& in)
3787{
3788 int64_t schema_id = in.read<int64_t>();
3789
3790 auto sch = schema_service.get(schema_id);
3791
3792 if (!sch) {
3793 throw exception::hazelcast_serialization{
3794 "compact_stream_serializer::read_generic_record",
3795 boost::str(
3796 boost::format(
3797 "The schema can not be found with id %1%") %
3798 schema_id)
3799 };
3800 }
3801
3802 compact::compact_reader reader = create_compact_reader(*this, in, *sch);
3803 generic_record::generic_record_builder builder{ sch };
3804
3805 for (const std::pair<const std::string, field_descriptor>& p : sch->fields()) {
3806 const std::string& field_name = p.first;
3807 const field_descriptor& descriptor = p.second;
3808 field_operations::get(descriptor.kind)
3809 .read_generic_record_or_primitive(reader, builder, field_name);
3810 }
3811
3812 return builder.build();
3813}
3814
3815void
3816compact_stream_serializer::write_generic_record(
3817 const generic_record::generic_record& record,
3818 object_data_output& out)
3819{
3820 const schema& s = record.get_schema();
3821
3822 if (!schema_service.is_schema_replicated(s)) {
3823 out.schemas_will_be_replicated_.push_back(s);
3824 }
3825
3826 out.write<int64_t>(s.schema_id());
3827 default_compact_writer default_writer(*this, out, s);
3828
3829 const auto& fields = s.fields();
3830 for (std::pair<std::string, field_descriptor> pair : fields) {
3831 const std::string& field = pair.first;
3832 const field_descriptor& desc = pair.second;
3833
3834 field_operations::get(desc.kind).write_field_from_record_to_writer(
3835 default_writer, record, field);
3836 }
3837
3838 default_writer.end();
3839}
3840
3841field_kind_based_operations::field_kind_based_operations()
3842 : kind_size_in_byte_func(DEFAULT_KIND_SIZE_IN_BYTES)
3843{}
3844
3845field_kind_based_operations::field_kind_based_operations(
3846 kind_size_in_bytes_fn kind_size_fn,
3847 write_field_from_record_to_writer_fn write_fn,
3848 read_generic_record_or_primitive_fn read_fn,
3849 write_json_formatted_field_fn json_fn)
3850 : kind_size_in_byte_func(std::move(kind_size_fn))
3851 , write_field_from_record_to_writer(std::move(write_fn))
3852 , read_generic_record_or_primitive(std::move(read_fn))
3853 , write_json_formatted_field(std::move(json_fn))
3854{}
3855
3856const field_kind_based_operations&
3857field_operations::get(field_kind kind)
3858{
3859 using util::Bits;
3860 using namespace boost::property_tree;
3861
3862 static const std::string NULL_STRING = "null";
3863 static const std::string BOOL_STRING[2] = { "true", "false" };
3864
3865 static auto time_to_string = [](const local_time& lt) {
3866 return boost::str(boost::format("%02d:%02d:%02d.%d") % int(lt.hours) %
3867 int(lt.minutes) % int(lt.seconds) % lt.nanos);
3868 };
3869
3870 static auto date_to_string = [](const local_date& lt) {
3871 return boost::str(boost::format("%d-%02d-%02d") % lt.year %
3872 int(lt.month) % int(lt.day_of_month));
3873 };
3874
3875 static auto timestamp_to_string = [](const local_date_time& lt) {
3876 return boost::str(boost::format("%1%T%2%") % date_to_string(lt.date) %
3877 time_to_string(lt.time));
3878 };
3879
3880 static auto timestamp_with_timezone_to_string =
3881 [](const offset_date_time& lt) {
3882 auto hours = lt.zone_offset_in_seconds / 60;
3883 auto seconds = lt.zone_offset_in_seconds % 60;
3884 return boost::str(boost::format("%1%%2%:%3%") %
3885 timestamp_to_string(lt.date_time) % hours %
3886 seconds);
3887 };
3888
3889 static const field_kind_based_operations ALL[] = {
3890 field_kind_based_operations{}, // [0]NOT_AVAILABLE
3891 field_kind_based_operations{
3892 // [1]BOOLEAN
3893 [] { return 0; },
3894 [](default_compact_writer& writer,
3895 const generic_record::generic_record& record,
3896 const std::string& field) {
3897 writer.write_boolean(field, record.get_boolean(field));
3898 },
3899 [](compact::compact_reader& reader,
3900 generic_record::generic_record_builder& builder,
3901 const std::string& field) {
3902 builder.set_boolean(field, reader.read_boolean(field));
3903 },
3904 [](boost::property_tree::ptree& parent,
3905 const generic_record::generic_record& record,
3906 const std::string& field_name) {
3907 parent.put(field_name, record.get_boolean(field_name));
3908 } },
3909 field_kind_based_operations{
3910 // [2]ARRAY_OF_BOOLEAN
3911 [] { return field_kind_based_operations::VARIABLE_SIZE; },
3912 [](default_compact_writer& writer,
3913 const generic_record::generic_record& record,
3914 const std::string& field) {
3915 writer.write_array_of_boolean(field,
3916 record.get_array_of_boolean(field));
3917 },
3918 [](compact::compact_reader& reader,
3919 generic_record::generic_record_builder& builder,
3920 const std::string& field) {
3921 builder.set_array_of_boolean(field,
3922 reader.read_array_of_boolean(field));
3923 },
3924 [](ptree& parent,
3925 const generic_record::generic_record& record,
3926 const std::string& field_name) {
3927 const auto& values = record.get_array_of_boolean(field_name);
3928
3929 if (!values) {
3930 parent.put(field_name, NULL_STRING);
3931 } else {
3932 ptree array;
3933
3934 for (bool value : *values) {
3935 array.push_back(
3936 std::make_pair("", ptree(BOOL_STRING[value])));
3937 }
3938
3939 parent.put_child(field_name, array);
3940 }
3941 } },
3942 field_kind_based_operations{
3943 // [3]INT8
3944 [] { return 1; },
3945 [](default_compact_writer& writer,
3946 const generic_record::generic_record& record,
3947 const std::string& field) {
3948 writer.write_int8(field, record.get_int8(field));
3949 },
3950 [](compact::compact_reader& reader,
3951 generic_record::generic_record_builder& builder,
3952 const std::string& field) {
3953 builder.set_int8(field, reader.read_int8(field));
3954 },
3955 [](boost::property_tree::ptree& parent,
3956 const generic_record::generic_record& record,
3957 const std::string& field_name) {
3958 parent.put(field_name, record.get_int8(field_name));
3959 } },
3960 field_kind_based_operations{
3961 // [4]ARRAY_OF_INT8
3962 [] { return field_kind_based_operations::VARIABLE_SIZE; },
3963 [](default_compact_writer& writer,
3964 const generic_record::generic_record& record,
3965 const std::string& field) {
3966 writer.write_array_of_int8(field,
3967 record.get_array_of_int8(field));
3968 },
3969 [](compact::compact_reader& reader,
3970 generic_record::generic_record_builder& builder,
3971 const std::string& field) {
3972 builder.set_array_of_int8(field,
3973 reader.read_array_of_int8(field));
3974 },
3975 [](ptree& parent,
3976 const generic_record::generic_record& record,
3977 const std::string& field_name) {
3978 const auto& values = record.get_array_of_int8(field_name);
3979
3980 if (!values) {
3981 parent.put(field_name, NULL_STRING);
3982 } else {
3983 ptree array;
3984
3985 for (auto value : *values) {
3986 array.push_back(
3987 std::make_pair("", ptree(std::to_string(value))));
3988 }
3989
3990 parent.put_child(field_name, array);
3991 }
3992 } },
3993 field_kind_based_operations{}, // [5]
3994 field_kind_based_operations{}, // [6]
3995 field_kind_based_operations{
3996 // [7]INT16
3997 [] { return Bits::SHORT_SIZE_IN_BYTES; },
3998 [](default_compact_writer& writer,
3999 const generic_record::generic_record& record,
4000 const std::string& field) {
4001 writer.write_int16(field, record.get_int16(field));
4002 },
4003 [](compact::compact_reader& reader,
4004 generic_record::generic_record_builder& builder,
4005 const std::string& field) {
4006 builder.set_int16(field, reader.read_int16(field));
4007 },
4008 [](boost::property_tree::ptree& pt,
4009 const generic_record::generic_record& record,
4010 const std::string& field_name) {
4011 pt.put(field_name, record.get_int16(field_name));
4012 } },
4013 field_kind_based_operations{
4014 // [8]ARRAY_OF_INT16
4015 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4016 [](default_compact_writer& writer,
4017 const generic_record::generic_record& record,
4018 const std::string& field) {
4019 writer.write_array_of_int16(field,
4020 record.get_array_of_int16(field));
4021 },
4022 [](compact::compact_reader& reader,
4023 generic_record::generic_record_builder& builder,
4024 const std::string& field) {
4025 builder.set_array_of_int16(field,
4026 reader.read_array_of_int16(field));
4027 },
4028 [](ptree& parent,
4029 const generic_record::generic_record& record,
4030 const std::string& field_name) {
4031 const auto& values = record.get_array_of_int16(field_name);
4032
4033 if (!values) {
4034 parent.put(field_name, NULL_STRING);
4035 } else {
4036 ptree array;
4037
4038 for (auto value : *values) {
4039 array.push_back(
4040 std::make_pair("", ptree(std::to_string(value))));
4041 }
4042
4043 parent.put_child(field_name, array);
4044 }
4045 } },
4046 field_kind_based_operations{
4047 // [9]INT32
4048 [] { return Bits::INT_SIZE_IN_BYTES; },
4049 [](default_compact_writer& writer,
4050 const generic_record::generic_record& record,
4051 const std::string& field) {
4052 writer.write_int32(field, record.get_int32(field));
4053 },
4054 [](compact::compact_reader& reader,
4055 generic_record::generic_record_builder& builder,
4056 const std::string& field) {
4057 builder.set_int32(field, reader.read_int32(field));
4058 },
4059 [](boost::property_tree::ptree& parent,
4060 const generic_record::generic_record& record,
4061 const std::string& field_name) {
4062 parent.put(field_name, record.get_int32(field_name));
4063 } },
4064 field_kind_based_operations{
4065 // [10]ARRAY_OF_INT32
4066 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4067 [](default_compact_writer& writer,
4068 const generic_record::generic_record& record,
4069 const std::string& field) {
4070 writer.write_array_of_int32(field,
4071 record.get_array_of_int32(field));
4072 },
4073 [](compact::compact_reader& reader,
4074 generic_record::generic_record_builder& builder,
4075 const std::string& field) {
4076 builder.set_array_of_int32(field,
4077 reader.read_array_of_int32(field));
4078 },
4079 [](ptree& parent,
4080 const generic_record::generic_record& record,
4081 const std::string& field_name) {
4082 const auto& values = record.get_array_of_int32(field_name);
4083
4084 if (!values) {
4085 parent.put(field_name, NULL_STRING);
4086 } else {
4087 ptree array;
4088
4089 for (auto value : *values) {
4090 array.push_back(
4091 std::make_pair("", ptree(std::to_string(value))));
4092 }
4093
4094 parent.put_child(field_name, array);
4095 }
4096 } },
4097 field_kind_based_operations{
4098 // [11]INT64
4099 [] { return Bits::LONG_SIZE_IN_BYTES; },
4100 [](default_compact_writer& writer,
4101 const generic_record::generic_record& record,
4102 const std::string& field) {
4103 writer.write_int64(field, record.get_int64(field));
4104 },
4105 [](compact::compact_reader& reader,
4106 generic_record::generic_record_builder& builder,
4107 const std::string& field) {
4108 builder.set_int64(field, reader.read_int64(field));
4109 },
4110 [](boost::property_tree::ptree& parent,
4111 const generic_record::generic_record& record,
4112 const std::string& field_name) {
4113 parent.put(field_name, record.get_int64(field_name));
4114 } },
4115 field_kind_based_operations{
4116 // [12]ARRAY_OF_INT64
4117 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4118 [](default_compact_writer& writer,
4119 const generic_record::generic_record& record,
4120 const std::string& field) {
4121 writer.write_array_of_int64(field,
4122 record.get_array_of_int64(field));
4123 },
4124 [](compact::compact_reader& reader,
4125 generic_record::generic_record_builder& builder,
4126 const std::string& field) {
4127 builder.set_array_of_int64(field,
4128 reader.read_array_of_int64(field));
4129 },
4130 [](ptree& parent,
4131 const generic_record::generic_record& record,
4132 const std::string& field_name) {
4133 const auto& values = record.get_array_of_int64(field_name);
4134
4135 if (!values) {
4136 parent.put(field_name, NULL_STRING);
4137 } else {
4138 ptree array;
4139
4140 for (auto value : *values) {
4141 array.push_back(
4142 std::make_pair("", ptree(std::to_string(value))));
4143 }
4144
4145 parent.put_child(field_name, array);
4146 }
4147 } },
4148 field_kind_based_operations{
4149 // [13]FLOAT32
4150 [] { return Bits::FLOAT_SIZE_IN_BYTES; },
4151 [](default_compact_writer& writer,
4152 const generic_record::generic_record& record,
4153 const std::string& field) {
4154 writer.write_float32(field, record.get_float32(field));
4155 },
4156 [](compact::compact_reader& reader,
4157 generic_record::generic_record_builder& builder,
4158 const std::string& field) {
4159 builder.set_float32(field, reader.read_float32(field));
4160 },
4161 [](boost::property_tree::ptree& parent,
4162 const generic_record::generic_record& record,
4163 const std::string& field_name) {
4164 parent.put(field_name, record.get_float32(field_name));
4165 } },
4166 field_kind_based_operations{
4167 // [14]ARRAY_OF_FLOAT32
4168 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4169 [](default_compact_writer& writer,
4170 const generic_record::generic_record& record,
4171 const std::string& field) {
4172 writer.write_array_of_float32(field,
4173 record.get_array_of_float32(field));
4174 },
4175 [](compact::compact_reader& reader,
4176 generic_record::generic_record_builder& builder,
4177 const std::string& field) {
4178 builder.set_array_of_float32(field,
4179 reader.read_array_of_float32(field));
4180 },
4181 [](ptree& parent,
4182 const generic_record::generic_record& record,
4183 const std::string& field_name) {
4184 const auto& values = record.get_array_of_float32(field_name);
4185
4186 if (!values) {
4187 parent.put(field_name, NULL_STRING);
4188 } else {
4189 ptree array;
4190
4191 for (auto value : *values) {
4192 array.push_back(
4193 std::make_pair("", ptree(std::to_string(value))));
4194 }
4195
4196 parent.put_child(field_name, array);
4197 }
4198 } },
4199 field_kind_based_operations{
4200 // [15]FLOAT64
4201 [] { return Bits::DOUBLE_SIZE_IN_BYTES; },
4202 [](default_compact_writer& writer,
4203 const generic_record::generic_record& record,
4204 const std::string& field) {
4205 writer.write_float64(field, record.get_float64(field));
4206 },
4207 [](compact::compact_reader& reader,
4208 generic_record::generic_record_builder& builder,
4209 const std::string& field) {
4210 builder.set_float64(field, reader.read_float64(field));
4211 },
4212 [](boost::property_tree::ptree& parent,
4213 const generic_record::generic_record& record,
4214 const std::string& field_name) {
4215 parent.put(field_name, record.get_float64(field_name));
4216 } },
4217 field_kind_based_operations{
4218 // [16]ARRAY_OF_FLOAT64
4219 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4220 [](default_compact_writer& writer,
4221 const generic_record::generic_record& record,
4222 const std::string& field) {
4223 writer.write_array_of_float64(field,
4224 record.get_array_of_float64(field));
4225 },
4226 [](compact::compact_reader& reader,
4227 generic_record::generic_record_builder& builder,
4228 const std::string& field) {
4229 builder.set_array_of_float64(field,
4230 reader.read_array_of_float64(field));
4231 },
4232 [](ptree& parent,
4233 const generic_record::generic_record& record,
4234 const std::string& field_name) {
4235 const auto& values = record.get_array_of_float64(field_name);
4236
4237 if (!values) {
4238 parent.put(field_name, NULL_STRING);
4239 } else {
4240 ptree array;
4241
4242 for (auto value : *values) {
4243 array.push_back(
4244 std::make_pair("", ptree(std::to_string(value))));
4245 }
4246
4247 parent.put_child(field_name, array);
4248 }
4249 } },
4250 field_kind_based_operations{
4251 // [17]STRING
4252 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4253 [](default_compact_writer& writer,
4254 const generic_record::generic_record& record,
4255 const std::string& field) {
4256 writer.write_string(field, record.get_string(field));
4257 },
4258 [](compact::compact_reader& reader,
4259 generic_record::generic_record_builder& builder,
4260 const std::string& field) {
4261 builder.set_string(field, reader.read_string(field));
4262 },
4263 [](boost::property_tree::ptree& parent,
4264 const generic_record::generic_record& record,
4265 const std::string& field_name) {
4266 const auto& value = record.get_string(field_name);
4267
4268 if (!value) {
4269 parent.put(field_name, NULL_STRING);
4270 } else {
4271 parent.put(field_name, *value);
4272 }
4273 } },
4274 field_kind_based_operations{
4275 // [18]ARRAY_OF_STRING
4276 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4277 [](default_compact_writer& writer,
4278 const generic_record::generic_record& record,
4279 const std::string& field) {
4280 writer.write_array_of_string(field,
4281 record.get_array_of_string(field));
4282 },
4283 [](compact::compact_reader& reader,
4284 generic_record::generic_record_builder& builder,
4285 const std::string& field) {
4286 builder.set_array_of_string(field,
4287 reader.read_array_of_string(field));
4288 },
4289 [](ptree& parent,
4290 const generic_record::generic_record& record,
4291 const std::string& field_name) {
4292 const auto& values = record.get_array_of_string(field_name);
4293
4294 if (!values) {
4295 parent.put(field_name, NULL_STRING);
4296 } else {
4297 ptree array;
4298
4299 for (const auto& value : *values) {
4300 if (!value) {
4301 array.push_back(
4302 std::make_pair("", ptree(NULL_STRING)));
4303 } else {
4304 array.push_back(std::make_pair("", ptree(*value)));
4305 }
4306 }
4307
4308 parent.put_child(field_name, array);
4309 }
4310 } },
4311 field_kind_based_operations{
4312 // [19]DECIMAL
4313 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4314 [](default_compact_writer& writer,
4315 const generic_record::generic_record& record,
4316 const std::string& field) {
4317 writer.write_decimal(field, record.get_decimal(field));
4318 },
4319 [](compact::compact_reader& reader,
4320 generic_record::generic_record_builder& builder,
4321 const std::string& field) {
4322 builder.set_decimal(field, reader.read_decimal(field));
4323 },
4324 [](boost::property_tree::ptree& parent,
4325 const generic_record::generic_record& record,
4326 const std::string& field_name) {
4327 const auto& value = record.get_decimal(field_name);
4328
4329 if (!value) {
4330 parent.put(field_name, NULL_STRING);
4331 } else {
4332 parent.put(field_name,
4333 value->unscaled.str() + "E" +
4334 std::to_string(value->scale));
4335 }
4336 } },
4337 field_kind_based_operations{
4338 // [20]ARRAY_OF_DECIMAL
4339 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4340 [](default_compact_writer& writer,
4341 const generic_record::generic_record& record,
4342 const std::string& field) {
4343 writer.write_array_of_decimal(field,
4344 record.get_array_of_decimal(field));
4345 },
4346 [](compact::compact_reader& reader,
4347 generic_record::generic_record_builder& builder,
4348 const std::string& field) {
4349 builder.set_array_of_decimal(field,
4350 reader.read_array_of_decimal(field));
4351 },
4352 [](ptree& parent,
4353 const generic_record::generic_record& record,
4354 const std::string& field_name) {
4355 const auto& values = record.get_array_of_decimal(field_name);
4356
4357 if (!values) {
4358 parent.put(field_name, NULL_STRING);
4359 } else {
4360 ptree array;
4361
4362 for (const auto& value : *values) {
4363 if (!value) {
4364 array.push_back(
4365 std::make_pair("", ptree(NULL_STRING)));
4366 } else {
4367 array.push_back(std::make_pair(
4368 "",
4369 ptree(value->unscaled.str() + "E" +
4370 std::to_string(value->scale))));
4371 }
4372 }
4373
4374 parent.put_child(field_name, array);
4375 }
4376 } },
4377 field_kind_based_operations{
4378 // [21]TIME
4379 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4380 [](default_compact_writer& writer,
4381 const generic_record::generic_record& record,
4382 const std::string& field) {
4383 writer.write_time(field, record.get_time(field));
4384 },
4385 [](compact::compact_reader& reader,
4386 generic_record::generic_record_builder& builder,
4387 const std::string& field) {
4388 builder.set_time(field, reader.read_time(field));
4389 },
4390 [](boost::property_tree::ptree& parent,
4391 const generic_record::generic_record& record,
4392 const std::string& field_name) {
4393 const auto& value = record.get_time(field_name);
4394
4395 if (!value) {
4396 parent.put(field_name, NULL_STRING);
4397 } else {
4398 parent.put(field_name, time_to_string(*value));
4399 }
4400 } },
4401 field_kind_based_operations{
4402 // [22]ARRAY_OF_TIME
4403 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4404 [](default_compact_writer& writer,
4405 const generic_record::generic_record& record,
4406 const std::string& field) {
4407 writer.write_array_of_time(field,
4408 record.get_array_of_time(field));
4409 },
4410 [](compact::compact_reader& reader,
4411 generic_record::generic_record_builder& builder,
4412 const std::string& field) {
4413 builder.set_array_of_time(field,
4414 reader.read_array_of_time(field));
4415 },
4416 [](ptree& parent,
4417 const generic_record::generic_record& record,
4418 const std::string& field_name) {
4419 const auto& values = record.get_array_of_time(field_name);
4420
4421 if (!values) {
4422 parent.put(field_name, NULL_STRING);
4423 } else {
4424 ptree array;
4425
4426 for (const auto& value : *values) {
4427 if (!value) {
4428 array.push_back(
4429 std::make_pair("", ptree(NULL_STRING)));
4430 } else {
4431 array.push_back(
4432 std::make_pair("", ptree(time_to_string(*value))));
4433 }
4434 }
4435
4436 parent.put_child(field_name, array);
4437 }
4438 } },
4439 field_kind_based_operations{
4440 // [23]DATE
4441 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4442 [](default_compact_writer& writer,
4443 const generic_record::generic_record& record,
4444 const std::string& field) {
4445 writer.write_date(field, record.get_date(field));
4446 },
4447 [](compact::compact_reader& reader,
4448 generic_record::generic_record_builder& builder,
4449 const std::string& field) {
4450 builder.set_date(field, reader.read_date(field));
4451 },
4452 [](boost::property_tree::ptree& parent,
4453 const generic_record::generic_record& record,
4454 const std::string& field_name) {
4455 const auto& value = record.get_date(field_name);
4456
4457 if (!value) {
4458 parent.put(field_name, NULL_STRING);
4459 } else {
4460 parent.put(field_name, date_to_string(*value));
4461 }
4462 } },
4463 field_kind_based_operations{
4464 // [24]ARRAY_OF_DATE
4465 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4466 [](default_compact_writer& writer,
4467 const generic_record::generic_record& record,
4468 const std::string& field) {
4469 writer.write_array_of_date(field,
4470 record.get_array_of_date(field));
4471 },
4472 [](compact::compact_reader& reader,
4473 generic_record::generic_record_builder& builder,
4474 const std::string& field) {
4475 builder.set_array_of_date(field,
4476 reader.read_array_of_date(field));
4477 },
4478 [](ptree& parent,
4479 const generic_record::generic_record& record,
4480 const std::string& field_name) {
4481 const auto& values = record.get_array_of_date(field_name);
4482
4483 if (!values) {
4484 parent.put(field_name, NULL_STRING);
4485 } else {
4486 ptree array;
4487
4488 for (const auto& value : *values) {
4489 if (!value) {
4490 array.push_back(
4491 std::make_pair("", ptree(NULL_STRING)));
4492 } else {
4493 array.push_back(
4494 std::make_pair("", ptree(date_to_string(*value))));
4495 }
4496 }
4497
4498 parent.put_child(field_name, array);
4499 }
4500 } },
4501 field_kind_based_operations{
4502 // [25]TIMESTAMP
4503 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4504 [](default_compact_writer& writer,
4505 const generic_record::generic_record& record,
4506 const std::string& field) {
4507 writer.write_timestamp(field, record.get_timestamp(field));
4508 },
4509 [](compact::compact_reader& reader,
4510 generic_record::generic_record_builder& builder,
4511 const std::string& field) {
4512 builder.set_timestamp(field, reader.read_timestamp(field));
4513 },
4514 [](boost::property_tree::ptree& parent,
4515 const generic_record::generic_record& record,
4516 const std::string& field_name) {
4517 const auto& value = record.get_timestamp(field_name);
4518
4519 if (!value) {
4520 parent.put(field_name, NULL_STRING);
4521 } else {
4522 parent.put(field_name, timestamp_to_string(*value));
4523 }
4524 } },
4525 field_kind_based_operations{
4526 // [26]ARRAY_OF_TIMESTAMP
4527 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4528 [](default_compact_writer& writer,
4529 const generic_record::generic_record& record,
4530 const std::string& field) {
4531 writer.write_array_of_timestamp(
4532 field, record.get_array_of_timestamp(field));
4533 },
4534 [](compact::compact_reader& reader,
4535 generic_record::generic_record_builder& builder,
4536 const std::string& field) {
4537 builder.set_array_of_timestamp(
4538 field, reader.read_array_of_timestamp(field));
4539 },
4540 [](ptree& parent,
4541 const generic_record::generic_record& record,
4542 const std::string& field_name) {
4543 const auto& values = record.get_array_of_timestamp(field_name);
4544
4545 if (!values) {
4546 parent.put(field_name, NULL_STRING);
4547 } else {
4548 ptree array;
4549
4550 for (const auto& value : *values) {
4551 if (!value) {
4552 array.push_back(
4553 std::make_pair("", ptree(NULL_STRING)));
4554 } else {
4555 array.push_back(std::make_pair(
4556 "", ptree(timestamp_to_string(*value))));
4557 }
4558 }
4559
4560 parent.put_child(field_name, array);
4561 }
4562 } },
4563 field_kind_based_operations{
4564 // [27]TIMESTAMP_WITH_TIMEZONE
4565 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4566 [](default_compact_writer& writer,
4567 const generic_record::generic_record& record,
4568 const std::string& field) {
4569 writer.write_timestamp_with_timezone(
4570 field, record.get_timestamp_with_timezone(field));
4571 },
4572 [](compact::compact_reader& reader,
4573 generic_record::generic_record_builder& builder,
4574 const std::string& field) {
4575 builder.set_timestamp_with_timezone(
4576 field, reader.read_timestamp_with_timezone(field));
4577 },
4578 [](boost::property_tree::ptree& parent,
4579 const generic_record::generic_record& record,
4580 const std::string& field_name) {
4581 const auto& value =
4582 record.get_timestamp_with_timezone(field_name);
4583
4584 if (!value) {
4585 parent.put(field_name, NULL_STRING);
4586 } else {
4587 parent.put(field_name,
4588 timestamp_with_timezone_to_string(*value));
4589 }
4590 } },
4591 field_kind_based_operations{
4592 // [28]ARRAY_OF_TIMESTAMP_WITH_TIMEZONE
4593 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4594 [](default_compact_writer& writer,
4595 const generic_record::generic_record& record,
4596 const std::string& field) {
4597 writer.write_array_of_timestamp_with_timezone(
4598 field, record.get_array_of_timestamp_with_timezone(field));
4599 },
4600 [](compact::compact_reader& reader,
4601 generic_record::generic_record_builder& builder,
4602 const std::string& field) {
4603 builder.set_array_of_timestamp_with_timezone(
4604 field, reader.read_array_of_timestamp_with_timezone(field));
4605 },
4606 [](ptree& parent,
4607 const generic_record::generic_record& record,
4608 const std::string& field_name) {
4609 const auto& values =
4610 record.get_array_of_timestamp_with_timezone(field_name);
4611
4612 if (!values) {
4613 parent.put(field_name, NULL_STRING);
4614 } else {
4615 ptree array;
4616
4617 for (const auto& value : *values) {
4618 if (!value) {
4619 array.push_back(
4620 std::make_pair("", ptree(NULL_STRING)));
4621 } else {
4622 array.push_back(std::make_pair(
4623 "",
4624 ptree(timestamp_with_timezone_to_string(*value))));
4625 }
4626 }
4627
4628 parent.put_child(field_name, array);
4629 }
4630 } },
4631 field_kind_based_operations{
4632 // [29]COMPACT
4633 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4634 [](default_compact_writer& writer,
4635 const generic_record::generic_record& record,
4636 const std::string& field) {
4637 writer.write_compact(field, record.get_generic_record(field));
4638 },
4639 [](compact::compact_reader& reader,
4640 generic_record::generic_record_builder& builder,
4641 const std::string& field) {
4642 builder.set_generic_record(
4643 field,
4644 reader.read_compact<generic_record::generic_record>(field));
4645 },
4646 [](boost::property_tree::ptree& parent,
4647 const generic_record::generic_record& record,
4648 const std::string& field_name) {
4649 const auto& value = record.get_generic_record(field_name);
4650
4651 if (!value) {
4652 parent.put(field_name, NULL_STRING);
4653 } else {
4654 parent.put_child(field_name, write_generic_record(*value));
4655 }
4656 } },
4657 field_kind_based_operations{
4658 // [30]ARRAY_OF_COMPACT
4659 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4660 [](default_compact_writer& writer,
4661 const generic_record::generic_record& record,
4662 const std::string& field) {
4663 writer.write_array_of_compact(
4664 field, record.get_array_of_generic_record(field));
4665 },
4666 [](compact::compact_reader& reader,
4667 generic_record::generic_record_builder& builder,
4668 const std::string& field) {
4669 builder.set_array_of_generic_record(
4670 field,
4671 reader.read_array_of_compact<generic_record::generic_record>(
4672 field));
4673 },
4674 [](ptree& parent,
4675 const generic_record::generic_record& record,
4676 const std::string& field_name) {
4677 const auto& values =
4678 record.get_array_of_generic_record(field_name);
4679
4680 if (!values) {
4681 parent.put(field_name, NULL_STRING);
4682 } else {
4683 ptree array;
4684
4685 for (const auto& value : *values) {
4686 if (!value) {
4687 array.push_back(
4688 std::make_pair("", ptree(NULL_STRING)));
4689 } else {
4690 array.push_back(
4691 std::make_pair("", write_generic_record(*value)));
4692 }
4693 }
4694
4695 parent.put_child(field_name, array);
4696 }
4697 } },
4698 field_kind_based_operations{}, // [31]
4699 field_kind_based_operations{}, // [32]
4700 field_kind_based_operations{
4701 // [33]NULLABLE_BOOLEAN
4702 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4703 [](default_compact_writer& writer,
4704 const generic_record::generic_record& record,
4705 const std::string& field) {
4706 writer.write_nullable_boolean(field,
4707 record.get_nullable_boolean(field));
4708 },
4709 [](compact::compact_reader& reader,
4710 generic_record::generic_record_builder& builder,
4711 const std::string& field) {
4712 builder.set_nullable_boolean(field,
4713 reader.read_nullable_boolean(field));
4714 },
4715 [](boost::property_tree::ptree& parent,
4716 const generic_record::generic_record& record,
4717 const std::string& field_name) {
4718 const auto& value = record.get_nullable_boolean(field_name);
4719
4720 if (!value) {
4721 parent.put(field_name, NULL_STRING);
4722 } else {
4723 parent.put(field_name, *value);
4724 }
4725 } },
4726 field_kind_based_operations{
4727 // [34]ARRAY_OF_NULLABLE_BOOLEAN
4728 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4729 [](default_compact_writer& writer,
4730 const generic_record::generic_record& record,
4731 const std::string& field) {
4732 writer.write_array_of_nullable_boolean(
4733 field, record.get_array_of_nullable_boolean(field));
4734 },
4735 [](compact::compact_reader& reader,
4736 generic_record::generic_record_builder& builder,
4737 const std::string& field) {
4738 builder.set_array_of_nullable_boolean(
4739 field, reader.read_array_of_nullable_boolean(field));
4740 },
4741 [](ptree& parent,
4742 const generic_record::generic_record& record,
4743 const std::string& field_name) {
4744 const auto& values =
4745 record.get_array_of_nullable_boolean(field_name);
4746
4747 if (!values) {
4748 parent.put(field_name, NULL_STRING);
4749 } else {
4750 ptree array;
4751
4752 for (const auto& value : *values) {
4753 if (!value) {
4754 array.push_back(
4755 std::make_pair("", ptree(NULL_STRING)));
4756 } else {
4757 array.push_back(
4758 std::make_pair("", ptree(BOOL_STRING[*value])));
4759 }
4760 }
4761
4762 parent.put_child(field_name, array);
4763 }
4764 } },
4765 field_kind_based_operations{
4766 // [35]NULLABLE_INT8
4767 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4768 [](default_compact_writer& writer,
4769 const generic_record::generic_record& record,
4770 const std::string& field) {
4771 writer.write_nullable_int8(field,
4772 record.get_nullable_int8(field));
4773 },
4774 [](compact::compact_reader& reader,
4775 generic_record::generic_record_builder& builder,
4776 const std::string& field) {
4777 builder.set_nullable_int8(field,
4778 reader.read_nullable_int8(field));
4779 },
4780 [](boost::property_tree::ptree& parent,
4781 const generic_record::generic_record& record,
4782 const std::string& field_name) {
4783 const auto& value = record.get_nullable_int8(field_name);
4784
4785 if (!value) {
4786 parent.put(field_name, NULL_STRING);
4787 } else {
4788 parent.put(field_name, std::to_string(*value));
4789 }
4790 } },
4791 field_kind_based_operations{
4792 // [36]ARRAY_OF_NULLABLE_INT8
4793 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4794 [](default_compact_writer& writer,
4795 const generic_record::generic_record& record,
4796 const std::string& field) {
4797 writer.write_array_of_nullable_int8(
4798 field, record.get_array_of_nullable_int8(field));
4799 },
4800 [](compact::compact_reader& reader,
4801 generic_record::generic_record_builder& builder,
4802 const std::string& field) {
4803 builder.set_array_of_nullable_int8(
4804 field, reader.read_array_of_nullable_int8(field));
4805 },
4806 [](ptree& parent,
4807 const generic_record::generic_record& record,
4808 const std::string& field_name) {
4809 const auto& values =
4810 record.get_array_of_nullable_int8(field_name);
4811
4812 if (!values) {
4813 parent.put(field_name, NULL_STRING);
4814 } else {
4815 ptree array;
4816
4817 for (const auto& value : *values) {
4818 if (!value) {
4819 array.push_back(
4820 std::make_pair("", ptree(NULL_STRING)));
4821 } else {
4822 array.push_back(
4823 std::make_pair("", ptree(std::to_string(*value))));
4824 }
4825 }
4826
4827 parent.put_child(field_name, array);
4828 }
4829 } },
4830 field_kind_based_operations{
4831 // [37]NULLABLE_INT16
4832 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4833 [](default_compact_writer& writer,
4834 const generic_record::generic_record& record,
4835 const std::string& field) {
4836 writer.write_nullable_int16(field,
4837 record.get_nullable_int16(field));
4838 },
4839 [](compact::compact_reader& reader,
4840 generic_record::generic_record_builder& builder,
4841 const std::string& field) {
4842 builder.set_nullable_int16(field,
4843 reader.read_nullable_int16(field));
4844 },
4845 [](boost::property_tree::ptree& parent,
4846 const generic_record::generic_record& record,
4847 const std::string& field_name) {
4848 const auto& value = record.get_nullable_int16(field_name);
4849
4850 if (!value) {
4851 parent.put(field_name, NULL_STRING);
4852 } else {
4853 parent.put(field_name, std::to_string(*value));
4854 }
4855 } },
4856 field_kind_based_operations{
4857 // [38]ARRAY_OF_NULLABLE_INT16
4858 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4859 [](default_compact_writer& writer,
4860 const generic_record::generic_record& record,
4861 const std::string& field) {
4862 writer.write_array_of_nullable_int16(
4863 field, record.get_array_of_nullable_int16(field));
4864 },
4865 [](compact::compact_reader& reader,
4866 generic_record::generic_record_builder& builder,
4867 const std::string& field) {
4868 builder.set_array_of_nullable_int16(
4869 field, reader.read_array_of_nullable_int16(field));
4870 },
4871 [](ptree& parent,
4872 const generic_record::generic_record& record,
4873 const std::string& field_name) {
4874 const auto& values =
4875 record.get_array_of_nullable_int16(field_name);
4876
4877 if (!values) {
4878 parent.put(field_name, NULL_STRING);
4879 } else {
4880 ptree array;
4881
4882 for (const auto& value : *values) {
4883 if (!value) {
4884 array.push_back(
4885 std::make_pair("", ptree(NULL_STRING)));
4886 } else {
4887 array.push_back(
4888 std::make_pair("", ptree(std::to_string(*value))));
4889 }
4890 }
4891
4892 parent.put_child(field_name, array);
4893 }
4894 } },
4895 field_kind_based_operations{
4896 // [39]NULLABLE_INT32
4897 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4898 [](default_compact_writer& writer,
4899 const generic_record::generic_record& record,
4900 const std::string& field) {
4901 writer.write_nullable_int32(field,
4902 record.get_nullable_int32(field));
4903 },
4904 [](compact::compact_reader& reader,
4905 generic_record::generic_record_builder& builder,
4906 const std::string& field) {
4907 builder.set_nullable_int32(field,
4908 reader.read_nullable_int32(field));
4909 },
4910 [](boost::property_tree::ptree& parent,
4911 const generic_record::generic_record& record,
4912 const std::string& field_name) {
4913 const auto& value = record.get_nullable_int32(field_name);
4914
4915 if (!value) {
4916 parent.put(field_name, NULL_STRING);
4917 } else {
4918 parent.put(field_name, std::to_string(*value));
4919 }
4920 } },
4921 field_kind_based_operations{
4922 // [40]ARRAY_OF_NULLABLE_INT32
4923 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4924 [](default_compact_writer& writer,
4925 const generic_record::generic_record& record,
4926 const std::string& field) {
4927 writer.write_array_of_nullable_int32(
4928 field, record.get_array_of_nullable_int32(field));
4929 },
4930 [](compact::compact_reader& reader,
4931 generic_record::generic_record_builder& builder,
4932 const std::string& field) {
4933 builder.set_array_of_nullable_int32(
4934 field, reader.read_array_of_nullable_int32(field));
4935 },
4936 [](ptree& parent,
4937 const generic_record::generic_record& record,
4938 const std::string& field_name) {
4939 const auto& values =
4940 record.get_array_of_nullable_int32(field_name);
4941
4942 if (!values) {
4943 parent.put(field_name, NULL_STRING);
4944 } else {
4945 ptree array;
4946
4947 for (const auto& value : *values) {
4948 if (!value) {
4949 array.push_back(
4950 std::make_pair("", ptree(NULL_STRING)));
4951 } else {
4952 array.push_back(
4953 std::make_pair("", ptree(std::to_string(*value))));
4954 }
4955 }
4956
4957 parent.put_child(field_name, array);
4958 }
4959 } },
4960 field_kind_based_operations{
4961 // [41]NULLABLE_INT64
4962 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4963 [](default_compact_writer& writer,
4964 const generic_record::generic_record& record,
4965 const std::string& field) {
4966 writer.write_nullable_int64(field,
4967 record.get_nullable_int64(field));
4968 },
4969 [](compact::compact_reader& reader,
4970 generic_record::generic_record_builder& builder,
4971 const std::string& field) {
4972 builder.set_nullable_int64(field,
4973 reader.read_nullable_int64(field));
4974 },
4975 [](boost::property_tree::ptree& parent,
4976 const generic_record::generic_record& record,
4977 const std::string& field_name) {
4978 const auto& value = record.get_nullable_int64(field_name);
4979
4980 if (!value) {
4981 parent.put(field_name, NULL_STRING);
4982 } else {
4983 parent.put(field_name, std::to_string(*value));
4984 }
4985 } },
4986 field_kind_based_operations{
4987 // [42]ARRAY_OF_NULLABLE_INT64
4988 [] { return field_kind_based_operations::VARIABLE_SIZE; },
4989 [](default_compact_writer& writer,
4990 const generic_record::generic_record& record,
4991 const std::string& field) {
4992 writer.write_array_of_nullable_int64(
4993 field, record.get_array_of_nullable_int64(field));
4994 },
4995 [](compact::compact_reader& reader,
4996 generic_record::generic_record_builder& builder,
4997 const std::string& field) {
4998 builder.set_array_of_nullable_int64(
4999 field, reader.read_array_of_nullable_int64(field));
5000 },
5001 [](ptree& parent,
5002 const generic_record::generic_record& record,
5003 const std::string& field_name) {
5004 const auto& values =
5005 record.get_array_of_nullable_int64(field_name);
5006
5007 if (!values) {
5008 parent.put(field_name, NULL_STRING);
5009 } else {
5010 ptree array;
5011
5012 for (const auto& value : *values) {
5013 if (!value) {
5014 array.push_back(
5015 std::make_pair("", ptree(NULL_STRING)));
5016 } else {
5017 array.push_back(
5018 std::make_pair("", ptree(std::to_string(*value))));
5019 }
5020 }
5021
5022 parent.put_child(field_name, array);
5023 }
5024 } },
5025 field_kind_based_operations{
5026 // [43]NULLABLE_FLOAT32
5027 [] { return field_kind_based_operations::VARIABLE_SIZE; },
5028 [](default_compact_writer& writer,
5029 const generic_record::generic_record& record,
5030 const std::string& field) {
5031 writer.write_nullable_float32(field,
5032 record.get_nullable_float32(field));
5033 },
5034 [](compact::compact_reader& reader,
5035 generic_record::generic_record_builder& builder,
5036 const std::string& field) {
5037 builder.set_nullable_float32(field,
5038 reader.read_nullable_float32(field));
5039 },
5040 [](boost::property_tree::ptree& parent,
5041 const generic_record::generic_record& record,
5042 const std::string& field_name) {
5043 const auto& value = record.get_nullable_float32(field_name);
5044
5045 if (!value) {
5046 parent.put(field_name, NULL_STRING);
5047 } else {
5048 parent.put(field_name, std::to_string(*value));
5049 }
5050 } },
5051 field_kind_based_operations{
5052 // [44]ARRAY_OF_NULLABLE_FLOAT32
5053 [] { return field_kind_based_operations::VARIABLE_SIZE; },
5054 [](default_compact_writer& writer,
5055 const generic_record::generic_record& record,
5056 const std::string& field) {
5057 writer.write_array_of_nullable_float32(
5058 field, record.get_array_of_nullable_float32(field));
5059 },
5060 [](compact::compact_reader& reader,
5061 generic_record::generic_record_builder& builder,
5062 const std::string& field) {
5063 builder.set_array_of_nullable_float32(
5064 field, reader.read_array_of_nullable_float32(field));
5065 },
5066 [](ptree& parent,
5067 const generic_record::generic_record& record,
5068 const std::string& field_name) {
5069 const auto& values =
5070 record.get_array_of_nullable_float32(field_name);
5071
5072 if (!values) {
5073 parent.put(field_name, NULL_STRING);
5074 } else {
5075 ptree array;
5076
5077 for (const auto& value : *values) {
5078 if (!value) {
5079 array.push_back(
5080 std::make_pair("", ptree(NULL_STRING)));
5081 } else {
5082 array.push_back(
5083 std::make_pair("", ptree(std::to_string(*value))));
5084 }
5085 }
5086
5087 parent.put_child(field_name, array);
5088 }
5089 } },
5090 field_kind_based_operations{
5091 // [45]NULLABLE_FLOAT64
5092 [] { return field_kind_based_operations::VARIABLE_SIZE; },
5093 [](default_compact_writer& writer,
5094 const generic_record::generic_record& record,
5095 const std::string& field) {
5096 writer.write_nullable_float64(field,
5097 record.get_nullable_float64(field));
5098 },
5099 [](compact::compact_reader& reader,
5100 generic_record::generic_record_builder& builder,
5101 const std::string& field) {
5102 builder.set_nullable_float64(field,
5103 reader.read_nullable_float64(field));
5104 },
5105 [](boost::property_tree::ptree& parent,
5106 const generic_record::generic_record& record,
5107 const std::string& field_name) {
5108 const auto& value = record.get_nullable_float64(field_name);
5109
5110 if (!value) {
5111 parent.put(field_name, NULL_STRING);
5112 } else {
5113 parent.put(field_name, std::to_string(*value));
5114 }
5115 } },
5116 field_kind_based_operations{
5117 // [46]ARRAY_OF_NULLABLE_FLOAT64
5118 [] { return field_kind_based_operations::VARIABLE_SIZE; },
5119 [](default_compact_writer& writer,
5120 const generic_record::generic_record& record,
5121 const std::string& field) {
5122 writer.write_array_of_nullable_float64(
5123 field, record.get_array_of_nullable_float64(field));
5124 },
5125 [](compact::compact_reader& reader,
5126 generic_record::generic_record_builder& builder,
5127 const std::string& field) {
5128 builder.set_array_of_nullable_float64(
5129 field, reader.read_array_of_nullable_float64(field));
5130 },
5131 [](ptree& parent,
5132 const generic_record::generic_record& record,
5133 const std::string& field_name) {
5134 const auto& values =
5135 record.get_array_of_nullable_float64(field_name);
5136
5137 if (!values) {
5138 parent.put(field_name, NULL_STRING);
5139 } else {
5140 ptree array;
5141
5142 for (const auto& value : *values) {
5143 if (!value) {
5144 array.push_back(
5145 std::make_pair("", ptree(NULL_STRING)));
5146 } else {
5147 array.push_back(
5148 std::make_pair("", ptree(std::to_string(*value))));
5149 }
5150 }
5151
5152 parent.put_child(field_name, array);
5153 }
5154 } }
5155 };
5156
5157 return ALL[std::size_t(kind)];
5158}
5159
5160} // namespace pimpl
5161} // namespace serialization
5162} // namespace client
5163} // namespace hazelcast
generic_record_builder & set_array_of_int8(std::string field_name, boost::optional< std::vector< int8_t > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:328
generic_record_builder & set_time(std::string field_name, boost::optional< local_time > value)
Sets a time field consisting of hour, minute, seconds, and nanos parts.
Definition compact.cpp:267
generic_record_builder & set_timestamp(std::string field_name, boost::optional< local_date_time > value)
Sets a timestamp field consisting of year, month of the year, and day of the month,...
Definition compact.cpp:281
generic_record_builder & set_generic_record(std::string field_name, boost::optional< generic_record > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:252
generic_record_builder & set_array_of_boolean(std::string field_name, boost::optional< std::vector< bool > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:303
generic_record_builder & set_array_of_string(std::string field_name, boost::optional< std::vector< boost::optional< std::string > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:670
generic_record_builder & set_array_of_nullable_int64(std::string field_name, boost::optional< std::vector< boost::optional< int64_t > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:593
generic_record_builder & set_array_of_nullable_float64(std::string field_name, boost::optional< std::vector< boost::optional< double > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:644
generic_record_builder & set_array_of_nullable_boolean(std::string field_name, boost::optional< std::vector< boost::optional< bool > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:492
generic_record_builder & set_int64(std::string field_name, int64_t value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:185
generic_record_builder & set_int8(std::string field_name, int8_t value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:167
generic_record_builder & set_array_of_decimal(std::string field_name, boost::optional< std::vector< boost::optional< big_decimal > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:679
generic_record_builder & set_decimal(std::string field_name, boost::optional< big_decimal > value)
Sets a decimal which is arbitrary precision and scale floating-point number.
Definition compact.cpp:260
generic_record_builder & set_array_of_nullable_int8(std::string field_name, boost::optional< std::vector< boost::optional< int8_t > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:518
generic_record_builder & set_nullable_int8(std::string field_name, boost::optional< int8_t > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:210
generic_record_builder & set_int16(std::string field_name, int16_t value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:173
generic_record_builder & set_array_of_nullable_int32(std::string field_name, boost::optional< std::vector< boost::optional< int32_t > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:568
generic_record_builder & set_nullable_float32(std::string field_name, boost::optional< float > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:238
generic_record_builder & set_array_of_nullable_int16(std::string field_name, boost::optional< std::vector< boost::optional< int16_t > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:543
generic_record_builder & set_array_of_nullable_float32(std::string field_name, boost::optional< std::vector< boost::optional< float > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:618
generic_record_builder & set_array_of_float64(std::string field_name, boost::optional< std::vector< double > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:452
generic_record_builder & set_array_of_int64(std::string field_name, boost::optional< std::vector< int64_t > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:402
generic_record_builder & set_array_of_timestamp_with_timezone(std::string field_name, boost::optional< std::vector< boost::optional< offset_date_time > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:713
generic_record_builder & set_nullable_int64(std::string field_name, boost::optional< int64_t > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:231
generic_record_builder & set_nullable_boolean(std::string field_name, boost::optional< bool > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:203
generic_record_builder & set_float32(std::string field_name, float value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:191
generic_record_builder & set_array_of_date(std::string field_name, boost::optional< std::vector< boost::optional< local_date > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:696
generic_record_builder & set_timestamp_with_timezone(std::string field_name, boost::optional< offset_date_time > value)
Sets a timestamp with timezone field consisting of year, month of the year and day of the month,...
Definition compact.cpp:288
generic_record_builder & set_nullable_float64(std::string field_name, boost::optional< double > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:245
generic_record_builder & set_array_of_int16(std::string field_name, boost::optional< std::vector< int16_t > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:352
generic_record_builder & set_boolean(std::string field_name, bool value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:161
generic_record_builder & set_array_of_float32(std::string field_name, boost::optional< std::vector< float > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:427
generic_record_builder & set_date(std::string field_name, boost::optional< local_date > value)
Sets a date field consisting of year, month of the year, and day of the month.
Definition compact.cpp:274
generic_record_builder & set_array_of_int32(std::string field_name, boost::optional< std::vector< int32_t > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:377
generic_record_builder & set_array_of_time(std::string field_name, boost::optional< std::vector< boost::optional< local_time > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:688
generic_record_builder & set_float64(std::string field_name, double value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:197
generic_record_builder & set_int32(std::string field_name, int32_t value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:179
generic_record_builder(std::string type_name)
Creates a Builder that will build a generic_record in Compact format with the given type name and sch...
Definition compact.cpp:84
generic_record_builder & set_string(std::string field_name, boost::optional< std::string > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:296
generic_record_builder & set_nullable_int32(std::string field_name, boost::optional< int32_t > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:224
generic_record_builder & set_nullable_int16(std::string field_name, boost::optional< int16_t > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:217
generic_record_builder & set_array_of_timestamp(std::string field_name, boost::optional< std::vector< boost::optional< local_date_time > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:704
generic_record_builder & set_array_of_generic_record(std::string field_name, boost::optional< std::vector< boost::optional< generic_record > > > value)
It is legal to set the field again only when Builder is created with generic_record::new_builder_with...
Definition compact.cpp:723
A generic object interface that is returned to the user when the domain class can not be created from...
int64_t get_int64(const std::string &field_name) const
Definition compact.cpp:849
boost::optional< int8_t > get_nullable_int8(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:903
boost::optional< float > get_nullable_float32(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:957
boost::optional< double > get_nullable_float64(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:971
const boost::optional< std::vector< boost::optional< float > > > & get_array_of_nullable_float32(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1292
const boost::optional< generic_record > & get_generic_record(const std::string &field_name) const
Definition compact.cpp:997
const boost::optional< std::vector< boost::optional< int64_t > > > & get_array_of_nullable_int64(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1274
double get_float64(const std::string &field_name) const
Definition compact.cpp:877
int16_t get_int16(const std::string &field_name) const
Definition compact.cpp:821
const boost::optional< std::vector< int64_t > > & get_array_of_int64(const std::string &field_name) const
Definition compact.cpp:1147
generic_record_builder new_builder() const
Creates a generic_record_builder allows to create a new object.
Definition compact.cpp:746
const boost::optional< std::vector< boost::optional< generic_record > > > & get_array_of_generic_record(const std::string &field_name) const
Definition compact.cpp:1416
const boost::optional< std::vector< boost::optional< local_date > > > & get_array_of_date(const std::string &field_name) const
Definition compact.cpp:1372
const boost::optional< offset_date_time > & get_timestamp_with_timezone(const std::string &field_name) const
Definition compact.cpp:1061
bool get_boolean(const std::string &field_name) const
Definition compact.cpp:793
boost::optional< int64_t > get_nullable_int64(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:943
const boost::optional< local_date_time > & get_timestamp(const std::string &field_name) const
Definition compact.cpp:1047
const boost::optional< std::vector< double > > & get_array_of_float64(const std::string &field_name) const
Definition compact.cpp:1183
int8_t get_int8(const std::string &field_name) const
Definition compact.cpp:807
generic_record_builder new_builder_with_clone() const
Returned generic_record_builder can be used to have exact copy and also just to update a couple of fi...
Definition compact.cpp:752
const boost::optional< std::vector< boost::optional< local_date_time > > > & get_array_of_timestamp(const std::string &field_name) const
Definition compact.cpp:1386
const boost::optional< std::string > & get_string(const std::string &field_name) const
Definition compact.cpp:985
const boost::optional< std::vector< boost::optional< int8_t > > > & get_array_of_nullable_int8(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1220
const boost::optional< std::vector< bool > > & get_array_of_boolean(const std::string &field_name) const
Definition compact.cpp:1075
const boost::optional< std::vector< int16_t > > & get_array_of_int16(const std::string &field_name) const
Definition compact.cpp:1111
const boost::optional< std::vector< boost::optional< double > > > & get_array_of_nullable_float64(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1311
int32_t get_int32(const std::string &field_name) const
Definition compact.cpp:835
float get_float32(const std::string &field_name) const
Definition compact.cpp:863
const boost::optional< local_date > & get_date(const std::string &field_name) const
Definition compact.cpp:1035
std::unordered_set< std::string > get_field_names() const
Definition compact.cpp:758
const boost::optional< std::vector< boost::optional< int32_t > > > & get_array_of_nullable_int32(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1256
boost::optional< int16_t > get_nullable_int16(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:915
const boost::optional< big_decimal > & get_decimal(const std::string &field_name) const
Definition compact.cpp:1011
boost::optional< bool > get_nullable_boolean(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:891
field_kind get_field_kind(const std::string &field_name) const
Returns the kind of the field for the given field name.
Definition compact.cpp:775
const boost::optional< std::vector< boost::optional< std::string > > > & get_array_of_string(const std::string &field_name) const
Definition compact.cpp:1330
const boost::optional< std::vector< boost::optional< big_decimal > > > & get_array_of_decimal(const std::string &field_name) const
Definition compact.cpp:1344
const boost::optional< std::vector< boost::optional< int16_t > > > & get_array_of_nullable_int16(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1238
const boost::optional< std::vector< boost::optional< offset_date_time > > > & get_array_of_timestamp_with_timezone(const std::string &field_name) const
Definition compact.cpp:1400
const boost::optional< std::vector< float > > & get_array_of_float32(const std::string &field_name) const
Definition compact.cpp:1165
const boost::optional< std::vector< int32_t > > & get_array_of_int32(const std::string &field_name) const
Definition compact.cpp:1129
const boost::optional< std::vector< boost::optional< local_time > > > & get_array_of_time(const std::string &field_name) const
Definition compact.cpp:1358
const boost::optional< local_time > & get_time(const std::string &field_name) const
Definition compact.cpp:1023
const boost::optional< std::vector< boost::optional< bool > > > & get_array_of_nullable_boolean(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:1201
boost::optional< int32_t > get_nullable_int32(const std::string &field_name) const
Supported only for Compact.
Definition compact.cpp:929
const boost::optional< std::vector< int8_t > > & get_array_of_int8(const std::string &field_name) const
Definition compact.cpp:1093
STL namespace.