41 {
42
43
44void
45OksData::SetFast(boost::gregorian::date d)
46{
47 data.DATE = d.day_number();
48}
49
50void
51OksData::SetFast(boost::posix_time::ptime t)
52{
53 data.TIME = *reinterpret_cast<uint64_t*>(&t);
54}
55
56boost::gregorian::date
57OksData::date() const noexcept
58{
59 return boost::gregorian::date(boost::gregorian::gregorian_calendar::from_day_number(
data.DATE));
60}
61
62boost::posix_time::ptime
63OksData::time() const noexcept
64{
65 return *
reinterpret_cast<boost::posix_time::ptime*
>(
const_cast<uint64_t*
>(&
data.TIME));
66}
67
68inline void
69free_list(OksData::List& dlist)
70{
71 for (OksData::List::const_iterator i = dlist.begin(); i != dlist.end(); ++i) {
72 delete *i;
73 }
74 dlist.clear();
75}
76
77static bool
78operator==(
const OksData::List& l1,
const OksData::List& l2)
79{
80 if (&l1 == &l2)
81 return true;
82
83 size_t l1Lenght = l1.size();
84 size_t l2Lenght = l2.size();
85
86 if (!l1Lenght && !l2Lenght)
87 return true;
88 if (l1Lenght != l2Lenght)
89 return false;
90
91 size_t pos = 0;
92
93 auto i1 = l1.begin();
94 auto i2 = l2.begin();
95
96 for (; i1 != l1.end(); ++i1, ++i2) {
97 OksData* d1 = *i1;
98 OksData* d2 = *i2;
99
100 if (!d1 && !d2)
101 return true;
102 if (!d1 || !d2)
103 return false;
104
105 if (((d1->type == d2->type) && (d1->type == OksData::object_type) &&
106 ((!d1->data.OBJECT && !d2->data.OBJECT) ||
107 ((d1->data.OBJECT && d2->data.OBJECT) &&
108 (d1->data.OBJECT->GetClass()->get_name() == d2->data.OBJECT->GetClass()->get_name()) &&
109 (d1->data.OBJECT->GetId() == d2->data.OBJECT->GetId())))) ||
110 ((*d1 == *d2))) {
111 pos++;
112 continue;
113 }
114
115 return false;
116 }
117
118 return true;
119}
120
121bool
122OksData::operator==(const OksData& d) const
123{
124 return ((
d.type ==
type) &&
125 (((
type == string_type) && (*
d.data.STRING == *
data.STRING)) ||
126 ((
type == u32_int_type) && (
d.data.U32_INT ==
data.U32_INT)) ||
127 ((
type == s32_int_type) && (
d.data.S32_INT ==
data.S32_INT)) ||
128 ((
type == u16_int_type) && (
d.data.U16_INT ==
data.U16_INT)) ||
129 ((
type == s16_int_type) && (
d.data.S16_INT ==
data.S16_INT)) ||
130 ((
type == s8_int_type) && (
d.data.S8_INT ==
data.S8_INT)) ||
131 ((
type == u8_int_type) && (
d.data.U8_INT ==
data.U8_INT)) ||
132 ((
type == s64_int_type) && (
d.data.S64_INT ==
data.S64_INT)) ||
133 ((
type == u64_int_type) && (
d.data.U64_INT ==
data.U64_INT)) ||
134 ((
type == float_type) && (
d.data.FLOAT ==
data.FLOAT)) ||
135 ((
type == double_type) && (
d.data.DOUBLE ==
data.DOUBLE)) ||
136 ((
type == bool_type) && (
d.data.BOOL ==
data.BOOL)) || ((
type == date_type) && (
d.data.DATE ==
data.DATE)) ||
137 ((
type == time_type) && (
d.data.TIME ==
data.TIME)) ||
138 ((
type == object_type) && OksObject::are_equal_fast(
d.data.OBJECT,
data.OBJECT)) ||
139 ((
type == list_type) && (*
d.data.LIST == *
data.LIST)) ||
140 ((
type == uid_type) && (
d.data.UID.class_id->get_name() ==
data.UID.class_id->get_name() &&
141 *
d.data.UID.object_id == *
data.UID.object_id)) ||
142 ((
type == uid2_type) &&
143 (*
d.data.UID2.class_id == *
data.UID2.class_id && *
d.data.UID2.object_id == *
data.UID2.object_id)) ||
144 ((
type == enum_type) && (*
d.data.ENUMERATION == *
data.ENUMERATION)) ||
145 ((
type == class_type) && (
d.data.CLASS->get_name() ==
data.CLASS->get_name()))));
146}
147
148bool
149OksData::operator!=(const OksData& d) const
150{
151 return ((d == *this) ? false : true);
152}
153
154static bool
155test_comparable(OksData::Type type1, OksData::Type type2)
156{
157 const char* fname = "OksData::operator[<|<=|>|>=](const OksData&) const";
158 const char* h3 = "Can't compare ";
159
160 if (type1 != type2 && !(OksData::is_object(type1) && OksData::is_object(type2))) {
161 Oks::error_msg(fname) << h3 << "OKS data of different types\n";
162 return false;
163 } else if (type1 == OksData::list_type) {
164 Oks::error_msg(fname) << h3 << "lists\n";
165 return false;
166 }
167
168 return true;
169}
170
171const std::string&
172OksData::__oid() const
173{
174 if (
type == object_type)
175 return data.OBJECT->uid.object_id;
176 else if (
type == uid_type)
177 return *
data.UID.object_id;
178 else
179 return *
data.UID2.object_id;
180}
181
182const std::string&
183OksData::__cn() const
184{
185 if (
type == object_type)
186 return data.OBJECT->uid.class_id->get_name();
187 else if (
type == uid_type)
188 return data.UID.class_id->get_name();
189 else
190 return *
data.UID2.class_id;
191}
192
193#define CMP_OBJ(OP, c1, c2, id1, id2) (c1 OP c2) || (!(c2 OP c1) && id1 OP id2)
194
195#define CMP_DATA(OP) \
196 switch (type) { \
197 case string_type: \
198 return (*data.STRING OP * d.data.STRING); \
199 case u32_int_type: \
200 return (data.U32_INT OP d.data.U32_INT); \
201 case s32_int_type: \
202 return (data.S32_INT OP d.data.S32_INT); \
203 case u16_int_type: \
204 return (data.U16_INT OP d.data.U16_INT); \
205 case s16_int_type: \
206 return (data.S16_INT OP d.data.S16_INT); \
207 case s8_int_type: \
208 return (data.S8_INT OP d.data.S8_INT); \
209 case u8_int_type: \
210 return (data.U8_INT OP d.data.U8_INT); \
211 case s64_int_type: \
212 return (data.S64_INT OP d.data.S64_INT); \
213 case u64_int_type: \
214 return (data.U64_INT OP d.data.U64_INT); \
215 case float_type: \
216 return (data.FLOAT OP d.data.FLOAT); \
217 case double_type: \
218 return (data.DOUBLE OP d.data.DOUBLE); \
219 case bool_type: \
220 return (data.BOOL OP d.data.BOOL); \
221 case date_type: \
222 return (data.DATE OP d.data.DATE); \
223 case time_type: \
224 return (data.TIME OP d.data.TIME); \
225 case enum_type: \
226 return (*data.ENUMERATION OP * d.data.ENUMERATION); \
227 case class_type: \
228 return (data.CLASS->get_name() OP d.data.CLASS->get_name()); \
229 case object_type: \
230 case uid_type: \
231 case uid2_type: \
232 return CMP_OBJ(OP, __cn(), d.__cn(), __oid(), d.__oid()); \
233 default: \
234 return false; \
235 }
236
237bool
238OksData::is_le(const OksData& d) const noexcept
239{
241}
242
243bool
244OksData::is_ge(const OksData& d) const noexcept
245{
247}
248
249bool
250OksData::is_l(const OksData& d) const noexcept
251{
253}
254
255bool
256OksData::is_g(const OksData& d) const noexcept
257{
259}
260
261bool
262OksData::operator<=(const OksData& d) const
263{
264 if (test_comparable(
type,
d.type) ==
false)
265 return false;
266 return is_le(d);
267}
268
269bool
270OksData::operator>=(const OksData& d) const
271{
272 if (test_comparable(
type,
d.type) ==
false)
273 return false;
274 return is_ge(d);
275}
276
277bool
278OksData::operator>(const OksData& d) const
279{
280 if (test_comparable(
type,
d.type) ==
false)
281 return false;
282 return is_g(d);
283}
284
285bool
286OksData::operator<(const OksData& d) const
287{
288 if (test_comparable(
type,
d.type) ==
false)
289 return false;
290 return is_l(d);
291}
292
293void
294OksData::copy(const OksData& d)
295{
297
298 if (
type == list_type) {
299 data.LIST =
new List();
300
301 for (List::iterator i =
d.data.LIST->begin(); i !=
d.data.LIST->end(); ++i) {
302 OksData* d2 = new OksData();
303 *d2 = *(*i);
304 data.LIST->push_back(d2);
305 }
306 }
else if (
type == string_type)
307 data.STRING =
new OksString(*
d.data.STRING);
308 else if (
type == object_type)
309 data.OBJECT =
d.data.OBJECT;
310 else if (
type == u32_int_type)
311 data.U32_INT =
d.data.U32_INT;
312 else if (
type == s32_int_type)
313 data.S32_INT =
d.data.S32_INT;
314 else if (
type == u16_int_type)
315 data.U16_INT =
d.data.U16_INT;
316 else if (
type == s16_int_type)
317 data.S16_INT =
d.data.S16_INT;
318 else if (
type == double_type)
319 data.DOUBLE =
d.data.DOUBLE;
320 else if (
type == float_type)
321 data.FLOAT =
d.data.FLOAT;
322 else if (
type == s8_int_type)
323 data.S8_INT =
d.data.S8_INT;
324 else if (
type == u8_int_type)
325 data.U8_INT =
d.data.U8_INT;
326 else if (
type == s64_int_type)
327 data.S64_INT =
d.data.S64_INT;
328 else if (
type == u64_int_type)
329 data.U64_INT =
d.data.U64_INT;
330 else if (
type == class_type)
331 data.CLASS =
d.data.CLASS;
332 else if (
type == uid2_type) {
333 data.UID2.class_id =
new OksString(*
d.data.UID2.class_id);
334 data.UID2.object_id =
new OksString(*
d.data.UID2.object_id);
335 }
else if (
type == uid_type) {
336 data.UID.class_id =
d.data.UID.class_id;
337 data.UID.object_id =
new OksString(*
d.data.UID.object_id);
338 }
else if (
type == bool_type)
339 data.BOOL =
d.data.BOOL;
340 else if (
type == date_type)
341 data.DATE =
d.data.DATE;
342 else if (
type == time_type)
343 data.TIME =
d.data.TIME;
344 else if (
type == enum_type)
345 data.ENUMERATION =
d.data.ENUMERATION;
346}
347
348std::ostream&
350{
352 case OksData::list_type: {
354 for (OksData::List::iterator i =
d.data.LIST->begin(); i !=
d.data.LIST->end(); ++i) {
356 if ((*i) !=
d.data.LIST->back())
358 }
360 break;
361 }
362
363 case OksData::string_type:
364 s <<
'\"' << *(
d.data.STRING) <<
'\"';
365 break;
366
367 case OksData::object_type:
369 s <<
'[' <<
d.data.OBJECT->GetId() <<
'@' <<
d.data.OBJECT->GetClass()->get_name() <<
']';
370 else
372
373 break;
374
375 case OksData::uid2_type:
376 s <<
'#' <<
'[' << *
d.data.UID2.object_id <<
'@' << *
d.data.UID2.class_id <<
']';
377 break;
378
379 case OksData::uid_type:
380 s <<
'#' <<
'[' << *
d.data.UID.object_id <<
'@' <<
d.data.UID.class_id->get_name() <<
']';
381 break;
382
383 case OksData::s32_int_type:
385 break;
386
387 case OksData::u32_int_type:
389 break;
390
391 case OksData::s16_int_type:
393 break;
394
395 case OksData::u16_int_type:
397 break;
398
399 case OksData::float_type: {
400 std::streamsize p =
s.precision();
401 s.precision(std::numeric_limits<float>::digits10);
404 break;
405 }
406
407 case OksData::double_type: {
408 std::streamsize p =
s.precision();
409 s.precision(std::numeric_limits<double>::digits10);
412 break;
413 }
414
415 case OksData::s8_int_type:
416 s << static_cast<int16_t>(
d.data.S8_INT);
417 break;
418
419 case OksData::u8_int_type:
420 s << static_cast<uint16_t>(
d.data.U8_INT);
421 break;
422
423 case OksData::s64_int_type:
425 break;
426
427 case OksData::u64_int_type:
429 break;
430
431 case OksData::bool_type:
432 s << ((
d.data.BOOL ==
true) ?
"true" :
"false");
433 break;
434
435 case OksData::date_type:
436 s << boost::gregorian::to_simple_string(
d.date());
437 break;
438
439 case OksData::time_type:
440 s << boost::posix_time::to_simple_string(
d.time());
441 break;
442
443 case OksData::enum_type:
444 s <<
'\"' << *(
d.data.ENUMERATION) <<
'\"';
445 break;
446
447 case OksData::class_type:
448 s <<
'[' <<
d.data.CLASS->get_name() <<
']';
449 break;
450
451 case OksData::unknown_type:
452 Oks::error_msg("operator<<(ostream&, const OksData&)") << "Can't put to stream \'OksData::unknown_type\'";
453 break;
454 }
455
457}
458
459void
460OksData::Clear()
461{
462 if (
type >= string_type) {
464 case list_type:
465 if (List* dlist =
data.LIST) {
466 if (!dlist->empty()) {
467 free_list(*dlist);
468 }
469 delete dlist;
470 }
471 break;
472
476 }
477 break;
478
479 case uid2_type:
480 if (
data.UID2.object_id) {
481 delete data.UID2.object_id;
482 }
483 if (
data.UID2.class_id) {
484 delete data.UID2.class_id;
485 }
486 break;
487
488 case uid_type:
489 if (
data.UID.object_id) {
490 delete data.UID.object_id;
491 }
492 break;
493
494 default:
495
496 break;
497 }
498 }
499
501}
502
503std::string
504AttributeRangeError::fill(
const OksData* d,
const std::string&
range)
505{
506 std::ostringstream
s;
508 if (
d->type == OksData::string_type ||
d->type == OksData::enum_type)
510 else
511 s <<
'\'' << *
d <<
'\'';
512 s <<
" is out of range \'" <<
range <<
'\'';
514}
515
516std::string
517AttributeReadError::fill(
const char* value,
const char*
type,
const std::string& reason)
518{
519 std::ostringstream
s;
520
521 if (value) {
522 s <<
"string \'" << value <<
'\'';
523 } else {
525 }
526
527 s <<
" is not a valid value for \'" <<
type <<
"\' type";
528
531
533}
534
535std::string
536AttributeReadError::fill(
const char*
type,
const std::string& reason)
537{
538 std::ostringstream
s;
539
540 s <<
"the string is not a valid value for \'" <<
type <<
"\' type";
541
544
546}
547
548void
549OksData::check_range(const OksAttribute* a) const
550{
551 if (a->p_range_obj == nullptr)
552 return;
553
554 if (
type == list_type) {
556 for (
const auto& i : *
data.LIST) {
557 i->check_range(a);
558 }
559 }
560 } else {
561 if (a->p_range_obj->validate(*this) == false) {
562 throw AttributeRangeError(this, a->get_range());
563 }
564 }
565}
566
567void
568OksData::SetNullValue(const OksAttribute* a)
569{
571 case s8_int_type:
573 return;
574 case u8_int_type:
576 return;
579 return;
580 case u32_int_type:
582 return;
583 case s32_int_type:
585 return;
586 case s16_int_type:
588 return;
589 case u16_int_type:
591 return;
592 case s64_int_type:
593 data.S64_INT = (int64_t)(0);
594 return;
595 case u64_int_type:
596 data.U64_INT = (uint64_t)(0);
597 return;
599 data.FLOAT = (float)(.0);
600 return;
602 data.DOUBLE = (double)(.0);
603 return;
605 data.STRING =
new OksString();
606 return;
608 data.ENUMERATION = &((*(a->p_enumerators))[0]);
609 return;
611 data.CLASS = a->p_class;
612 return;
614 SetFast(boost::gregorian::day_clock::universal_day());
615 return;
617 SetFast(boost::posix_time::second_clock::universal_time());
618 return;
619 default:
620 Clear2();
621 throw AttributeReadError("", "non-attribute-type", "internal OKS error");
622 }
623}
624
625void
626OksData::SetValue(const char* s, const OksAttribute* a)
627{
628 if (*s == '\0') {
629 SetNullValue(a);
630 } else {
632 case s8_int_type:
633 data.S8_INT =
static_cast<int8_t
>(strtol(s, 0, 0));
634 return;
635 case u8_int_type:
636 data.U8_INT =
static_cast<uint8_t
>(strtoul(s, 0, 0));
637 return;
639 switch (strlen(s)) {
640 case 4:
642 return;
643 case 1:
644 data.BOOL = (*
s ==
't' || *
s ==
'T' || *
s ==
'1');
645 return;
646 default:
648 return;
649 }
650 case u32_int_type:
651 data.U32_INT =
static_cast<uint32_t
>(strtoul(s, 0, 0));
652 return;
653 case s32_int_type:
654 data.S32_INT =
static_cast<int32_t
>(strtol(s, 0, 0));
655 return;
656 case s16_int_type:
657 data.S16_INT =
static_cast<int16_t
>(strtol(s, 0, 0));
658 return;
659 case u16_int_type:
660 data.U16_INT =
static_cast<uint16_t
>(strtoul(s, 0, 0));
661 return;
662 case s64_int_type:
663 data.S64_INT =
static_cast<int64_t
>(strtoll(s, 0, 0));
664 return;
665 case u64_int_type:
666 data.U64_INT =
static_cast<uint64_t
>(strtoull(s, 0, 0));
667 return;
669 data.FLOAT = strtof(s, 0);
670 return;
672 data.DOUBLE = strtod(s, 0);
673 return;
674
676 data.STRING =
new OksString(s);
677 return;
679 try {
680 data.ENUMERATION = a->get_enum_value(s, strlen(s));
681 return;
682 } catch (std::exception& ex) {
683 throw AttributeReadError(s, "enum", ex.what());
684 }
686 try {
687 if (strchr(s, '-') || strchr(s, '/')) {
688 SetFast(boost::gregorian::from_simple_string(s));
689 return;
690 } else {
691 SetFast(boost::gregorian::from_undelimited_string(s));
692 return;
693 }
694 } catch (std::exception& ex) {
695 throw AttributeReadError(s, "date", ex.what());
696 }
698 try {
699 if (strlen(s) == 15 && s[8] == 'T') {
700 SetFast(boost::posix_time::from_iso_string(s));
701 return;
702 } else {
703 SetFast(boost::posix_time::time_from_string(s));
704 return;
705 }
706 } catch (std::exception& ex) {
707 throw AttributeReadError(s, "time", ex.what());
708 }
710 if (OksClass* c = a->p_class->get_kernel()->find_class(s)) {
712 return;
713 } else {
714 Clear2();
715 throw AttributeReadError(s, "class", "the value is not a name of valid OKS class");
716 }
717 default:
718 Clear2();
719 throw AttributeReadError(s, "non-attribute-type", "internal OKS error");
720 }
721 }
722}
723
724std::list<std::string>
725OksAttribute::get_init_values() const
726{
727 std::list<std::string> val;
728
729
730 if (get_is_multi_values() == true) {
732 d.SetValues(get_init_value().c_str(),
this);
733
734 for (OksData::List::const_iterator i =
d.data.LIST->begin(); i !=
d.data.LIST->end(); ++i) {
735 val.push_back((*i)->str());
736 }
737 }
738
739 return val;
740}
741
742void
743OksData::SetValues(const char* s, const OksAttribute* a)
744{
745 if (!a->get_is_multi_values()) {
746 ReadFrom(s, a->get_data_type(), a);
747 return;
748 }
749
750 if (
type != list_type) {
751 Set(new List());
752 }
else if (!
data.LIST->empty()) {
753 free_list(*
data.LIST);
754 }
755
756 if (!s)
757 return;
758 while (*s == ' ')
760 if (*s == '\0')
761 return;
762
764
765 while (
str.length()) {
766 while (
str.length() && str[0] ==
' ')
769 return;
770 char delimeter = (
str[0] ==
'\"' ?
'\"' :
str[0] ==
'\'' ?
'\'' :
str[0] ==
'`' ?
'`' :
',');
771
772 if (delimeter != ',')
774 std::string::size_type p =
str.find(delimeter);
775
776 OksData*
d =
new OksData();
777 d->type = a->get_data_type();
778
779 if (
d->type == OksData::string_type) {
780 d->data.STRING =
new OksString(str, p);
781 }
else if (
d->type == OksData::enum_type) {
782 std::string token(str, 0, p);
783 d->data.ENUMERATION = a->get_enum_value(token);
784 } else {
785 std::string token(str, 0, p);
786 d->SetValue(token.c_str(), a);
787 }
788
789 data.LIST->push_back(d);
790
793 if (delimeter != ',') {
795 if (p == std::string::npos)
797 else
798 p++;
800 } else
802 }
803 }
804}
805
806void
807OksData::ReadFrom(const OksRelationship* r) noexcept
808{
809 if (
r->get_high_cardinality_constraint() != OksRelationship::Many) {
810 Set((OksObject*)0);
811 } else {
812 Set(new List());
813 }
814}
815
816void
817OksXmlInputStream::get_num_token(char __last)
818{
819 size_t pos(1);
820
821 try {
822 char c = get_first_non_empty();
823
824 if (c == __last) {
825 m_cvt_char->m_buf[0] = 0;
826 throw std::runtime_error("empty numeric value");
827 }
828
829 m_cvt_char->m_buf[0] =
c;
830
831 while (true) {
833
834 if (c == __last) {
835 m_cvt_char->m_buf[pos] = '\0';
837 return;
838 } else if (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
839 m_cvt_char->m_buf[pos] = '\0';
840 return;
841 }
842
843 m_cvt_char->realloc(pos);
844 m_cvt_char->m_buf[pos++] =
c;
845 }
846 } catch (std::exception& ex) {
847 m_cvt_char->m_buf[pos] = '\0';
848 throw BadFileData(std::string("failed to read numeric value: ") + ex.what(), line_no, line_pos);
849 }
850}
851
852void
853OksData::read(const ReadFileParams& read_params, const OksAttribute* a, int32_t num)
854{
855 if (
type != list_type) {
856 Set(new List());
857 }
else if (!
data.LIST->empty()) {
858 free_list(*
data.LIST);
859 }
860
861 while (num-- > 0) {
862 data.LIST->push_back(
new OksData(read_params, a));
863 }
864}
865
866void
867OksData::read(const ReadFileParams& read_params, const OksAttribute* a)
868{
869 const char* read_value = "";
870 char* __sanity;
871 OksXmlInputStream& fxs(read_params.s);
872
873 try {
874 switch (a->get_data_type()) {
876 read_value = "quoted string";
877 {
878 size_t len = fxs.get_quoted();
879 if (
type == string_type &&
data.STRING) {
880 data.STRING->assign(fxs.get_xml_token().m_buf, len);
881 } else {
882 Clear();
884 data.STRING =
new OksString(fxs.get_xml_token().m_buf, len);
885 }
886 }
887 break;
888
889 case s32_int_type:
890 read_value = "signed 32 bits integer";
891 fxs.get_num_token('<');
892 Set(static_cast<int32_t>(strtol(fxs.m_cvt_char->m_buf, &__sanity, 0)));
893 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
894 OksXmlInputStream::__throw_strto("strtol", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
895 break;
896
897 case u32_int_type:
898 read_value = "unsigned 32 bits integer";
899 fxs.get_num_token('<');
900 Set(static_cast<uint32_t>(strtoul(fxs.m_cvt_char->m_buf, &__sanity, 0)));
901 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
902 OksXmlInputStream::__throw_strto("strtoul", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
903 break;
904
905 case s16_int_type:
906 read_value = "signed 16 bits integer";
907 fxs.get_num_token('<');
908 Set(static_cast<int16_t>(strtol(fxs.m_cvt_char->m_buf, &__sanity, 0)));
909 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
910 OksXmlInputStream::__throw_strto("strtol", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
911 break;
912
913 case u16_int_type:
914 read_value = "unsigned 16 bits integer";
915 fxs.get_num_token('<');
916 Set(static_cast<uint16_t>(strtoul(fxs.m_cvt_char->m_buf, &__sanity, 0)));
917 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
918 OksXmlInputStream::__throw_strto("strtoul", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
919 break;
920
921 case s8_int_type:
922 read_value = "signed 8 bits integer";
923 fxs.get_num_token('<');
924 Set(static_cast<int8_t>(strtol(fxs.m_cvt_char->m_buf, &__sanity, 0)));
925 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
926 OksXmlInputStream::__throw_strto("strtol", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
927 break;
928
929 case u8_int_type:
930 read_value = "unsigned 8 bits integer";
931 fxs.get_num_token('<');
932 Set(static_cast<uint8_t>(strtoul(fxs.m_cvt_char->m_buf, &__sanity, 0)));
933 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
934 OksXmlInputStream::__throw_strto("strtoul", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
935 break;
936
937 case s64_int_type:
938 read_value = "signed 64 bits integer";
939 fxs.get_num_token('<');
940 Set(static_cast<int64_t>(strtoll(fxs.m_cvt_char->m_buf, &__sanity, 0)));
941 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
942 OksXmlInputStream::__throw_strto("strtoll", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
943 break;
944
945 case u64_int_type:
946 read_value = "unsigned 64 bits integer";
947 fxs.get_num_token('<');
948 Set(static_cast<uint64_t>(strtoull(fxs.m_cvt_char->m_buf, &__sanity, 0)));
949 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
950 OksXmlInputStream::__throw_strto("strtoull", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
951 break;
952
954 read_value = "float";
955 fxs.get_num_token('<');
956 Set(strtof(fxs.m_cvt_char->m_buf, &__sanity));
957 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
958 OksXmlInputStream::__throw_strto("strtof", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
959 break;
960
962 read_value = "double";
963 fxs.get_num_token('<');
964 Set(strtod(fxs.m_cvt_char->m_buf, &__sanity));
965 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
966 OksXmlInputStream::__throw_strto("strtod", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
967 break;
968
970 read_value = "boolean";
971 fxs.get_num_token('<');
972 Set(static_cast<bool>(strtol(fxs.m_cvt_char->m_buf, &__sanity, 0)));
973 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
974 OksXmlInputStream::__throw_strto("strtol", __sanity, fxs.m_cvt_char->m_buf, fxs.line_no, fxs.line_pos);
975 break;
976
978 read_value = "quoted date string";
979 {
980 size_t len = fxs.get_quoted();
981 Set(
str2date(fxs.get_xml_token().m_buf, len));
982 }
983 break;
984
986 read_value = "quoted time string";
987 {
988 size_t len = fxs.get_quoted();
989 Set(
str2time(fxs.get_xml_token().m_buf, len));
990 }
991 break;
992
994 read_value = "quoted enum string";
995 {
996 size_t len = fxs.get_quoted();
997 SetE(fxs.get_xml_token().m_buf, len, a);
998 }
999 break;
1000
1001 case uid2_type:
1002 read_value = "two quoted class-name / object-id strings";
1003 Set(new OksString(), new OksString());
1004 {
1005 size_t len = fxs.get_quoted();
1006 data.UID2.class_id->assign(fxs.get_xml_token().m_buf, len);
1007 len = fxs.get_quoted();
1008 data.UID2.object_id->assign(fxs.get_xml_token().m_buf, len);
1009 }
1010 break;
1011
1013 read_value = "quoted class-type string";
1015 fxs.get_quoted();
1016 SetValue(fxs.get_xml_token().m_buf, a);
1017 break;
1018
1019 default:
1020 type = unknown_type;
1021 {
1022 std::ostringstream
s;
1023 s <<
"Unknown attribute type \"" << (
int)a->get_data_type() <<
"\" (line " << fxs.get_line_no() <<
", char "
1024 << fxs.get_line_pos() << ')';
1025 throw std::runtime_error(
s.str().c_str());
1026 }
1027 }
1028 } catch (exception& e) {
1029 throw FailedRead(read_value, e);
1030 } catch (std::exception& e) {
1031 throw FailedRead(read_value, e.what());
1032 }
1033}
1034
1035void
1036OksData::read(const OksAttribute* a, const OksXmlValue& value)
1037{
1038 const char* read_value = "";
1039 char* __sanity;
1040
1041 try {
1042 switch (a->get_data_type()) {
1044 if (
type == string_type &&
data.STRING) {
1045 data.STRING->assign(value.buf(), value.len());
1046 } else {
1047 Clear();
1049 data.STRING =
new OksString(value.buf(), value.len());
1050 }
1051 } break;
1052
1053 case s32_int_type:
1054 read_value = "signed 32 bits integer";
1055 Set(static_cast<int32_t>(strtol(value.buf(), &__sanity, 0)));
1056 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1057 OksXmlInputStream::__throw_strto("strtol", __sanity, value.buf(), value.line_no(), value.line_pos());
1058 break;
1059
1060 case u32_int_type:
1061 read_value = "unsigned 32 bits integer";
1062 Set(static_cast<uint32_t>(strtoul(value.buf(), &__sanity, 0)));
1063 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1064 OksXmlInputStream::__throw_strto("strtoul", __sanity, value.buf(), value.line_no(), value.line_pos());
1065 break;
1066
1067 case s16_int_type:
1068 read_value = "signed 16 bits integer";
1069 Set(static_cast<int16_t>(strtol(value.buf(), &__sanity, 0)));
1070 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1071 OksXmlInputStream::__throw_strto("strtol", __sanity, value.buf(), value.line_no(), value.line_pos());
1072 break;
1073
1074 case u16_int_type:
1075 read_value = "unsigned 16 bits integer";
1076 Set(static_cast<uint16_t>(strtoul(value.buf(), &__sanity, 0)));
1077 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1078 OksXmlInputStream::__throw_strto("strtoul", __sanity, value.buf(), value.line_no(), value.line_pos());
1079 break;
1080
1081 case s8_int_type:
1082 read_value = "signed 8 bits integer";
1083 Set(static_cast<int8_t>(strtol(value.buf(), &__sanity, 0)));
1084 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1085 OksXmlInputStream::__throw_strto("strtol", __sanity, value.buf(), value.line_no(), value.line_pos());
1086 break;
1087
1088 case u8_int_type:
1089 read_value = "unsigned 8 bits integer";
1090 Set(static_cast<uint8_t>(strtoul(value.buf(), &__sanity, 0)));
1091 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1092 OksXmlInputStream::__throw_strto("strtoul", __sanity, value.buf(), value.line_no(), value.line_pos());
1093 break;
1094
1095 case s64_int_type:
1096 read_value = "signed 64 bits integer";
1097 Set(static_cast<int64_t>(strtoll(value.buf(), &__sanity, 0)));
1098 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1099 OksXmlInputStream::__throw_strto("strtoll", __sanity, value.buf(), value.line_no(), value.line_pos());
1100 break;
1101
1102 case u64_int_type:
1103 read_value = "unsigned 64 bits integer";
1104 Set(static_cast<uint64_t>(strtoull(value.buf(), &__sanity, 0)));
1105 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1106 OksXmlInputStream::__throw_strto("strtoull", __sanity, value.buf(), value.line_no(), value.line_pos());
1107 break;
1108
1110 read_value = "float";
1111 Set(strtof(value.buf(), &__sanity));
1112 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1113 OksXmlInputStream::__throw_strto("strtof", __sanity, value.buf(), value.line_no(), value.line_pos());
1114 break;
1115
1117 read_value = "double";
1118 Set(strtod(value.buf(), &__sanity));
1119 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1120 OksXmlInputStream::__throw_strto("strtod", __sanity, value.buf(), value.line_no(), value.line_pos());
1121 break;
1122
1124 read_value = "boolean";
1125 Set(static_cast<bool>(strtol(value.buf(), &__sanity, 0)));
1126 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
1127 OksXmlInputStream::__throw_strto("strtol", __sanity, value.buf(), value.line_no(), value.line_pos());
1128 break;
1129
1131 read_value = "quoted date string";
1132 Set(
str2date(value.buf(), value.len()));
1133 break;
1134
1136 read_value = "quoted time string";
1137 Set(
str2time(value.buf(), value.len()));
1138 break;
1139
1141 read_value = "quoted enum string";
1142 SetE(value.buf(), value.len(), a);
1143 break;
1144
1145 case uid2_type:
1146 read_value = "two quoted class-name / object-id strings";
1147 {
1148 std::ostringstream
s;
1149 s <<
"Unexpected uid2 type at (line " << value.line_no() <<
", char " << value.line_pos() <<
')';
1150 throw std::runtime_error(
s.str().c_str());
1151 }
1152 break;
1153
1155 read_value = "quoted class-type string";
1157 SetValue(value.buf(), a);
1158 break;
1159
1160 default:
1161 type = unknown_type;
1162 {
1163 std::ostringstream
s;
1164 s <<
"Unknown attribute type \"" << (
int)a->get_data_type() <<
"\" (line " << value.line_no() <<
", char "
1165 << value.line_pos() << ')';
1166 throw std::runtime_error(
s.str().c_str());
1167 }
1168 }
1169 } catch (exception& e) {
1170 throw FailedRead(read_value, e);
1171 } catch (std::exception& e) {
1172 throw FailedRead(read_value, e.what());
1173 }
1174}
1175
1176void
1177OksData::read(const OksAttribute* a, const ReadFileParams& read_params)
1178{
1179 if (
type != list_type)
1180 Set(new List());
1181 else if (!
data.LIST->empty())
1182 free_list(*
data.LIST);
1183
1184 while (true)
1185 try {
1186 const char* tag_start = read_params.s.get_tag_start();
1187
1188
1189 if (*tag_start ==
'/' &&
cmp_str5n(tag_start + 1, OksObject::attribute_xml_tag))
1190 break;
1191
1192 if (
cmp_str4(tag_start, OksObject::data_xml_tag)) {
1193 {
1194 OksXmlAttribute attr(read_params.s);
1195
1196 if (
cmp_str3(attr.name(), OksObject::value_xml_attribute)) {
1197 OksXmlValue value(read_params.s.get_value(attr.p_value_len));
1198 data.LIST->push_back(
new OksData(a, value));
1199 } else {
1200 std::ostringstream
s;
1201 s <<
"Unexpected attribute \"" << attr.name() <<
"\" instead of \"" << OksObject::value_xml_attribute
1202 << "\" (line " << read_params.s.get_line_no() << ", char " << read_params.s.get_line_pos() << ')';
1203 throw std::runtime_error(
s.str().c_str());
1204 }
1205 }
1206 {
1207 OksXmlAttribute attr(read_params.s);
1208
1209 if (
cmp_str1(attr.name(),
"/") ==
false) {
1210 std::ostringstream
s;
1211 s <<
"Unexpected tag \"" << attr.name() <<
"\" instead of close tag (line " << read_params.s.get_line_no()
1212 << ", char " << read_params.s.get_line_pos() << ')';
1213 throw std::runtime_error(
s.str().c_str());
1214 }
1215 }
1216 } else {
1217 std::ostringstream
s;
1218 s <<
"Unexpected tag \"" << tag_start <<
"\" (line " << read_params.s.get_line_no() <<
", char "
1219 << read_params.s.get_line_pos() << ')';
1220 throw std::runtime_error(
s.str().c_str());
1221 }
1222 } catch (exception& e) {
1223 throw FailedRead("multi-value", e);
1224 } catch (std::exception& e) {
1225 throw FailedRead("multi-value", e.what());
1226 }
1227}
1228
1229void
1230OksData::read(const ReadFileParams& read_params, const OksRelationship* r, int32_t num)
1231{
1232 if (__builtin_expect((
type != list_type), 0)) {
1233 Set(new List());
1234 }
else if (__builtin_expect((!
data.LIST->empty()), 0)) {
1235 free_list(*
data.LIST);
1236 }
1237
1238 while (num-- > 0) {
1239 OksData*
d =
new OksData(read_params, r);
1240
1241
1242 if (__builtin_expect((
d->type == OksData::uid2_type &&
d->data.UID2.class_id->empty()), 0))
1243 continue;
1244
1245
1246 data.LIST->push_back(d);
1247 }
1248}
1249
1250void
1251OksData::read(const ReadFileParams& read_params, const OksRelationship* r)
1252{
1253 const OksClass* rel_class(
r->p_class_type);
1254 OksString* class_id(0);
1255 const OksClass*
c(0);
1256 OksXmlInputStream& fxs(read_params.s);
1257
1258 try {
1259
1260
1261
1262 size_t len = fxs.get_quoted();
1263
1264 if (__builtin_expect((len > 0), 1)) {
1265 if (__builtin_expect((!read_params.alias_table), 1)) {
1266 if (__builtin_expect((rel_class != 0), 1)) {
1267 c = rel_class->get_kernel()->find_class(fxs.get_xml_token().m_buf);
1268 }
1269
1270 if (__builtin_expect((c == 0), 0)) {
1271 class_id = new OksString(fxs.get_xml_token().m_buf, len);
1272 }
1273 } else {
1274 const char* class_name_str(fxs.get_xml_token().m_buf);
1275
1276 if (class_name_str[0] == '@') {
1277 class_name_str++;
1279
1280 c = (rel_class ? rel_class->get_kernel()->find_class(class_name_str) : 0);
1281
1282 if (c) {
1283 read_params.alias_table->add_value(0, c);
1284 } else {
1285 read_params.alias_table->add_value(new OksString(class_name_str, len), 0);
1286 }
1287 } else {
1288 if (rel_class) {
1289 if (const OksAliasTable::Value* value = read_params.alias_table->get(class_name_str)) {
1290 c = (value->class_ptr ? value->class_ptr : rel_class->get_kernel()->find_class(*value->class_name));
1291 } else {
1292 Oks::warning_msg("OksData::read(const ReadFileParams&, const OksRelationship*")
1293 << " Can't find alias for class \'" << class_name_str
1294 << "\'\n"
1295 " Possibly data file has been saved in old format\n";
1296
1297 c = rel_class->get_kernel()->find_class(class_name_str);
1298 }
1299 }
1300 }
1301
1302 if (!c) {
1303 class_id = new OksString(class_name_str, len);
1304 }
1305 }
1306 }
1307
1308
1309
1310 len = fxs.get_quoted();
1311
1312 if (__builtin_expect((c == 0), 0)) {
1313 if (class_id) {
1314 Set(class_id, new OksString(fxs.get_xml_token().m_buf, len));
1315 class_id = 0;
1316 } else {
1317 Set((OksObject*)0);
1318 }
1319
1320 goto final;
1321 }
1322
1323 std::string& obj_id((const_cast<ReadFileParams&>(read_params)).tmp);
1324 obj_id.assign(fxs.get_xml_token().m_buf, len);
1325 OksObject*
obj =
c->get_object(obj_id);
1326
1328 Set(c, new OksString(obj_id));
1329 goto final;
1330 }
1331
1332
1333
1334 read_params.owner->OksObject::check_class_type(r, c);
1336 obj->add_RCR(read_params.owner, r);
1337 } catch (exception& ex) {
1338 if (class_id)
1339 delete class_id;
1340 throw FailedRead("relationship value", ex);
1341 } catch (std::exception& ex) {
1342 if (class_id)
1343 delete class_id;
1344 throw FailedRead("relationship value", ex.what());
1345 }
1346
1347final:
1348
1349 IsConsistent(r, read_params.owner, "WARNING");
1350}
1351
1352void
1353OksData::read(const OksRelationship* r, const OksXmlRelValue& value)
1354{
1355 try {
1356 if (__builtin_expect((value.m_class == nullptr), 0)) {
1357 if (value.m_class_id) {
1358 Set(value.m_class_id, new OksString(value.m_value.buf(), value.m_value.len()));
1359 value.m_class_id = nullptr;
1360 } else {
1361 Set((OksObject*)nullptr);
1362 }
1363
1364 goto final;
1365 }
1366
1367 OksObject*
obj = value.m_class->get_object(value.m_value.buf());
1368
1370 Set(value.m_class, new OksString(value.m_value.buf(), value.m_value.len()));
1371 goto final;
1372 }
1373
1374
1375
1376 value.m_file_params.owner->OksObject::check_class_type(r, value.m_class);
1378 obj->add_RCR(value.m_file_params.owner, r);
1379 } catch (exception& ex) {
1380 if (value.m_class_id)
1381 delete value.m_class_id;
1382 throw FailedRead("relationship value", ex);
1383 } catch (std::exception& ex) {
1384 if (value.m_class_id)
1385 delete value.m_class_id;
1386 throw FailedRead("relationship value", ex.what());
1387 }
1388
1389final:
1390
1391 IsConsistent(r, value.m_file_params.owner, "WARNING");
1392}
1393
1394void
1395OksData::read(const OksRelationship* r, const ReadFileParams& read_params)
1396{
1397 if (
type != list_type)
1398 Set(new List());
1399 else if (!
data.LIST->empty())
1400 free_list(*
data.LIST);
1401
1402 while (true)
1403 try {
1404 const char* tag_start = read_params.s.get_tag_start();
1405
1406
1407 if (*tag_start ==
'/' &&
cmp_str4n(tag_start + 1, OksObject::relationship_xml_tag))
1408 break;
1409
1410 if (
cmp_str3(tag_start, OksObject::ref_xml_tag)) {
1411 OksXmlRelValue value(read_params);
1412
1413 try {
1414 while (true) {
1415 OksXmlAttribute attr(read_params.s);
1416
1417
1418
1420 break;
1421 }
1422
1423
1424
1425 else if (
cmp_str5(attr.name(), OksObject::class_xml_attribute)) {
1426 value.m_class = read_params.owner->uid.class_id->get_kernel()->find_class(attr.value());
1427 if (__builtin_expect((value.m_class == nullptr && attr.value_len() > 0), 0)) {
1428 value.m_class_id = new OksString(attr.value(), attr.value_len());
1429 }
1430 }
else if (
cmp_str2(attr.name(), OksObject::id_xml_attribute)) {
1431 value.m_value = read_params.s.get_value(attr.p_value_len);
1432 } else
1433 read_params.s.throw_unexpected_attribute(attr.name());
1434 }
1435
1436 if (value.is_empty() == false) {
1437 OksData*
d =
new OksData(r, value);
1438
1439
1440 if (__builtin_expect((
d->type == OksData::uid2_type &&
d->data.UID2.class_id->empty()), 0))
1441 continue;
1442
1443
1444 data.LIST->push_back(d);
1445 }
1446 } catch (exception& e) {
1447 throw FailedRead("multi-value relationship", e);
1448 } catch (std::exception& e) {
1449 throw FailedRead("multi-value relationship", e.what());
1450 }
1451 } else {
1452 std::ostringstream
s;
1453 s <<
"Unexpected tag \"" << tag_start <<
"\" (line " << read_params.s.get_line_no() <<
", char "
1454 << read_params.s.get_line_pos() << ')';
1455 throw std::runtime_error(
s.str().c_str());
1456 }
1457 } catch (exception& e) {
1458 throw FailedRead("multi-value", e);
1459 } catch (std::exception& e) {
1460 throw FailedRead("multi-value", e.what());
1461 }
1462}
1463
1464
1465
1466
1467
1468
1469void
1470OksData::WriteTo(OksXmlOutputStream& xmls, bool put_number) const
1471{
1473 case list_type: {
1474 if (!
data.LIST->empty()) {
1475 if (put_number)
1476 xmls.put_value((
unsigned long)
data.LIST->size());
1477 for (List::iterator i =
data.LIST->begin(); i !=
data.LIST->end(); ++i) {
1478 if (!put_number) {
1479 xmls.put_raw('\n');
1480 xmls.put_raw(' ');
1481 }
1482
1483 xmls.put_raw(' ');
1484
1485 (*i)->WriteTo(xmls, put_number);
1486 }
1487
1488 if (!put_number) {
1489 xmls.put_raw('\n');
1490 xmls.put_raw(' ');
1491 }
1492 } else {
1493 if (put_number)
1494 xmls.put_raw('0');
1495 }
1496
1497 break;
1498 }
1499
1501 xmls.put_quoted(
data.STRING->c_str());
1502 break;
1503
1504 case s32_int_type:
1505 xmls.put_value(
data.S32_INT);
1506 break;
1507
1508 case u32_int_type:
1509 xmls.put_value(
data.U32_INT);
1510 break;
1511
1512 case s16_int_type:
1513 xmls.put_value(
data.S16_INT);
1514 break;
1515
1516 case u16_int_type:
1517 xmls.put_value(
data.U16_INT);
1518 break;
1519
1521 std::ostream&
s = xmls.get_stream();
1522 std::streamsize p =
s.precision();
1523 s.precision(std::numeric_limits<float>::digits10);
1524 xmls.put_value(
data.FLOAT);
1526 break;
1527 }
1528
1530 std::ostream&
s = xmls.get_stream();
1531 std::streamsize p =
s.precision();
1532 s.precision(std::numeric_limits<double>::digits10);
1533 xmls.put_value(
data.DOUBLE);
1535 break;
1536 }
1537
1538 case s8_int_type:
1539 xmls.put_value(
static_cast<int16_t
>(
data.S8_INT));
1540 break;
1541
1542 case u8_int_type:
1543 xmls.put_value(
static_cast<uint16_t
>(
data.U8_INT));
1544 break;
1545
1546 case s64_int_type:
1547 xmls.put_value(
data.S64_INT);
1548 break;
1549
1550 case u64_int_type:
1551 xmls.put_value(
data.U64_INT);
1552 break;
1553
1555 xmls.put_value((
short)(
data.BOOL));
1556 break;
1557
1559 xmls.put_quoted(boost::gregorian::to_iso_string(date()).c_str());
1560 break;
1561
1563 xmls.put_quoted(boost::posix_time::to_iso_string(time()).c_str());
1564 break;
1565
1567 xmls.put_quoted(
data.ENUMERATION->c_str());
1568 break;
1569
1571 xmls.put_quoted(
data.CLASS->get_name().c_str());
1572 break;
1573
1574 case uid2_type:
1575 case uid_type:
1576 case object_type:
1577 case unknown_type:
1578 Oks::error_msg("OksData::WriteTo(OksXmlOutputStream&, bool)")
1579 <<
"Can't write \'" << (
type == unknown_type ?
"unknown" :
"relationship") <<
"_type\'\n";
1580 break;
1581 }
1582}
1583
1584void
1585OksData::WriteTo(OksXmlOutputStream& xmls) const
1586{
1589 xmls.put(
data.STRING->c_str());
1590 break;
1591
1592 case s32_int_type:
1593 xmls.put_value(
data.S32_INT);
1594 break;
1595
1596 case u32_int_type:
1597 xmls.put_value(
data.U32_INT);
1598 break;
1599
1600 case s16_int_type:
1601 xmls.put_value(
data.S16_INT);
1602 break;
1603
1604 case u16_int_type:
1605 xmls.put_value(
data.U16_INT);
1606 break;
1607
1609 std::ostream&
s = xmls.get_stream();
1610 std::streamsize p =
s.precision();
1611 s.precision(std::numeric_limits<float>::digits10);
1612 xmls.put_value(
data.FLOAT);
1614 break;
1615 }
1616
1618 std::ostream&
s = xmls.get_stream();
1619 std::streamsize p =
s.precision();
1620 s.precision(std::numeric_limits<double>::digits10);
1621 xmls.put_value(
data.DOUBLE);
1623 break;
1624 }
1625
1626 case s8_int_type:
1627 xmls.put_value(
static_cast<int16_t
>(
data.S8_INT));
1628 break;
1629
1630 case u8_int_type:
1631 xmls.put_value(
static_cast<uint16_t
>(
data.U8_INT));
1632 break;
1633
1634 case s64_int_type:
1635 xmls.put_value(
data.S64_INT);
1636 break;
1637
1638 case u64_int_type:
1639 xmls.put_value(
data.U64_INT);
1640 break;
1641
1643 xmls.put_value((
short)(
data.BOOL));
1644 break;
1645
1647 xmls.put(boost::gregorian::to_iso_string(date()).c_str());
1648 break;
1649
1651 xmls.put(boost::posix_time::to_iso_string(time()).c_str());
1652 break;
1653
1655 xmls.put(
data.ENUMERATION->c_str());
1656 break;
1657
1659 xmls.put(
data.CLASS->get_name().c_str());
1660 break;
1661
1662 case list_type:
1663 throw std::runtime_error("internal error: call OksData::WriteTo() on list");
1664
1665 case uid2_type:
1666 case uid_type:
1667 case object_type:
1668 case unknown_type:
1669 Oks::error_msg("OksData::WriteTo(OksXmlOutputStream&, bool)")
1670 <<
"Can't write \'" << (
type == unknown_type ?
"unknown" :
"relationship") <<
"_type\'\n";
1671 break;
1672 }
1673}
1674
1675
1676
1677
1678
1679void
1680OksData::WriteTo(OksXmlOutputStream& xmls,
1681 OksKernel* k,
1682 OksAliasTable* alias_table,
1683 bool ,
1684 bool put_number) const
1685{
1686 const char* fname = "WriteTo(OksXmlOutputStream&, ...)";
1687
1688 static std::string emptyName("");
1689
1690 const std::string* class_name = 0;
1691 const std::string* object_id = 0;
1692
1694 case object_type:
1696 class_name = &
data.OBJECT->GetClass()->get_name();
1697 object_id = &
data.OBJECT->GetId();
1698 } else
1699 class_name = object_id = &emptyName;
1700
1701 break;
1702
1703 case list_type: {
1704 if (!
data.LIST->empty()) {
1705 if (put_number)
1706 xmls.put_value((
unsigned long)
data.LIST->size());
1707
1708 for (List::iterator i =
data.LIST->begin(); i !=
data.LIST->end(); ++i) {
1709 if (!put_number) {
1710 xmls.put_raw('\n');
1711 xmls.put_raw(' ');
1712 }
1713
1714 xmls.put_raw(' ');
1715
1716 (*i)->WriteTo(xmls, k, alias_table, false, put_number);
1717 }
1718
1719 if (!put_number) {
1720 xmls.put_raw('\n');
1721 xmls.put_raw(' ');
1722 }
1723 } else {
1724 if (put_number)
1725 xmls.put_raw('0');
1726 }
1727
1728 return;
1729 }
1730
1731 case uid2_type:
1732 class_name =
data.UID2.class_id;
1733 object_id =
data.UID2.object_id;
1734 break;
1735
1736 case uid_type:
1737 class_name = &
data.UID.class_id->get_name();
1738 object_id =
data.UID.object_id;
1739 break;
1740
1741 default:
1742 Oks::error_msg(fname) <<
"Can't write \'" << (
type == unknown_type ?
"unknown" :
"attribute") <<
"_type\'\n";
1743 return;
1744 }
1745
1746 if (!class_name->empty()) {
1747
1748
1749
1750 if (!alias_table) {
1751 xmls.put_quoted(class_name->c_str());
1752 }
1753
1754
1755
1756 else {
1757 const OksAliasTable::Value* value = alias_table->get(static_cast<const OksString*>(class_name));
1758
1759
1760 if (value)
1761 xmls.put_quoted(value->class_name->c_str());
1762
1763
1764 else {
1765 alias_table->add_key(static_cast<OksString*>(const_cast<std::string*>(class_name)));
1766
1767 std::string
s(*class_name);
1769 xmls.put_quoted(
s.c_str());
1770 }
1771 }
1772
1773 } else {
1774 xmls.put_quoted("");
1775 }
1776
1777 xmls.put_raw(' ');
1778 xmls.put_quoted(object_id->c_str());
1779}
1780
1781void
1782OksData::ConvertTo(OksData*
to,
const OksRelationship* r)
const
1783{
1784 if (
r->get_high_cardinality_constraint() == OksRelationship::Many) {
1785 to->Set(
new List());
1786
1787 if (
type != list_type) {
1788 OksData* item = new OksData();
1789
1790 if (
type == OksData::object_type)
1791 item->Set(
data.OBJECT);
1792 else if (
type == OksData::uid_type)
1793 item->Set(
data.UID.class_id, *
data.UID.object_id);
1794 else if (
type == OksData::uid2_type)
1795 item->Set(*
data.UID2.class_id, *
data.UID2.object_id);
1796
1797 to->data.LIST->push_back(item);
1798
1799 return;
1800 }
else if (
data.LIST && !
data.LIST->empty()) {
1801 for (List::iterator i =
data.LIST->begin(); i !=
data.LIST->end(); ++i) {
1802 OksData* item = new OksData();
1803 OksData* dd = *i;
1804
1805 if (dd->type == OksData::object_type)
1806 item->Set(dd->data.OBJECT);
1807 else if (dd->type == OksData::uid_type)
1808 item->Set(dd->data.UID.class_id, *dd->data.UID.object_id);
1809 else if (dd->type == OksData::uid2_type)
1810 item->Set(*dd->data.UID2.class_id, *dd->data.UID2.object_id);
1811
1812 to->data.LIST->push_back(item);
1813 }
1814
1815 return;
1816 }
1817
1818 } else {
1819 const OksData* from = ((
type == list_type) ?
data.LIST->front() :
this);
1820
1821 if (from->type == OksData::object_type)
1822 to->Set(from->data.OBJECT);
1823 else if (from->type == OksData::uid_type)
1824 to->Set(from->data.UID.class_id, *from->data.UID.object_id);
1825 else if (from->type == OksData::uid2_type)
1826 to->Set(*from->data.UID2.class_id, *from->data.UID2.object_id);
1827 }
1828}
1829
1830void
1831OksData::cvt(OksData*
to,
const OksAttribute* a)
const
1832{
1833 if (a->get_is_multi_values()) {
1834 to->Set(
new List());
1835
1836 if (
type != list_type) {
1837 OksData* item = new OksData();
1838
1839 std::string cvts =
str();
1840 item->ReadFrom(cvts.c_str(), a->get_data_type(), a);
1841
1842 to->data.LIST->push_back(item);
1843
1844 return;
1845 }
else if (
data.LIST && !
data.LIST->empty()) {
1846 for (List::iterator i =
data.LIST->begin(); i !=
data.LIST->end(); ++i) {
1847 OksData* item = new OksData();
1848 OksData* dd = *i;
1849
1850 std::string cvts = dd->str();
1851 item->ReadFrom(cvts.c_str(), a->get_data_type(), a);
1852
1853 to->data.LIST->push_back(item);
1854 }
1855
1856 return;
1857 }
1858 } else {
1859 const OksData* from = ((
type == list_type) ? (
data.LIST->empty() ? 0 :
data.LIST->front()) :
this);
1860 std::string cvts;
1861 if (from)
1862 cvts = from->str();
1863 to->ReadFrom(cvts.c_str(), a->get_data_type(), a);
1864 }
1865}
1866
1867static std::string
1868list2str(const OksData::List* l, const OksKernel* k, int base)
1869{
1870 std::ostringstream
s;
1871
1873
1874 if (l) {
1875 bool is_first = true;
1876
1877 for (OksData::List::const_iterator i =
l->begin(); i !=
l->end(); ++i) {
1878 std::string s2 = (k ? (*i)->str(k) : (*i)->str(base));
1879
1880 if (!s2.empty()) {
1881 if (is_first == false) {
1883 } else {
1884 is_first = false;
1885 }
1887 }
1888 }
1889 }
1890
1892
1894}
1895
1896
1897
1898std::string
1899OksData::str(const OksKernel* kernel) const
1900{
1901 if (
type == list_type) {
1902 return list2str(
data.LIST, kernel, 0);
1903 }
1904
1905 std::ostringstream
s;
1906
1908 case uid2_type:
1909 s <<
"#[" << *
data.UID2.object_id <<
'@' << *
data.UID2.class_id <<
']';
1910 break;
1911
1912 case uid_type:
1913 s <<
"#[" << *
data.UID.object_id <<
'@' <<
data.UID.class_id->get_name() <<
']';
1914 break;
1915
1916 case object_type:
1917 if (
data.OBJECT && !kernel->is_dangling(
data.OBJECT) &&
data.OBJECT->GetClass()->get_name().length()) {
1918 s <<
'[' <<
data.OBJECT->GetId() <<
'@' <<
data.OBJECT->GetClass()->get_name() <<
']';
1919 }
1920 break;
1921
1922 default:
1923 std::cerr << "ERROR [OksData::str(const OksKernel *)]: wrong use for such data: " << *this << std::endl;
1924 return "";
1925 }
1926
1928}
1929
1930
1931
1932std::string
1933OksData::str(int base) const
1934{
1935 if (
type == string_type) {
1936 return *
data.STRING;
1937 }
else if (
type == enum_type) {
1938 return *
data.ENUMERATION;
1939 }
else if (
type == bool_type) {
1940 return (
data.BOOL ?
"true" :
"false");
1941 }
else if (
type == list_type) {
1942 return list2str(
data.LIST, 0, base);
1943 }
else if (
type == date_type) {
1944 return boost::gregorian::to_simple_string(date());
1945 }
else if (
type == time_type) {
1946 return boost::posix_time::to_simple_string(time());
1947 }
else if (
type == class_type) {
1948 return data.CLASS->get_name();
1949 }
1950
1951 std::ostringstream
s;
1952
1953 if (base) {
1954 s.setf((base == 10 ? std::ios::dec : base == 16 ? std::ios::hex : std::ios::oct), std::ios::basefield);
1955 s.setf(std::ios::showbase);
1956 }
1957
1959 case s8_int_type:
1960 s << static_cast<int16_t>(
data.S8_INT);
1961 break;
1962
1963 case u8_int_type:
1964 s << static_cast<uint16_t>(
data.U8_INT);
1965 break;
1966
1967 case s16_int_type:
1969 break;
1970
1971 case u16_int_type:
1973 break;
1974
1975 case s32_int_type:
1977 break;
1978
1979 case u32_int_type:
1981 break;
1982
1983 case s64_int_type:
1985 break;
1986
1987 case u64_int_type:
1989 break;
1990
1992 s.precision(std::numeric_limits<float>::digits10);
1994 break;
1995
1997 s.precision(std::numeric_limits<double>::digits10);
1999 break;
2000
2001 default:
2002 std::cerr << "ERROR [OksData::str(int)]: wrong use for such data: " << *this << std::endl;
2003 return "";
2004 }
2005
2007}
2008
2009bool
2010OksData::IsConsistent(const OksRelationship* r, const OksObject* o, const char* msg)
2011{
2012 if (
r->get_low_cardinality_constraint() != OksRelationship::Zero) {
2013 if ((
type == OksData::object_type &&
data.OBJECT == 0) ||
2014 (
type == OksData::uid_type && (!
data.UID.object_id ||
data.UID.object_id->empty() || !
data.UID.class_id)) ||
2015 (
type == OksData::uid2_type && (!
data.UID2.object_id || !
data.UID2.class_id ||
data.UID2.object_id->empty() ||
2016 data.UID2.class_id->empty()))) {
2017 if (o->GetClass()->get_kernel()->get_silence_mode() != true) {
2018 std::cerr << msg <<
": value of \"" <<
r->get_name() <<
"\" relationship in object " << o
2019 << " must be non-null\n";
2020 }
2021 return false;
2022 }
else if (
type == OksData::list_type &&
data.LIST->empty()) {
2023 if (o->GetClass()->get_kernel()->get_silence_mode() != true) {
2024 std::cerr << msg <<
": \"" <<
r->get_name() <<
"\" relationship in object " << o
2025 << " must contain at least one object\n";
2026 }
2027 return false;
2028 }
2029 }
2030
2031 return true;
2032}
2033
2034void
2035OksData::sort(bool ascending)
2036{
2037 if (
type != list_type ||
data.LIST->size() < 2)
2038 return;
2039
2040 if (ascending)
2041 data.LIST->sort([](
const OksData* a,
const OksData* b) {
return *a < *b; });
2042 else
2043 data.LIST->sort([](
const OksData* a,
const OksData* b) {
return *a > *b; });
2044}
2045
2046boost::posix_time::ptime
2047str2time(
const char* value,
size_t len,
const char* file_name)
2048{
2049 if (len == 15 && value[8] == 'T') {
2050 try {
2051 return boost::posix_time::from_iso_string(value);
2052 } catch (std::exception& ex) {
2053
2054 throw AttributeReadError(value, "time", ex.what());
2055 }
2056 } else {
2057 try {
2059 std::ostringstream text;
2060 text << std::setfill('0') << std::setw(4) << t.year() << std::setw(2) << (t.month() + 1) << std::setw(2)
2061 << t.day() << 'T' << std::setw(2) << t.hour() << std::setw(2) << t.min() << std::setw(2) << t.sec();
2062 TLOG_DEBUG(1) <<
"parse OKS time: " << t <<
" => " << text.str();
2063
2064 if (file_name)
2066 else
2067 Oks::warning_msg("oks str2time") << "The file is using deprecated OKS time format \"" << value
2068 << "\"\nPlease refresh it using an oks application\nSupport for such format "
2069 "will be removed in a future release.\n";
2070
2071 return boost::posix_time::from_iso_string(text.str());
2072 } catch (exception& ex) {
2073
2074 throw AttributeReadError(value, "time", ex);
2075 } catch (std::exception& ex) {
2076
2077 throw AttributeReadError(value, "time", ex.what());
2078 }
2079 }
2080}
2081
2082boost::gregorian::date
2083str2date(
const char* value,
size_t len)
2084{
2085 if (len == 8 && value[2] != '/' && value[3] != '/') {
2086 try {
2087 return boost::gregorian::from_undelimited_string(value);
2088 } catch (std::exception& ex) {
2089 throw AttributeReadError(value, "date", ex.what());
2090 }
2091 } else {
2092 try {
2093 Date t(value);
2094 std::ostringstream text;
2095 text << std::setfill('0') << std::setw(4) << t.year() << std::setw(2) << (t.month() + 1) << std::setw(2)
2096 << t.day();
2097 TLOG_DEBUG(1) <<
"parse OKS date: " << t <<
" => " << text.str();
2098
2099 Oks::warning_msg("oks str2date") << "The file is using deprecated OKS date format \"" << value
2100 << "\"\nPlease refresh it using an oks application.\nSupport for such format "
2101 "will be removed in a future release.\n";
2102
2103 return boost::gregorian::from_undelimited_string(text.str());
2104 } catch (exception& ex) {
2105 throw AttributeReadError(value, "date", ex);
2106 } catch (std::exception& ex) {
2107 throw AttributeReadError(value, "date", ex.what());
2108 }
2109 }
2110}
2111
2112}
#define TLOG_DEBUG(lvl,...)
std::string const reason(ers::Issue const &)
bool cmp_str1(const char *s1, const char s2[2])
bool cmp_str4(const char *s1, const char s2[5])
bool cmp_str5n(const char *s1, const char s2[5])
boost::posix_time::ptime str2time(const char *value, size_t len, const char *file_name=nullptr)
boost::gregorian::date str2date(const char *value, size_t len)
bool cmp_str2(const char *s1, const char s2[3])
bool cmp_str5(const char *s1, const char s2[6])
bool cmp_str3(const char *s1, const char s2[4])
bool cmp_str4n(const char *s1, const char s2[4])
DAC value out of range
Message.
std::ostream & operator<<(std::ostream &s, const ConfigurationChange &c)
Both frame_count_limit and tp_count_limit were set to(disabled) in the TPCRawDataProcessor " "config. TPs will not send."
void warning(const Issue &issue)