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