MADARA  3.2.3
KnowledgeRecord.inl
Go to the documentation of this file.
1 
2 
3 #ifndef _KNOWLEDGE_RECORD_INL_
4 #define _KNOWLEDGE_RECORD_INL_
5 
6 #include <algorithm>
7 #include <iostream>
8 #include <sstream>
9 #include <math.h>
10 
11 #include "madara/utility/Utility.h"
13 
21 namespace madara { namespace knowledge {
22 
23 inline
25 : logger_ (&logger)
26 {
27 }
28 
29 template<typename T,
30  typename std::enable_if<std::is_integral<T>::value, void*>::type>
32  logger::Logger & logger) noexcept
33 : logger_ (&logger), int_value_ ((Integer)value), type_ (INTEGER)
34 {
35 }
36 
38  const std::vector <Integer> & value, logger::Logger & logger)
39 : logger_ (&logger)
40 {
41  set_value (value);
42 }
43 
45  std::vector <Integer> && value, logger::Logger & logger) noexcept
46 : logger_ (&logger)
47 {
48  set_value (std::move(value));
49 }
50 
52  std::shared_ptr<std::vector<Integer>> value,
53  logger::Logger & logger) noexcept
54 : logger_ (&logger)
55 {
56  set_value (std::move(value));
57 }
58 
59 template<typename T,
60  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
61 inline KnowledgeRecord::KnowledgeRecord (T value,
62  logger::Logger & logger) noexcept
63 : logger_ (&logger), double_value_ ((double)value), type_ (DOUBLE)
64 {
65 }
66 
68  const std::vector <double> & value,
69  logger::Logger & logger)
70 : logger_ (&logger)
71 {
72  set_value (value);
73 }
74 
76  std::vector <double> && value,
77  logger::Logger & logger) noexcept
78 : logger_ (&logger)
79 {
80  set_value (std::move(value));
81 }
82 
84  std::shared_ptr<std::vector<double>> value,
85  logger::Logger & logger) noexcept
86 : logger_ (&logger)
87 {
88  set_value (std::move(value));
89 }
90 
92  logger::Logger & logger)
93 : logger_ (&logger)
94 {
95  set_value (value);
96 }
97 
99  logger::Logger & logger) noexcept
100 : logger_ (&logger)
101 {
102  set_value (std::move(value));
103 }
104 
106  std::shared_ptr<std::string> value,
107  logger::Logger & logger) noexcept
108 : logger_ (&logger)
109 {
110  set_value (std::move(value));
111 }
112 
113 inline KnowledgeRecord::KnowledgeRecord (const char * value,
114  logger::Logger & logger)
115 : logger_ (&logger)
116 {
117  set_value (std::string (value));
118 }
119 
121  std::shared_ptr<std::vector<unsigned char>> value,
122  logger::Logger & logger) noexcept
123 : logger_ (&logger)
124 {
125  set_file (std::move(value));
126 }
127 
129  const knowledge::KnowledgeRecord & rhs)
130 : logger_ (rhs.logger_),
131  clock (rhs.clock),
132  quality (rhs.quality),
134  type_ (rhs.type_),
135  shared_ (rhs.is_ref_counted() ? SHARED : OWNED)
136 {
137  if (rhs.type_ == EMPTY)
138  return;
139 
140  if (rhs.type_ == INTEGER)
141  int_value_ = rhs.int_value_;
142  else if (rhs.type_ == INTEGER_ARRAY)
143  new (&int_array_) std::shared_ptr<std::vector<Integer>>(rhs.int_array_);
144  else if (rhs.type_ == DOUBLE)
146  else if (rhs.type_ == DOUBLE_ARRAY)
147  new (&double_array_) std::shared_ptr<std::vector<double>>(rhs.double_array_);
148  else if (rhs.is_string_type ())
149  new (&str_value_) std::shared_ptr<std::string>(rhs.str_value_);
150  else if (rhs.is_binary_file_type ())
151  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(rhs.file_value_);
152 }
153 
155  knowledge::KnowledgeRecord &&rhs) noexcept
156 : logger_ (std::move(rhs.logger_)),
157  clock (rhs.clock),
158  quality (rhs.quality),
160  type_ (rhs.type_),
161  shared_ (rhs.shared_)
162 {
163  if (rhs.type_ == EMPTY)
164  return;
165 
166  if (rhs.type_ == INTEGER)
167  int_value_ = rhs.int_value_;
168  else if (rhs.type_ == INTEGER_ARRAY)
169  new (&int_array_) std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
170  else if (rhs.type_ == DOUBLE)
171  double_value_ = rhs.double_value_;
172  else if (rhs.type_ == DOUBLE_ARRAY)
173  new (&double_array_) std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
174  else if (rhs.is_string_type ())
175  new (&str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
176  else if (rhs.is_binary_file_type ())
177  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
178 
179  rhs.type_ = EMPTY;
180 }
181 
183 {
184  clear_union();
185 }
186 
187 inline KnowledgeRecord &
189 {
190  if (this == &rhs)
191  return *this;
192 
193  // clear any dynamic memory being used on the left hand side
194  clear_value ();
195 
196  if (rhs.type_ == EMPTY)
197  return *this;
198 
199  // set the instance properties accordingly
200  clock = rhs.clock;
201  quality = rhs.quality;
203  type_ = rhs.type_;
205 
206  if (rhs.type_ == INTEGER)
207  int_value_ = rhs.int_value_;
208  else if (rhs.type_ == INTEGER_ARRAY)
209  new (&int_array_) std::shared_ptr<std::vector<Integer>>(rhs.int_array_);
210  else if (rhs.type_ == DOUBLE)
212  else if (rhs.type_ == DOUBLE_ARRAY)
213  new (&double_array_) std::shared_ptr<std::vector<double>>(rhs.double_array_);
214  else if (rhs.is_string_type ())
215  new (&str_value_) std::shared_ptr<std::string>(rhs.str_value_);
216  else if (rhs.is_binary_file_type ())
217  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(rhs.file_value_);
218 
219  return *this;
220 }
221 
222 inline KnowledgeRecord &
224 {
225  if (this == &rhs)
226  return *this;
227 
228  // clear any dynamic memory being used on the left hand side
229  clear_value();
230 
231  if (rhs.type_ == EMPTY)
232  return *this;
233 
234  // set the instance properties accordingly
235  clock = rhs.clock;
236  quality = rhs.quality;
237  write_quality = rhs.write_quality;
238  type_ = rhs.type_;
239  shared_ = rhs.shared_;
240 
241  if (rhs.type_ == INTEGER)
242  int_value_ = rhs.int_value_;
243  else if (rhs.type_ == INTEGER_ARRAY)
244  new (&int_array_) std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
245  else if (rhs.type_ == DOUBLE)
246  double_value_ = rhs.double_value_;
247  else if (rhs.type_ == DOUBLE_ARRAY)
248  new (&double_array_) std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
249  else if (rhs.is_string_type ())
250  new (&str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
251  else if (rhs.is_binary_file_type ())
252  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
253 
254  rhs.type_ = EMPTY;
255 
256  return *this;
257 }
258 
259 #if 0
260 template<typename T,
261  typename std::enable_if<std::is_integral<T>::value, void*>::type>
262 inline bool
263 KnowledgeRecord::operator== (T value) const
264 {
265  // for this type of comparison, we can only be equal if we are the same
266  // base type
267  if (is_integer_type ())
268  {
269  return to_integer () == value;
270  }
271  else if (is_double_type () || is_string_type ())
272  {
273  return to_double () == value;
274  }
275 
276  return false;
277 }
278 
279 template<typename T,
280  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
281 inline bool
282 KnowledgeRecord::operator== (T value) const
283 {
284  // for this type of comparison, we can only be equal if we are the same
285  // base type
286  if (is_integer_type ())
287  {
288  return to_integer () == value;
289  }
290  else if (is_double_type () || is_string_type ())
291  {
292  return to_double () == value;
293  }
294 
295  return false;
296 }
297 
298 inline bool
300  const std::string & value) const
301 {
302  return to_string () == value;
303 }
304 
305 inline bool
306 KnowledgeRecord::operator== (const char * value) const
307 {
308  return to_string ().compare (value) == 0;
309 }
310 #endif
311 
312 inline bool
314 {
315  return !(*this == rhs);
316 }
317 
321 inline bool
323 {
324  return !is_true ();
325 }
326 
330 inline KnowledgeRecord
332 {
333  KnowledgeRecord record (*this);
334 
335  if (type_ == INTEGER)
336  {
337  record.set_value (-int_value_);
338  }
339  else if (type_ == DOUBLE)
340  {
341  record.set_value (-double_value_);
342  }
343 
344  return record;
345 }
346 
350 inline KnowledgeRecord &
352 {
353  if (is_integer_type ())
354  {
355  if (rhs.is_integer_type ())
356  set_value (to_integer () + rhs.to_integer ());
357  else
358  set_value (to_integer () + rhs.to_double ());
359  }
360  else if (is_double_type ())
361  set_value (to_double () + rhs.to_double ());
362 
363  else if (is_string_type ())
364  set_value (to_string () + rhs.to_string ());
365 
366  return *this;
367 }
368 
372 inline KnowledgeRecord &
374 {
375  if (is_integer_type ())
376  set_value (to_integer () - 1);
377 
378  else if (is_double_type ())
379  set_value (to_double () - 1);
380 
381  return *this;
382 }
383 
387 inline KnowledgeRecord &
389 {
390  if (is_integer_type ())
391  set_value (to_integer () + 1);
392 
393  else if (is_double_type ())
394  set_value (to_double () + 1);
395 
396 
397  return *this;
398 }
399 
403 inline KnowledgeRecord &
405 {
406  if (is_integer_type ())
407  {
408  if (rhs.is_integer_type ())
409  set_value (to_integer () - rhs.to_integer ());
410  else
411  set_value (to_integer () - rhs.to_double ());
412  }
413  else if (is_double_type () || is_string_type ())
414  set_value (to_double () - rhs.to_double ());
415 
416  return *this;
417 }
418 
422 inline KnowledgeRecord &
424 {
425  if (is_integer_type ())
426  {
427  if (rhs.is_integer_type ())
428  set_value (to_integer () * rhs.to_integer ());
429  else
430  set_value (to_integer () * rhs.to_double ());
431  }
432  else if (is_double_type () || is_string_type ())
433  set_value (to_double () * rhs.to_double ());
434 
435  return *this;
436 }
437 
441 inline KnowledgeRecord &
443 {
444  if (is_integer_type ())
445  {
446  if (rhs.is_integer_type ())
447  {
448  Integer denom = rhs.to_integer ();
449  if (denom == 0)
450  set_value (NAN);
451  else
452  set_value (to_integer () / denom);
453  }
454  else
455  {
456  double denom = rhs.to_double ();
457 
458  if (denom == 0)
459  set_value (NAN);
460  else
461  set_value (to_integer () / denom);
462  }
463  }
464  else if (is_double_type () || is_string_type ())
465  {
466  double denom = rhs.to_double ();
467 
468  if (denom == 0)
469  set_value (NAN);
470  else
471  set_value (to_double () / denom);
472  }
473 
474  return *this;
475 }
476 
480 inline KnowledgeRecord &
482 {
483  if (is_integer_type ())
484  {
485  if (rhs.is_integer_type ())
486  {
487  Integer denom = rhs.to_integer ();
488  if (denom == 0)
489  set_value (NAN);
490  else
491  set_value (to_integer () % denom);
492  }
493  }
494 
495  return *this;
496 }
497 
501 inline KnowledgeRecord
503 {
504  // copy this value to a local copy
505  knowledge::KnowledgeRecord ret_value (*this);
506 
507  return ret_value *= rhs;
508 }
509 
513 inline KnowledgeRecord
515 {
516  // copy this value to a local copy
517  knowledge::KnowledgeRecord ret_value (*this);
518 
519  return ret_value /= rhs;
520 }
521 
525 inline KnowledgeRecord
527 {
528  // copy this value to a local copy
529  knowledge::KnowledgeRecord ret_value (*this);
530 
531  return ret_value %= rhs;
532 }
533 
537 inline KnowledgeRecord
539 {
540  // copy this value to a local copy
541  knowledge::KnowledgeRecord ret_value (*this);
542 
543  return ret_value += rhs;
544 }
545 
546 inline bool
548 {
549  return !is_true ();
550 }
551 
555 inline std::ostream & operator<< (std::ostream & stream,
556  const KnowledgeRecord & rhs)
557 {
558  if (rhs.type () &
561  {
562  stream << rhs.to_string (", ");
563  }
564  else
565  stream << rhs.to_string ();
566 
567  return stream;
568 }
569 
573 inline KnowledgeRecord
575 {
576  // copy this value to a local copy
577  knowledge::KnowledgeRecord ret_value (*this);
578 
579  return ret_value -= rhs;
580 }
581 
582 inline void
584 {
585  if (shared_ != SHARED) {
586  return;
587  }
588 
589  if (is_ref_counted ())
590  {
591  if (is_string_type()) {
593  } else if (is_binary_file_type()) {
595  } else if (type_ == INTEGER_ARRAY) {
597  } else if (type_ == DOUBLE_ARRAY) {
599  }
600  }
601  shared_ = OWNED;
602 }
603 
604 inline KnowledgeRecord *
606 {
608 
609  result->unshare();
610 
611  return result;
612 }
613 
614 inline void
616 {
617  *this = source;
618  unshare();
619 }
620 
621 inline KnowledgeRecord
623 {
624  KnowledgeRecord ret (*this);
625  ret.unshare();
626  return ret;
627 }
628 
629 inline bool
631 {
632  return type_ != EMPTY;
633 }
634 
635 inline int
637 {
638  return type_ == EMPTY ? UNCREATED : MODIFIED;
639 }
640 
644 inline void
646 {
647  if (!exists()) {
648  set_value ((Integer)0);
649  }
650 }
651 
652 inline uint32_t
654 {
655  if (type_ == INTEGER || type_ == DOUBLE) {
656  return 1;
657  } else if (is_string_type()) {
658  return (uint32_t)str_value_->size () + 1;
659  } else if (is_binary_file_type()) {
660  return (uint32_t)file_value_->size ();
661  } else if (type_ == INTEGER_ARRAY) {
662  return (uint32_t)int_array_->size ();
663  } else if (type_ == DOUBLE_ARRAY) {
664  return (uint32_t)double_array_->size ();
665  }
666  return 1;
667 }
668 
669 inline int32_t
671 {
672  return type_;
673 }
674 
675 inline bool
677 {
678  if ((uint32_t)type == type_ ||
679  (is_string_type() && is_string_type(type)) ||
681  ) {
682  type_ = type;
683  return true;
684  }
685  return false;
686 }
687 
688 inline int64_t
690 {
691  int64_t buffer_size (sizeof (uint32_t) * 2);
692  if (type_ == INTEGER)
693  {
694  buffer_size += sizeof (Integer);
695  }
696  else if (type_ == DOUBLE)
697  {
698  buffer_size += sizeof (double);
699  }
700  else if (type_ == INTEGER_ARRAY)
701  {
702  buffer_size += sizeof (Integer) * double_array_->size();
703  }
704  else if (type_ == DOUBLE_ARRAY)
705  {
706  buffer_size += sizeof (double) * double_array_->size();
707  }
708  else if (is_string_type ())
709  {
710  buffer_size += str_value_->size () + 1;
711  }
712  else if (is_binary_file_type ())
713  {
714  buffer_size += file_value_->size ();
715  }
716 
717  return buffer_size;
718 }
719 
720 inline int64_t
722 {
723  // for keyed size, add another uint32_t and the size of the key with a null char
724  int64_t buffer_size (sizeof (uint32_t) * 1);
725  buffer_size += (key.size () + 1);
726 
727  // and then add the default encoded size
728  buffer_size += get_encoded_size ();
729 
730  return buffer_size;
731 }
732 
733 inline bool
735 {
736  return is_ref_counted (type_);
737 }
738 
739 inline bool
741 {
742  return type != INTEGER && type != DOUBLE;
743 }
744 
745 inline bool
747 {
748  return is_string_type (type_);
749 }
750 
751 inline bool
753 {
754  return type == STRING || type == XML || type == TEXT_FILE;
755 }
756 
757 inline bool
759 {
760  return is_double_type (type_);
761 }
762 
763 inline bool
765 {
766  return type == DOUBLE || type == DOUBLE_ARRAY;
767 }
768 
769 inline bool
771 {
772  return is_integer_type (type_);
773 }
774 
775 
776 inline bool
778 {
779  return type == EMPTY || type == INTEGER || type == INTEGER_ARRAY;
780 }
781 
782 inline bool
784 {
785  return is_array_type (type_);
786 }
787 
788 inline bool
790 {
791  return (type & ALL_ARRAYS) != 0;
792 }
793 
794 inline bool
796 {
797  return is_image_type (type_);
798 }
799 
800 inline bool
802 {
803  return type == IMAGE_JPEG;
804 }
805 
806 inline bool
808 {
809  return is_file_type (type_);
810 }
811 
812 inline bool
814 {
815  return type == TEXT_FILE || type == XML ||
816  type == IMAGE_JPEG || type == UNKNOWN_FILE_TYPE;
817 }
818 
819 inline bool
821 {
822  return is_binary_file_type (type_);
823 }
824 
825 inline bool
827 {
828  return type == IMAGE_JPEG || type == UNKNOWN_FILE_TYPE;
829 }
830 
831 inline uint32_t
833 {
834  uint32_t max = 0;
835 
836  // iterate over the list and return the max
837  for (KnowledgeRecords::const_iterator i = records.begin ();
838  i != records.end (); ++i)
839  {
840  max = std::max <uint32_t> (i->second->quality, max);
841  }
842  return max;
843 }
844 
845 inline uint32_t
846 max_quality (const KnowledgeMap & records)
847 {
848  uint32_t max = 0;
849 
850  // iterate over the list and return the max
851  for (KnowledgeMap::const_iterator i = records.begin ();
852  i != records.end (); ++i)
853  {
854  max = std::max <uint32_t> (i->second.quality, max);
855  }
856  return max;
857 }
858 
859 template<typename T>
860 inline void destruct(T &x) {
861  x.~T();
862 }
863 
864 inline void
866 {
867  if (type_ & ALL_CLEARABLES)
868  {
869  if (type_ == INTEGER_ARRAY)
871  else if (type_ == DOUBLE_ARRAY)
873  else if (is_string_type ())
875  else if (is_binary_file_type ())
877  shared_ = OWNED;
878  }
879 }
880 
881 inline void
883 {
884  clear_union ();
885 
886  type_ = EMPTY;
887 }
888 
889 inline const char *
890 KnowledgeRecord::read (const char * buffer,
891  int64_t & buffer_remaining)
892 {
893  // format is [key_size | key | type | value_size | value]
894 
895  uint32_t buff_value_size (0);
896  decltype(type_) type = INTEGER;
897  uint32_t size = 1;
898 
899  // Remove the type of value from the buffer
900  if (buffer_remaining >= (int64_t) sizeof (type))
901  {
902  memcpy (&type, buffer, sizeof (type));
904  buffer += sizeof (type);
905  }
906  buffer_remaining -= sizeof (type);
907 
908  // Remove the size of value from the buffer
909  if (buffer_remaining >= (int64_t) sizeof (size))
910  {
911  memcpy (&size, buffer, sizeof (size));
912  size = madara::utility::endian_swap (size);
913 
914  if (is_integer_type (type))
915  buff_value_size = size * sizeof (Integer);
916  else if (is_double_type (type))
917  buff_value_size = size * sizeof (double);
918  else
919  buff_value_size = size;
920 
921  buffer += sizeof (buff_value_size);
922  } else {
923  buffer_remaining = -1;
924  return buffer;
925  }
926  buffer_remaining -= sizeof (buff_value_size);
927 
928  // Remove the value from the buffer
929  if (buffer_remaining >= int64_t (buff_value_size))
930  {
931  if (is_string_type (type))
932  {
933  if (buff_value_size >= 1) {
934  emplace_string (buffer, buff_value_size - 1);
935  } else {
936  emplace_string ();
937  }
938  }
939 
940  else if (type == INTEGER)
941  {
942  Integer tmp;
943  memcpy (&tmp, buffer, sizeof (tmp));
945  }
946 
947  else if (type == INTEGER_ARRAY)
948  {
949  std::vector<Integer> tmp;
950  tmp.reserve(size);
951 
952  for (uint32_t i = 0; i < size; ++i)
953  {
954  Integer cur;
955  memcpy (&cur, buffer + i * sizeof(cur), sizeof(cur));
956  tmp.emplace_back(madara::utility::endian_swap (cur));
957  }
958 
959  emplace_integers (std::move(tmp));
960  }
961 
962  else if (type == DOUBLE)
963  {
964  double tmp;
965  memcpy (&tmp, buffer, sizeof (tmp));
967  }
968 
969  else if (type == DOUBLE_ARRAY)
970  {
971  std::vector<double> tmp;
972  tmp.reserve(size);
973 
974  for (uint32_t i = 0; i < size; ++i)
975  {
976  double cur;
977  memcpy (&cur, buffer + i * sizeof(cur), sizeof(cur));
978  tmp.emplace_back(madara::utility::endian_swap (cur));
979  }
980 
981  emplace_doubles (std::move(tmp));
982  }
983 
984  else if (is_binary_file_type (type))
985  {
986  const unsigned char *b = (const unsigned char *)buffer;
987  emplace_file (b, b + size);
988  }
989 
990  else {
991  buffer_remaining = -1;
992  return buffer;
993  }
994 
995  buffer += buff_value_size;
996  buffer_remaining -= sizeof (char) * buff_value_size;
997 
998  type_ = type;
999  }
1000 
1001  return buffer;
1002 }
1003 
1004 inline const char *
1005 KnowledgeRecord::read (const char * buffer, std::string & key,
1006 int64_t & buffer_remaining)
1007 {
1008  // format is [key_size | key | type | value_size | value]
1009 
1010  uint32_t key_size (0);
1011 
1012  // Remove the key size from the buffer
1013  if (buffer_remaining >= (int64_t) sizeof (key_size))
1014  {
1015  memcpy (&key_size, buffer, sizeof (key_size));
1016  key_size = madara::utility::endian_swap (key_size);
1017  buffer += sizeof (key_size);
1018  }
1019  buffer_remaining -= sizeof (key_size);
1020 
1021  // Remove the key from the buffer
1022  if (buffer_remaining >= int64_t (sizeof (char) * int64_t (key_size)))
1023  {
1024  if (key_size > 0) {
1025  // don't worry about null terminator
1026  key.assign (buffer, key_size - 1);
1027  } else {
1028  key.clear ();
1029  }
1030 
1031  buffer += sizeof (char) * key_size;
1032  }
1033  buffer_remaining -= sizeof (char) * int64_t (key_size);
1034 
1035  // read the type and data
1036  buffer = read (buffer, buffer_remaining);
1037 
1038  return buffer;
1039 }
1040 
1041 inline const char *
1042 KnowledgeRecord::read (const char * buffer, uint32_t & key_id,
1043 int64_t & buffer_remaining)
1044 {
1045  // format is [key_id | type | value_size | value]
1046 
1047  // Remove the key size from the buffer
1048  if (buffer_remaining >= (int64_t) sizeof (key_id))
1049  {
1050  memcpy (&key_id, buffer, sizeof (key_id));
1051  key_id = madara::utility::endian_swap (key_id);
1052  buffer += sizeof (key_id);
1053  buffer_remaining -= sizeof (key_id);
1054 
1055  // read the type and data
1056  buffer = read (buffer, buffer_remaining);
1057  }
1058 
1059  return buffer;
1060 }
1061 
1062 // reset the value_ to an integer
1063 inline void
1065 {
1066  clear_value ();
1067 
1068  quality = 0;
1069  write_quality = 0;
1070  clock = 0;
1071 }
1072 
1073 inline void
1075 {
1076  uint64_t cur_clock = this->clock;
1077  uint32_t cur_quality = this->write_quality;
1078  uint32_t cur_write_quality = this->write_quality;
1079  *this = new_value;
1080  this->clock = cur_clock;
1081  this->quality = cur_quality;
1082  this->write_quality = cur_write_quality;
1083 }
1084 
1085 inline void
1087 {
1088  uint64_t cur_clock = this->clock;
1089  uint32_t cur_quality = this->write_quality;
1090  uint32_t cur_write_quality = this->write_quality;
1091  *this = std::move(new_value);
1092  this->clock = cur_clock;
1093  this->quality = cur_quality;
1094  this->write_quality = cur_write_quality;
1095 }
1096 
1097 // set the value_ to a string
1098 inline void
1100 {
1101  emplace_string (std::move(new_value));
1102  type_ = STRING;
1103 }
1104 
1105 // set the value_ to a string
1106 inline void
1108 {
1109  emplace_string (new_value);
1110  type_ = STRING;
1111 }
1112 
1113 // set the value_ to a string
1114 inline void
1115 KnowledgeRecord::set_value (std::shared_ptr<std::string> new_value)
1116 {
1117  emplace_shared_string (std::move(new_value));
1118  type_ = STRING;
1119 }
1120 
1121 // set the value_ to a string
1122 inline void
1123 KnowledgeRecord::set_value (const char * new_value, uint32_t size)
1124 {
1125  emplace_string (new_value, size);
1126  type_ = STRING;
1127 }
1128 
1129 // set the value_ to a string
1130 inline void
1131 KnowledgeRecord::set_xml (const char * new_value, size_t size)
1132 {
1133  emplace_string (new_value, size);
1134  type_ = XML;
1135 }
1136 
1137 // set the value_ to a string
1138 inline void
1140 {
1141  emplace_string (std::move(new_value));
1142  type_ = XML;
1143 }
1144 
1145 // set the value_ to a string
1146 inline void
1148 {
1149  emplace_string (new_value);
1150  type_ = XML;
1151 }
1152 
1153 // set the value_ to a string
1154 inline void
1155 KnowledgeRecord::set_xml (std::shared_ptr<std::string> new_value)
1156 {
1157  emplace_shared_string (std::move(new_value));
1158  type_ = XML;
1159 }
1160 
1161 // set the value_ to a string
1162 inline void
1163 KnowledgeRecord::set_text (const char * new_value, size_t size)
1164 {
1165  emplace_string (new_value, size);
1166  type_ = TEXT_FILE;
1167 }
1168 
1169 // set the value_ to a string
1170 inline void
1172 {
1173  emplace_string (std::move(new_value));
1174  type_ = TEXT_FILE;
1175 }
1176 
1177 // set the value_ to a string
1178 inline void
1180 {
1181  emplace_string (new_value);
1182  type_ = TEXT_FILE;
1183 }
1184 
1185 // set the value_ to a string
1186 inline void
1187 KnowledgeRecord::set_text (std::shared_ptr<std::string> new_value)
1188 {
1189  emplace_shared_string (std::move(new_value));
1190  type_ = TEXT_FILE;
1191 }
1192 
1193 // set the value_ to a string
1194 inline void
1195 KnowledgeRecord::set_jpeg (const unsigned char * new_value,
1196  size_t size)
1197 {
1198  emplace_file (new_value, new_value + size);
1199  type_ = IMAGE_JPEG;
1200 }
1201 
1202 inline void
1203 KnowledgeRecord::set_jpeg (std::vector <unsigned char> && new_value)
1204 {
1205  emplace_file (std::move(new_value));
1206  type_ = IMAGE_JPEG;
1207 }
1208 
1209 inline void
1210 KnowledgeRecord::set_jpeg (const std::vector <unsigned char> & new_value)
1211 {
1212  emplace_file (new_value);
1213  type_ = IMAGE_JPEG;
1214 }
1215 
1216 inline void
1218  std::shared_ptr<std::vector <unsigned char>> new_value)
1219 {
1220  emplace_shared_file (std::move(new_value));
1221  type_ = IMAGE_JPEG;
1222 }
1223 
1224 // set the value_ to a string
1225 inline void
1226 KnowledgeRecord::set_file (const unsigned char * new_value,
1227  size_t size)
1228 {
1229  emplace_file (new_value, new_value + size);
1231 }
1232 
1233 inline void
1234 KnowledgeRecord::set_file (std::vector <unsigned char> && new_value)
1235 {
1236  emplace_file (std::move(new_value));
1238 }
1239 
1240 inline void
1241 KnowledgeRecord::set_file (const std::vector <unsigned char> & new_value)
1242 {
1243  emplace_file (new_value);
1245 }
1246 
1247 inline void
1249  std::shared_ptr<std::vector <unsigned char>> new_value)
1250 {
1251  emplace_shared_file (std::move(new_value));
1253 }
1254 
1255 // set the value_ to an integer
1256 template<typename T,
1257  typename std::enable_if<std::is_integral<T>::value, void*>::type>
1258 inline void
1260 {
1261  if (type_ != INTEGER) {
1262  clear_union();
1263  type_ = INTEGER;
1264  }
1265  int_value_ = new_value;
1266 }
1267 
1268 // set the value_ to an array of doubles
1269 inline void
1270 KnowledgeRecord::set_value (const Integer * new_value, uint32_t size)
1271 {
1272  emplace_integers (new_value, new_value + size);
1273 }
1274 
1275 // set the value_ to an array of integers
1276 inline void
1277 KnowledgeRecord::set_value (std::vector <Integer> && new_value)
1278 {
1279  emplace_integers (std::move(new_value));
1280 }
1281 
1282 // set the value_ to an array of integers
1283 inline void
1284 KnowledgeRecord::set_value (const std::vector <Integer> & new_value)
1285 {
1286  emplace_integers (new_value);
1287 }
1288 
1289 // set the value_ to an array of integers
1290 inline void
1291 KnowledgeRecord::set_value (std::shared_ptr<std::vector <Integer>> new_value)
1292 {
1293  emplace_shared_integers (std::move(new_value));
1294 }
1295 
1296 // set the value_ to a double
1297 template<typename T,
1298  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
1299 inline void
1300 KnowledgeRecord::set_value (T new_value)
1301 {
1302  if (type_ != DOUBLE) {
1303  clear_union();
1304  type_ = DOUBLE;
1305  }
1306  double_value_ = new_value;
1307 }
1308 
1309 // set the value_ to an array of doubles
1310 inline void
1311 KnowledgeRecord::set_value (const double * new_value, uint32_t size)
1312 {
1313  emplace_doubles (new_value, new_value + size);
1314 }
1315 
1316 // set the value_ to an array of doubles
1317 inline void
1318 KnowledgeRecord::set_value (std::vector <double> && new_value)
1319 {
1320  emplace_doubles (std::move(new_value));
1321 }
1322 
1323 // set the value_ to an array of doubles
1324 inline void
1325 KnowledgeRecord::set_value (const std::vector <double> & new_value)
1326 {
1327  emplace_doubles (new_value);
1328 }
1329 
1330 // set the value_ to an array of doubles
1331 inline void
1332 KnowledgeRecord::set_value (std::shared_ptr<std::vector <double>> new_value)
1333 {
1334  emplace_shared_doubles (std::move(new_value));
1335 }
1336 
1342 template<typename T,
1343  typename std::enable_if<std::is_integral<T>::value, void*>::type>
1344 inline void
1345 KnowledgeRecord::set_index (size_t index, T value)
1346 {
1347  if (type_ == DOUBLE_ARRAY)
1348  {
1349  // let the set_index for doubles take care of this
1350  set_index (index, double (value));
1351  return;
1352  }
1353  else if (type_ == INTEGER_ARRAY)
1354  {
1355  unshare();
1356 
1357  if (index >= int_array_->size ())
1358  {
1359  int_array_->resize(index + 1);
1360  }
1361  }
1362  else
1363  {
1364  emplace_integers (index + 1);
1365  }
1366 
1367  int_array_->at (index) = value;
1368 }
1369 
1375 template<typename T,
1376  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
1377 inline void
1378 KnowledgeRecord::set_index (size_t index, T value)
1379 {
1380  if (type_ == INTEGER_ARRAY)
1381  {
1382  std::vector<double> tmp (int_array_->begin (), int_array_->end ());
1383  emplace_doubles (std::move(tmp));
1384  }
1385  else if (type_ != DOUBLE_ARRAY)
1386  {
1387  emplace_doubles (index + 1);
1388  }
1389  else
1390  {
1391  unshare();
1392 
1393  if (index >= double_array_->size ())
1394  {
1395  double_array_->resize (index + 1);
1396  }
1397  }
1398 
1399  double_array_->at (index) = value;
1400 }
1401 
1402 inline std::shared_ptr<std::string>
1404 {
1405  if (is_string_type()) {
1406  shared_ = SHARED;
1407  return str_value_;
1408  }
1409  return nullptr;
1410 }
1411 
1412 inline std::shared_ptr<std::string>
1414 {
1415  if (is_string_type()) {
1416  std::shared_ptr<std::string> ret;
1417 
1418  using std::swap;
1419  swap(ret, str_value_);
1420 
1421  reset_value();
1422 
1423  return ret;
1424  }
1425  return nullptr;
1426 }
1427 
1428 inline std::shared_ptr<std::vector<KnowledgeRecord::Integer>>
1430 {
1431  if (type_ == INTEGER_ARRAY) {
1432  shared_ = SHARED;
1433  return int_array_;
1434  }
1435  return nullptr;
1436 }
1437 
1438 inline std::shared_ptr<std::vector<KnowledgeRecord::Integer>>
1440 {
1441  if (type_ == INTEGER_ARRAY) {
1442  std::shared_ptr<std::vector<Integer>> ret;
1443 
1444  using std::swap;
1445  swap(ret, int_array_);
1446 
1447  reset_value();
1448 
1449  return ret;
1450  }
1451  return nullptr;
1452 }
1453 
1454 inline std::shared_ptr<std::vector<double>>
1456 {
1457  if (type_ == DOUBLE_ARRAY) {
1458  shared_ = SHARED;
1459  return double_array_;
1460  }
1461  return nullptr;
1462 }
1463 
1464 inline std::shared_ptr<std::vector<double>>
1466 {
1467  if (type_ == DOUBLE_ARRAY) {
1468  std::shared_ptr<std::vector<double>> ret;
1469 
1470  using std::swap;
1471  swap(ret, double_array_);
1472 
1473  reset_value();
1474 
1475  return ret;
1476  }
1477  return nullptr;
1478 }
1479 
1480 inline std::shared_ptr<std::vector<unsigned char>>
1482 {
1483  if (is_binary_file_type()) {
1484  shared_ = SHARED;
1485  return file_value_;
1486  }
1487  return nullptr;
1488 }
1489 
1490 inline std::shared_ptr<std::vector<unsigned char>>
1492 {
1493  if (is_binary_file_type()) {
1494  std::shared_ptr<std::vector<unsigned char>> ret;
1495 
1496  using std::swap;
1497  swap(ret, file_value_);
1498 
1499  reset_value();
1500 
1501  return ret;
1502  }
1503  return nullptr;
1504 }
1505 
1506 inline
1507 KnowledgeRecord::operator bool (void) const
1508 {
1509  return is_true();
1510 }
1511 
1512 inline char *
1513 KnowledgeRecord::write (char * buffer,
1514  int64_t & buffer_remaining) const
1515 {
1516  // format is [type | value_size | value]
1517 
1518  char * size_location = 0;
1519  uint32_t size_intermediate = 0;
1520  uint32_t uint32_temp;
1521  Integer integer_temp;
1522  double double_temp;
1523  uint32_t size = this->size ();
1524 
1525  int64_t encoded_size = get_encoded_size ();
1526 
1527  if (buffer_remaining >= encoded_size)
1528  {
1529  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1530  " encoding %" PRId64 " byte message\n", encoded_size);
1531 
1532  // Remove the type of value from the buffer
1533  if (buffer_remaining >= (int64_t) sizeof (type_))
1534  {
1535  decltype(type_) tmp = madara::utility::endian_swap (type_);
1536  memcpy (buffer, &tmp, sizeof (tmp));
1537  buffer += sizeof (tmp);
1538  }
1539  buffer_remaining -= sizeof (type_);
1540 
1541  // Remove the size of value from the buffer
1542  if (buffer_remaining >= (int64_t) sizeof (size))
1543  {
1544  // set a pointer to size, in case we need to modify it during
1545  // value copy (e.g. during double conversion)
1546  size_location = buffer;
1547  size_intermediate = size;
1548 
1549  uint32_temp = madara::utility::endian_swap (size);
1550  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1551 
1552  // note that we do not encode the size yet because it may change
1553  // and we need the architectural-specific version for other checks
1554 
1555  buffer += sizeof (size);
1556  }
1557  buffer_remaining -= sizeof (size);
1558 
1559  // Remove the value from the buffer
1560  if (is_string_type ())
1561  {
1562  // strings do not have to be converted
1563  if (buffer_remaining >= int64_t (size))
1564  {
1565  memcpy (buffer, &(*str_value_)[0], size);
1566  }
1567  }
1568  else if (type_ == INTEGER)
1569  {
1570  if (buffer_remaining >= int64_t (sizeof (Integer)))
1571  {
1572  integer_temp = madara::utility::endian_swap (int_value_);
1573  memcpy (buffer, &integer_temp, sizeof (integer_temp));
1574 
1575  size_intermediate = sizeof (Integer);
1576  }
1577  }
1578  else if (type_ == INTEGER_ARRAY)
1579  {
1580  if (buffer_remaining >= int64_t (size * sizeof (Integer)))
1581  {
1582  // convert integers to network byte order
1583  const Integer * ptr_temp = &(*int_array_)[0];
1584  Integer * target_buffer = (Integer *)buffer;
1585 
1586  for (uint32_t i = 0; i < size; ++i, ++ptr_temp, ++target_buffer)
1587  {
1588  integer_temp = madara::utility::endian_swap (*ptr_temp);
1589  memcpy (target_buffer, &integer_temp, sizeof (Integer));
1590  }
1591 
1592  size_intermediate = size * sizeof (Integer);
1593  }
1594  }
1595  else if (type_ == DOUBLE)
1596  {
1597  if (buffer_remaining >= int64_t (sizeof (double)))
1598  {
1600  memcpy (buffer, &double_temp, sizeof (double));
1601 
1602  size_intermediate = sizeof (double);
1603  }
1604  }
1605  else if (type_ == DOUBLE_ARRAY)
1606  {
1607  if (buffer_remaining >= int64_t (size * sizeof (double)))
1608  {
1609  // convert integers to network byte order
1610  const double * ptr_temp = &(*double_array_)[0];
1611  double * target_buffer = (double *)buffer;
1612 
1613  for (uint32_t i = 0; i < size; ++i, ++ptr_temp, ++target_buffer)
1614  {
1615  double_temp = madara::utility::endian_swap (*ptr_temp);
1616  memcpy (target_buffer, &double_temp, sizeof (double_temp));
1617  }
1618 
1619  size_intermediate = size * sizeof (double);
1620 
1631  }
1632  }
1633  else if (is_binary_file_type ())
1634  {
1635  // strings do not have to be converted
1636  if (buffer_remaining >= size)
1637  {
1638  memcpy (buffer, &(*file_value_)[0], size);
1639  }
1640  }
1641 
1642  if (size_location)
1643  {
1644  buffer_remaining -= size_intermediate;
1645  buffer += size_intermediate;
1646  }
1647  }
1648  else
1649  {
1650  std::stringstream buffer;
1651  buffer << "KnowledgeRecord::write: ";
1652  buffer << encoded_size << " byte encoding cannot fit in ";
1653  buffer << buffer_remaining << " byte buffer\n";
1654 
1656  buffer.str ().c_str ());
1657 
1658  throw exceptions::MemoryException (buffer.str ());
1659  }
1660  return buffer;
1661 }
1662 
1663 inline char *
1664 KnowledgeRecord::write (char * buffer, const std::string & key,
1665 int64_t & buffer_remaining) const
1666 
1667 {
1668  // format is [key_size | key | type | value_size | value]
1669 
1670  uint32_t key_size = uint32_t (key.size () + 1);
1671  uint32_t uint32_temp;
1672 
1673  int64_t encoded_size = get_encoded_size (key);
1674 
1675  if (buffer_remaining >= encoded_size)
1676  {
1677  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1678  " encoding %" PRId64 " byte message\n", encoded_size);
1679 
1680  // Remove the key size from the buffer
1681  if (buffer_remaining >= (int64_t) sizeof (key_size))
1682  {
1683  uint32_temp = madara::utility::endian_swap (key_size);
1684  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1685  buffer += sizeof (key_size);
1686  }
1687  buffer_remaining -= sizeof (key_size);
1688 
1689  // Remove the key from the buffer
1690  if (buffer_remaining >= (int64_t) sizeof (char) * key_size)
1691  {
1692  // copy the string and set null terminator in buffer
1693  strncpy (buffer, key.c_str (), key_size - 1);
1694  buffer[key_size - 1] = 0;
1695 
1696  buffer += sizeof (char) * key_size;
1697  }
1698  buffer_remaining -= sizeof (char) * key_size;
1699 
1700  // write the type and value of the record
1701  buffer = write (buffer, buffer_remaining);
1702  }
1703  else
1704  {
1705  std::stringstream buffer;
1706  buffer << "KnowledgeRecord::write: ";
1707  buffer << encoded_size << " byte encoding cannot fit in ";
1708  buffer << buffer_remaining << " byte buffer\n";
1709 
1711  buffer.str ().c_str ());
1712 
1713  throw exceptions::MemoryException (buffer.str ());
1714  }
1715  return buffer;
1716 }
1717 
1718 inline char *
1719 KnowledgeRecord::write (char * buffer, uint32_t key_id,
1720  int64_t & buffer_remaining) const
1721 {
1722  // format is [key_id | type | value_size | value]
1723 
1724  uint32_t uint32_temp;
1725 
1726  int64_t encoded_size = get_encoded_size () + sizeof (key_id);
1727 
1728  if (buffer_remaining >= encoded_size)
1729  {
1730  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1731  " encoding %" PRId64 " byte message\n", encoded_size);
1732 
1733  // write the key id to the buffer
1734  if (buffer_remaining >= (int64_t)sizeof (key_id))
1735  {
1736  uint32_temp = madara::utility::endian_swap (key_id);
1737  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1738  buffer += sizeof (key_id);
1739  }
1740  buffer_remaining -= sizeof (key_id);
1741 
1742  // write the type and value of the record
1743  buffer = write (buffer, buffer_remaining);
1744  }
1745  else
1746  {
1747  std::stringstream buffer;
1748  buffer << "KnowledgeRecord::write: ";
1749  buffer << encoded_size << " byte encoding cannot fit in ";
1750  buffer << buffer_remaining << " byte buffer\n";
1751 
1753  buffer.str ().c_str ());
1754 
1755  throw exceptions::MemoryException (buffer.str ());
1756  }
1757  return buffer;
1758 }
1759 
1760 } }
1761 
1762 #endif // _KNOWLEDGE_RECORD_INL_
This class encapsulates an entry in a KnowledgeBase.
uint32_t max_quality(const KnowledgeRecords &records)
Returns the maximum quality within the records.
void emplace_shared_file(Args &&...args)
Construct a shared_ptr to a file (vector of unsigned char) within this KnowledgeRecord.
bool is_true(void) const
Checks to see if the record is true.
void emplace_string(Args &&...args)
Construct a string within this KnowledgeRecord.
std::shared_ptr< std::vector< double > > share_doubles() const
void reset_value(void) noexcept
resets the variable to an integer
int32_t type(void) const
returns the size of the value
std::shared_ptr< std::vector< unsigned char > > share_binary() const
bool is_image_type(void) const
returns true if the knowledge record has an image type
helper type for specifying template type parameters using a function argument instead of inside expli...
Definition: KnowledgeCast.h:72
std::shared_ptr< std::string > share_string() const
void emplace_integers(Args &&...args)
Construct a vector of integers within this KnowledgeRecord.
uint32_t quality
priority of the update
KnowledgeRecord deep_copy() const
Creates a deep copy of this knowledge record.
madara::knowledge::KnowledgeRecord KnowledgeRecord
void emplace_file(Args &&...args)
Construct a file (vector of unsigned char) within this KnowledgeRecord.
double to_double(void) const
converts the value to a float/double.
const char * read(const char *buffer, int64_t &buffer_remaining)
Reads a KnowledgeRecord instance from a buffer and updates the amount of buffer room remaining...
std::shared_ptr< std::vector< Integer > > share_integers() const
void set_file(const unsigned char *new_value, size_t size)
sets the value to an unknown file type
void clear_value(void) noexcept
clears any dynamic values.
KnowledgeRecord operator-(void) const
Negate.
STL namespace.
bool is_file_type(void) const
returns true if the knowledge record has a file type
bool is_binary_file_type(void) const
returns true if the knowledge record has a binary file type
void set_text(const char *new_value, size_t size)
sets the value to a plaintext string
std::shared_ptr< std::vector< Integer > > int_array_
void emplace_shared_integers(Args &&...args)
Construct a shared_ptr to vector of integers within this KnowledgeRecord.
int64_t get_encoded_size(void) const
Returns the encoded size of the record.
bool exists(void) const
Checks if record exists (i.e., is not uncreated)
bool is_double_type(void) const
returns if the record is a double type (DOUBLE, DOUBLE_ARRAY)
void set_xml(const char *new_value, size_t size)
sets the value to an xml string
logger::Logger * logger_
the logger used for any internal debugging information
Provides knowledge logging services to files and terminals.
Definition: GlobalLogger.h:11
void emplace_shared_doubles(Args &&...args)
Construct a shared_ptr to vector of doubles within this KnowledgeRecord.
bool set_type(int32_t type)
Modify the type, but only if it&#39;s compatible with current type without changing any actual data store...
void emplace_shared_string(Args &&...args)
Construct a shared_ptr to a string within this KnowledgeRecord.
A multi-threaded logger for logging to one or more destinations.
Definition: Logger.h:88
void set_value(const KnowledgeRecord &new_value)
Sets the value from another KnowledgeRecord, does not copy clock and write_quality.
std::shared_ptr< std::vector< double > > take_doubles()
int status(void) const
returns the status of the record.
void set_jpeg(const unsigned char *new_value, size_t size)
sets the value to a jpeg
KnowledgeRecord operator*(const KnowledgeRecord &rhs) const
Times operator.
KnowledgeRecord & operator*=(const KnowledgeRecord &rhs)
In-place multiplication operator.
KnowledgeRecord & operator%=(const KnowledgeRecord &rhs)
In-place modulus operator.
static struct madara::knowledge::tags::string_t string
uint64_t endian_swap(uint64_t value)
Converts a host format uint64_t into big endian.
Definition: Utility.inl:115
bool operator==(const KnowledgeRecord &rhs) const
Equal to.
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
::std::map< std::string, KnowledgeRecord * > KnowledgeRecords
KnowledgeRecord & operator++(void)
Preincrement operator.
std::shared_ptr< std::vector< unsigned char > > take_binary()
::std::map< std::string, KnowledgeRecord > KnowledgeMap
auto operator=(T &&t) -> typename std::enable_if<!std::is_convertible< T, KnowledgeRecord >::value, decltype(this->set_value(std::forward< T >(t)),*this)>::type
std::shared_ptr< std::vector< double > > double_array_
KnowledgeRecord operator%(const KnowledgeRecord &rhs) const
Modulus operator.
std::shared_ptr< std::vector< Integer > > take_integers()
void set_index(size_t index, T value)
sets the value at the index to the specified value.
void set_modified(void)
sets the status to modified
Integer to_integer(void) const
converts the value to an integer.
An exception for general memory errors like out-of-memory.
KnowledgeRecord & operator-=(const KnowledgeRecord &rhs)
In-place subtraction operator.
std::shared_ptr< std::vector< unsigned char > > file_value_
bool operator!(void) const
Logical not.
KnowledgeRecord operator+(const KnowledgeRecord &rhs) const
Plus operator.
KnowledgeRecord * clone(void) const
clones the record.
bool shared_
is this knowledge record&#39;s shared_ptr, if any, exposed to outside holders?
void unshare(void)
If this record holds a shared_ptr, make a copy of the underlying value so it has an exclusive copy...
Provides functions and classes for the distributed knowledge base.
std::ostream & operator<<(std::ostream &stream, const KnowledgeRecord &rhs)
output stream buffering
void emplace_doubles(Args &&...args)
Construct a vector of doubles within this KnowledgeRecord.
uint32_t write_quality
write priority for any local updates
uint32_t type_
type of variable (INTEGER, DOUBLE, STRING, FILE, IMAGE)
KnowledgeRecord & operator--(void)
Predecrement operator.
KnowledgeRecord & operator+=(const KnowledgeRecord &rhs)
In-place addition operator.
bool operator!=(const KnowledgeRecord &rhs) const
Unequal to.
bool is_array_type(void) const
returns if the record is an array type (DOUBLE_ARRAY, INTEGER_ARRAY)
Copyright (c) 2015 Carnegie Mellon University.
bool is_ref_counted(void) const
returns if the record has a reference-counted type
KnowledgeRecord & operator/=(const KnowledgeRecord &rhs)
In-place division operator.
char * write(char *buffer, int64_t &buffer_remaining) const
Writes a KnowledgeRecord instance to a buffer and updates the amount of buffer room remaining...
bool is_integer_type(void) const
returns if the record is a integer type (INTEGER, INTEGER_ARRAY)
bool is_false(void) const
Checks to see if the record is false.
bool is_string_type(void) const
returns true if the record is a string type (STRING, XML, TEXT_FILE)
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
std::shared_ptr< std::string > take_string()
uint32_t size(void) const
returns the size of the value
KnowledgeRecord operator/(const KnowledgeRecord &rhs) const
Divides operator.
uint64_t clock
last modification time
std::shared_ptr< std::string > str_value_