MADARA  3.1.8
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 
10 
18 namespace madara { namespace knowledge {
19 
20 inline
22 : logger_ (&logger)
23 {
24 }
25 
26 template<typename T,
27  typename std::enable_if<std::is_integral<T>::value, void*>::type>
29  logger::Logger & logger) noexcept
30 : logger_ (&logger), int_value_ ((Integer)value), type_ (INTEGER)
31 {
32 }
33 
35  const std::vector <Integer> & value, logger::Logger & logger)
36 : logger_ (&logger)
37 {
38  set_value (value);
39 }
40 
42  std::vector <Integer> && value, logger::Logger & logger) noexcept
43 : logger_ (&logger)
44 {
45  set_value (std::move(value));
46 }
47 
49  std::shared_ptr<std::vector<Integer>> value,
50  logger::Logger & logger) noexcept
51 : logger_ (&logger)
52 {
53  set_value (std::move(value));
54 }
55 
56 template<typename T,
57  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
58 inline KnowledgeRecord::KnowledgeRecord (T value,
59  logger::Logger & logger) noexcept
60 : logger_ (&logger), double_value_ ((double)value), type_ (DOUBLE)
61 {
62 }
63 
65  const std::vector <double> & value,
66  logger::Logger & logger)
67 : logger_ (&logger)
68 {
69  set_value (value);
70 }
71 
73  std::vector <double> && value,
74  logger::Logger & logger) noexcept
75 : logger_ (&logger)
76 {
77  set_value (std::move(value));
78 }
79 
81  std::shared_ptr<std::vector<double>> value,
82  logger::Logger & logger) noexcept
83 : logger_ (&logger)
84 {
85  set_value (std::move(value));
86 }
87 
89  logger::Logger & logger)
90 : logger_ (&logger)
91 {
92  set_value (value);
93 }
94 
96  logger::Logger & logger) noexcept
97 : logger_ (&logger)
98 {
99  set_value (std::move(value));
100 }
101 
103  std::shared_ptr<std::string> value,
104  logger::Logger & logger) noexcept
105 : logger_ (&logger)
106 {
107  set_value (std::move(value));
108 }
109 
110 inline KnowledgeRecord::KnowledgeRecord (const char * value,
111  logger::Logger & logger)
112 : logger_ (&logger)
113 {
114  set_value (std::string (value));
115 }
116 
118  std::shared_ptr<std::vector<unsigned char>> value,
119  logger::Logger & logger) noexcept
120 : logger_ (&logger)
121 {
122  set_file (std::move(value));
123 }
124 
126  const knowledge::KnowledgeRecord & rhs)
127 : logger_ (rhs.logger_),
128  clock (rhs.clock),
129  quality (rhs.quality),
131  type_ (rhs.type_),
132  shared_ (rhs.is_ref_counted() ? SHARED : OWNED)
133 {
134  if (rhs.type_ == EMPTY)
135  return;
136 
137  if (rhs.type_ == INTEGER)
138  int_value_ = rhs.int_value_;
139  else if (rhs.type_ == INTEGER_ARRAY)
140  new (&int_array_) std::shared_ptr<std::vector<Integer>>(rhs.int_array_);
141  else if (rhs.type_ == DOUBLE)
143  else if (rhs.type_ == DOUBLE_ARRAY)
144  new (&double_array_) std::shared_ptr<std::vector<double>>(rhs.double_array_);
145  else if (rhs.is_string_type ())
146  new (&str_value_) std::shared_ptr<std::string>(rhs.str_value_);
147  else if (rhs.is_binary_file_type ())
148  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(rhs.file_value_);
149 }
150 
152  knowledge::KnowledgeRecord &&rhs) noexcept
153 : logger_ (std::move(rhs.logger_)),
154  clock (rhs.clock),
155  quality (rhs.quality),
157  type_ (rhs.type_),
158  shared_ (rhs.shared_)
159 {
160  if (rhs.type_ == EMPTY)
161  return;
162 
163  if (rhs.type_ == INTEGER)
164  int_value_ = rhs.int_value_;
165  else if (rhs.type_ == INTEGER_ARRAY)
166  new (&int_array_) std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
167  else if (rhs.type_ == DOUBLE)
168  double_value_ = rhs.double_value_;
169  else if (rhs.type_ == DOUBLE_ARRAY)
170  new (&double_array_) std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
171  else if (rhs.is_string_type ())
172  new (&str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
173  else if (rhs.is_binary_file_type ())
174  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
175 }
176 
178 {
179  clear_union();
180 }
181 
182 inline KnowledgeRecord &
184 {
185  if (this == &rhs)
186  return *this;
187 
188  // clear any dynamic memory being used on the left hand side
189  clear_value ();
190 
191  if (rhs.type_ == EMPTY)
192  return *this;
193 
194  // set the instance properties accordingly
195  clock = rhs.clock;
196  quality = rhs.quality;
198  type_ = rhs.type_;
200 
201  if (rhs.type_ == INTEGER)
202  int_value_ = rhs.int_value_;
203  else if (rhs.type_ == INTEGER_ARRAY)
204  new (&int_array_) std::shared_ptr<std::vector<Integer>>(rhs.int_array_);
205  else if (rhs.type_ == DOUBLE)
207  else if (rhs.type_ == DOUBLE_ARRAY)
208  new (&double_array_) std::shared_ptr<std::vector<double>>(rhs.double_array_);
209  else if (rhs.is_string_type ())
210  new (&str_value_) std::shared_ptr<std::string>(rhs.str_value_);
211  else if (rhs.is_binary_file_type ())
212  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(rhs.file_value_);
213 
214  return *this;
215 }
216 
217 inline KnowledgeRecord &
219 {
220  if (this == &rhs)
221  return *this;
222 
223  // clear any dynamic memory being used on the left hand side
224  clear_union();
225 
226  if (rhs.type_ == EMPTY)
227  return *this;
228 
229  // set the instance properties accordingly
230  clock = rhs.clock;
231  quality = rhs.quality;
232  write_quality = rhs.write_quality;
233  type_ = rhs.type_;
234  shared_ = rhs.shared_;
235 
236  if (rhs.type_ == INTEGER)
237  int_value_ = rhs.int_value_;
238  else if (rhs.type_ == INTEGER_ARRAY)
239  new (&int_array_) std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
240  else if (rhs.type_ == DOUBLE)
241  double_value_ = rhs.double_value_;
242  else if (rhs.type_ == DOUBLE_ARRAY)
243  new (&double_array_) std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
244  else if (rhs.is_string_type ())
245  new (&str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
246  else if (rhs.is_binary_file_type ())
247  new (&file_value_) std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
248 
249  return *this;
250 }
251 
252 template<typename T,
253  typename std::enable_if<std::is_integral<T>::value, void*>::type>
254 inline bool
256 {
257  // for this type of comparison, we can only be equal if we are the same
258  // base type
259  if (is_integer_type ())
260  {
261  return to_integer () == value;
262  }
263  else if (is_double_type () || is_string_type ())
264  {
265  return to_double () == value;
266  }
267 
268  return false;
269 }
270 
271 template<typename T,
272  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
273 inline bool
274 KnowledgeRecord::operator== (T value) const
275 {
276  // for this type of comparison, we can only be equal if we are the same
277  // base type
278  if (is_integer_type ())
279  {
280  return to_integer () == value;
281  }
282  else if (is_double_type () || is_string_type ())
283  {
284  return to_double () == value;
285  }
286 
287  return false;
288 }
289 
290 inline bool
292  const std::string & value) const
293 {
294  return to_string () == value;
295 }
296 
297 inline bool
298 KnowledgeRecord::operator== (const char * value) const
299 {
300  return to_string ().compare (value) == 0;
301 }
302 
303 inline bool
305 {
306  return !(*this == rhs);
307 }
308 
312 inline bool
314 {
315  return !is_true ();
316 }
317 
321 inline KnowledgeRecord
323 {
324  KnowledgeRecord record (*this);
325 
326  if (is_integer_type ())
327  record.set_value (-to_integer ());
328  else if (is_double_type ())
329  record.set_value (-to_double ());
330 
331  return record;
332 }
333 
337 inline KnowledgeRecord &
339 {
340  if (is_integer_type ())
341  {
342  if (rhs.is_integer_type ())
343  set_value (to_integer () + rhs.to_integer ());
344  else
345  set_value (to_integer () + rhs.to_double ());
346  }
347  else if (is_double_type ())
348  set_value (to_double () + rhs.to_double ());
349 
350  else if (is_string_type ())
351  set_value (to_string () + rhs.to_string ());
352 
353  return *this;
354 }
355 
359 inline KnowledgeRecord &
361 {
362  if (is_integer_type ())
363  set_value (to_integer () - 1);
364 
365  else if (is_double_type ())
366  set_value (to_double () - 1);
367 
368  return *this;
369 }
370 
374 inline KnowledgeRecord &
376 {
377  if (is_integer_type ())
378  set_value (to_integer () + 1);
379 
380  else if (is_double_type ())
381  set_value (to_double () + 1);
382 
383 
384  return *this;
385 }
386 
390 inline KnowledgeRecord &
392 {
393  if (is_integer_type ())
394  {
395  if (rhs.is_integer_type ())
396  set_value (to_integer () - rhs.to_integer ());
397  else
398  set_value (to_integer () - rhs.to_double ());
399  }
400  else if (is_double_type () || is_string_type ())
401  set_value (to_double () - rhs.to_double ());
402 
403  return *this;
404 }
405 
409 inline KnowledgeRecord &
411 {
412  if (is_integer_type ())
413  {
414  if (rhs.is_integer_type ())
415  set_value (to_integer () * rhs.to_integer ());
416  else
417  set_value (to_integer () * rhs.to_double ());
418  }
419  else if (is_double_type () || is_string_type ())
420  set_value (to_double () * rhs.to_double ());
421 
422  return *this;
423 }
424 
428 inline KnowledgeRecord &
430 {
431  if (is_integer_type ())
432  {
433  if (rhs.is_integer_type ())
434  {
435  Integer denom = rhs.to_integer ();
436  if (denom == 0)
437  set_value ("Division by Zero");
438  else
439  set_value (to_integer () / denom);
440  }
441  else
442  {
443  double denom = rhs.to_double ();
444 
445  if (denom == 0)
446  set_value ("Division by Zero");
447  else
448  set_value (to_integer () / denom);
449  }
450  }
451  else if (is_double_type () || is_string_type ())
452  {
453  double denom = rhs.to_double ();
454 
455  if (denom == 0)
456  set_value ("Division by Zero");
457  else
458  set_value (to_double () / denom);
459  }
460 
461  return *this;
462 }
463 
467 inline KnowledgeRecord &
469 {
470  if (is_integer_type ())
471  {
472  if (rhs.is_integer_type ())
473  {
474  Integer denom = rhs.to_integer ();
475  if (denom == 0)
476  set_value ("Division by Zero");
477  else
478  set_value (to_integer () % denom);
479  }
480  }
481 
482  return *this;
483 }
484 
488 inline KnowledgeRecord
490 {
491  // copy this value to a local copy
492  knowledge::KnowledgeRecord ret_value (*this);
493 
494  return ret_value *= rhs;
495 }
496 
500 inline KnowledgeRecord
502 {
503  // copy this value to a local copy
504  knowledge::KnowledgeRecord ret_value (*this);
505 
506  return ret_value /= rhs;
507 }
508 
512 inline KnowledgeRecord
514 {
515  // copy this value to a local copy
516  knowledge::KnowledgeRecord ret_value (*this);
517 
518  return ret_value %= rhs;
519 }
520 
524 inline KnowledgeRecord
526 {
527  // copy this value to a local copy
528  knowledge::KnowledgeRecord ret_value (*this);
529 
530  return ret_value += rhs;
531 }
532 
533 inline bool
535 {
536  return !is_true ();
537 }
538 
542 inline std::ostream & operator<< (std::ostream & stream,
543  const KnowledgeRecord & rhs)
544 {
545  if (rhs.type () &
548  {
549  stream << rhs.to_string (", ");
550  }
551  else
552  stream << rhs.to_string ();
553 
554  return stream;
555 }
556 
560 inline KnowledgeRecord
562 {
563  // copy this value to a local copy
564  knowledge::KnowledgeRecord ret_value (*this);
565 
566  return ret_value -= rhs;
567 }
568 
569 inline void
571 {
572  if (shared_ != SHARED) {
573  return;
574  }
575 
576  if (is_ref_counted ())
577  {
578  if (is_string_type()) {
580  } else if (is_binary_file_type()) {
582  } else if (type_ == INTEGER_ARRAY) {
584  } else if (type_ == DOUBLE_ARRAY) {
586  }
587  }
588  shared_ = OWNED;
589 }
590 
591 inline KnowledgeRecord *
593 {
595 
596  result->unshare();
597 
598  return result;
599 }
600 
601 inline void
603 {
604  *this = source;
605  unshare();
606 }
607 
608 inline KnowledgeRecord
610 {
611  KnowledgeRecord ret (*this);
612  ret.unshare();
613  return ret;
614 }
615 
616 inline bool
618 {
619  return type_ != EMPTY;
620 }
621 
622 inline int
624 {
625  return type_ == EMPTY ? UNCREATED : MODIFIED;
626 }
627 
631 inline void
633 {
634  if (!exists()) {
635  set_value ((Integer)0);
636  }
637 }
638 
639 inline uint32_t
641 {
642  if (type_ == INTEGER || type_ == DOUBLE) {
643  return 1;
644  } else if (is_string_type()) {
645  return str_value_->size () + 1;
646  } else if (is_binary_file_type()) {
647  return file_value_->size ();
648  } else if (type_ == INTEGER_ARRAY) {
649  return int_array_->size ();
650  } else if (type_ == DOUBLE_ARRAY) {
651  return double_array_->size ();
652  }
653  return 1;
654 }
655 
656 inline int32_t
658 {
659  return type_;
660 }
661 
662 inline bool
664 {
665  if ((uint32_t)type == type_ ||
666  (is_string_type() && is_string_type(type)) ||
668  ) {
669  type_ = type;
670  return true;
671  }
672  return false;
673 }
674 
675 inline int64_t
677 {
678  int64_t buffer_size (sizeof (uint32_t) * 2);
679  if (type_ == INTEGER)
680  {
681  buffer_size += sizeof (Integer);
682  }
683  else if (type_ == DOUBLE)
684  {
685  buffer_size += sizeof (double);
686  }
687  else if (type_ == INTEGER_ARRAY)
688  {
689  buffer_size += sizeof (Integer) * double_array_->size();
690  }
691  else if (type_ == DOUBLE_ARRAY)
692  {
693  buffer_size += sizeof (double) * double_array_->size();
694  }
695  else if (is_string_type ())
696  {
697  buffer_size += str_value_->size () + 1;
698  }
699  else if (is_binary_file_type ())
700  {
701  buffer_size += file_value_->size ();
702  }
703 
704  return buffer_size;
705 }
706 
707 inline int64_t
709 {
710  // for keyed size, add another uint32_t and the size of the key with a null char
711  int64_t buffer_size (sizeof (uint32_t) * 1);
712  buffer_size += (key.size () + 1);
713 
714  // and then add the default encoded size
715  buffer_size += get_encoded_size ();
716 
717  return buffer_size;
718 }
719 
720 inline bool
722 {
723  return is_ref_counted (type_);
724 }
725 
726 inline bool
728 {
729  return type != INTEGER && type != DOUBLE;
730 }
731 
732 inline bool
734 {
735  return is_string_type (type_);
736 }
737 
738 inline bool
740 {
741  return type == STRING || type == XML || type == TEXT_FILE;
742 }
743 
744 inline bool
746 {
747  return is_double_type (type_);
748 }
749 
750 inline bool
752 {
753  return type == DOUBLE || type == DOUBLE_ARRAY;
754 }
755 
756 inline bool
758 {
759  return is_integer_type (type_);
760 }
761 
762 
763 inline bool
765 {
766  return type == EMPTY || type == INTEGER || type == INTEGER_ARRAY;
767 }
768 
769 inline bool
771 {
772  return is_array_type (type_);
773 }
774 
775 inline bool
777 {
778  return type & ALL_ARRAYS;
779 }
780 
781 inline bool
783 {
784  return is_image_type (type_);
785 }
786 
787 inline bool
789 {
790  return type == IMAGE_JPEG;
791 }
792 
793 inline bool
795 {
796  return is_file_type (type_);
797 }
798 
799 inline bool
801 {
802  return type == TEXT_FILE || type == XML ||
803  type == IMAGE_JPEG || type == UNKNOWN_FILE_TYPE;
804 }
805 
806 inline bool
808 {
809  return is_binary_file_type (type_);
810 }
811 
812 inline bool
814 {
815  return type == IMAGE_JPEG || type == UNKNOWN_FILE_TYPE;
816 }
817 
818 inline uint32_t
820 {
821  uint32_t max = 0;
822 
823  // iterate over the list and return the max
824  for (KnowledgeRecords::const_iterator i = records.begin ();
825  i != records.end (); ++i)
826  {
827  max = std::max <uint32_t> (i->second->quality, max);
828  }
829  return max;
830 }
831 
832 inline uint32_t
833 max_quality (const KnowledgeMap & records)
834 {
835  uint32_t max = 0;
836 
837  // iterate over the list and return the max
838  for (KnowledgeMap::const_iterator i = records.begin ();
839  i != records.end (); ++i)
840  {
841  max = std::max <uint32_t> (i->second.quality, max);
842  }
843  return max;
844 }
845 
846 template<typename T>
847 inline void destruct(T &x) {
848  x.~T();
849 }
850 
851 inline void
853 {
854  if (type_ & ALL_CLEARABLES)
855  {
856  if (type_ == INTEGER_ARRAY)
858  else if (type_ == DOUBLE_ARRAY)
860  else if (is_string_type ())
862  else if (is_binary_file_type ())
864  shared_ = OWNED;
865  }
866 }
867 
868 inline void
870 {
871  clear_union ();
872 
873  type_ = EMPTY;
874 }
875 
876 inline const char *
877 KnowledgeRecord::read (const char * buffer,
878  int64_t & buffer_remaining)
879 {
880  // format is [key_size | key | type | value_size | value]
881 
882  uint32_t buff_value_size (0);
883  decltype(type_) type = INTEGER;
884  uint32_t size = 1;
885 
886  // Remove the type of value from the buffer
887  if (buffer_remaining >= (int64_t) sizeof (type))
888  {
889  memcpy (&type, buffer, sizeof (type));
891  buffer += sizeof (type);
892  }
893  buffer_remaining -= sizeof (type);
894 
895  // Remove the size of value from the buffer
896  if (buffer_remaining >= (int64_t) sizeof (size))
897  {
898  memcpy (&size, buffer, sizeof (size));
899  size = madara::utility::endian_swap (size);
900 
901  if (is_integer_type (type))
902  buff_value_size = size * sizeof (Integer);
903  else if (is_double_type (type))
904  buff_value_size = size * sizeof (double);
905  else
906  buff_value_size = size;
907 
908  buffer += sizeof (buff_value_size);
909  } else {
910  buffer_remaining = -1;
911  return buffer;
912  }
913  buffer_remaining -= sizeof (buff_value_size);
914 
915  // Remove the value from the buffer
916  if (buffer_remaining >= int64_t (buff_value_size))
917  {
918  if (is_string_type (type))
919  {
920  if (buff_value_size >= 1) {
921  emplace_string (buffer, buff_value_size - 1);
922  } else {
923  emplace_string ();
924  }
925  }
926 
927  else if (type == INTEGER)
928  {
929  Integer tmp;
930  memcpy (&tmp, buffer, sizeof (tmp));
932  }
933 
934  else if (type == INTEGER_ARRAY)
935  {
936  std::vector<Integer> tmp;
937  tmp.reserve(size);
938 
939  for (uint32_t i = 0; i < size; ++i)
940  {
941  Integer cur;
942  memcpy (&cur, buffer + i * sizeof(cur), sizeof(cur));
943  tmp.emplace_back(madara::utility::endian_swap (cur));
944  }
945 
946  emplace_integers (std::move(tmp));
947  }
948 
949  else if (type == DOUBLE)
950  {
951  double tmp;
952  memcpy (&tmp, buffer, sizeof (tmp));
954  }
955 
956  else if (type == DOUBLE_ARRAY)
957  {
958  std::vector<double> tmp;
959  tmp.reserve(size);
960 
961  for (uint32_t i = 0; i < size; ++i)
962  {
963  double cur;
964  memcpy (&cur, buffer + i * sizeof(cur), sizeof(cur));
965  tmp.emplace_back(madara::utility::endian_swap (cur));
966  }
967 
968  emplace_doubles (std::move(tmp));
969  }
970 
971  else if (is_binary_file_type (type))
972  {
973  const unsigned char *b = (const unsigned char *)buffer;
974  emplace_file (b, b + size);
975  }
976 
977  else {
978  buffer_remaining = -1;
979  return buffer;
980  }
981 
982  buffer += buff_value_size;
983  buffer_remaining -= sizeof (char) * buff_value_size;
984 
985  type_ = type;
986  }
987 
988  return buffer;
989 }
990 
991 inline const char *
992 KnowledgeRecord::read (const char * buffer, std::string & key,
993 int64_t & buffer_remaining)
994 {
995  // format is [key_size | key | type | value_size | value]
996 
997  uint32_t key_size (0);
998 
999  // Remove the key size from the buffer
1000  if (buffer_remaining >= (int64_t) sizeof (key_size))
1001  {
1002  memcpy (&key_size, buffer, sizeof (key_size));
1003  key_size = madara::utility::endian_swap (key_size);
1004  buffer += sizeof (key_size);
1005  }
1006  buffer_remaining -= sizeof (key_size);
1007 
1008  // Remove the key from the buffer
1009  if (buffer_remaining >= int64_t (sizeof (char) * int64_t (key_size)))
1010  {
1011  if (key_size > 0) {
1012  // don't worry about null terminator
1013  key.assign (buffer, key_size - 1);
1014  } else {
1015  key.clear ();
1016  }
1017 
1018  buffer += sizeof (char) * key_size;
1019  }
1020  buffer_remaining -= sizeof (char) * int64_t (key_size);
1021 
1022  // read the type and data
1023  buffer = read (buffer, buffer_remaining);
1024 
1025  return buffer;
1026 }
1027 
1028 inline const char *
1029 KnowledgeRecord::read (const char * buffer, uint32_t & key_id,
1030 int64_t & buffer_remaining)
1031 {
1032  // format is [key_id | type | value_size | value]
1033 
1034  // Remove the key size from the buffer
1035  if (buffer_remaining >= (int64_t) sizeof (key_id))
1036  {
1037  memcpy (&key_id, buffer, sizeof (key_id));
1038  key_id = madara::utility::endian_swap (key_id);
1039  buffer += sizeof (key_id);
1040  buffer_remaining -= sizeof (key_id);
1041 
1042  // read the type and data
1043  buffer = read (buffer, buffer_remaining);
1044  }
1045 
1046  return buffer;
1047 }
1048 
1049 // reset the value_ to an integer
1050 inline void
1052 {
1053  clear_value ();
1054 
1055  quality = 0;
1056  write_quality = 0;
1057  clock = 0;
1058 }
1059 
1060 inline void
1062 {
1063  uint64_t clock = this->clock;
1064  uint64_t quality = this->write_quality;
1065  uint64_t write_quality = this->write_quality;
1066  *this = new_value;
1067  this->clock = clock;
1068  this->quality = quality;
1069  this->write_quality = write_quality;
1070 }
1071 
1072 inline void
1074 {
1075  uint64_t clock = this->clock;
1076  uint64_t quality = this->write_quality;
1077  uint64_t write_quality = this->write_quality;
1078  *this = std::move(new_value);
1079  this->clock = clock;
1080  this->quality = quality;
1081  this->write_quality = write_quality;
1082 }
1083 
1084 // set the value_ to a string
1085 inline void
1087 {
1088  emplace_string (std::move(new_value));
1089  type_ = STRING;
1090 }
1091 
1092 // set the value_ to a string
1093 inline void
1095 {
1096  emplace_string (new_value);
1097  type_ = STRING;
1098 }
1099 
1100 // set the value_ to a string
1101 inline void
1102 KnowledgeRecord::set_value (std::shared_ptr<std::string> new_value)
1103 {
1104  emplace_shared_string (std::move(new_value));
1105  type_ = STRING;
1106 }
1107 
1108 // set the value_ to a string
1109 inline void
1110 KnowledgeRecord::set_value (const char * new_value, uint32_t size)
1111 {
1112  emplace_string (new_value, size);
1113  type_ = STRING;
1114 }
1115 
1116 // set the value_ to a string
1117 inline void
1118 KnowledgeRecord::set_xml (const char * new_value, size_t size)
1119 {
1120  emplace_string (new_value, size);
1121  type_ = XML;
1122 }
1123 
1124 // set the value_ to a string
1125 inline void
1127 {
1128  emplace_string (std::move(new_value));
1129  type_ = XML;
1130 }
1131 
1132 // set the value_ to a string
1133 inline void
1135 {
1136  emplace_string (new_value);
1137  type_ = XML;
1138 }
1139 
1140 // set the value_ to a string
1141 inline void
1142 KnowledgeRecord::set_xml (std::shared_ptr<std::string> new_value)
1143 {
1144  emplace_shared_string (std::move(new_value));
1145  type_ = XML;
1146 }
1147 
1148 // set the value_ to a string
1149 inline void
1150 KnowledgeRecord::set_text (const char * new_value, size_t size)
1151 {
1152  emplace_string (new_value, size);
1153  type_ = TEXT_FILE;
1154 }
1155 
1156 // set the value_ to a string
1157 inline void
1159 {
1160  emplace_string (std::move(new_value));
1161  type_ = TEXT_FILE;
1162 }
1163 
1164 // set the value_ to a string
1165 inline void
1167 {
1168  emplace_string (new_value);
1169  type_ = TEXT_FILE;
1170 }
1171 
1172 // set the value_ to a string
1173 inline void
1174 KnowledgeRecord::set_text (std::shared_ptr<std::string> new_value)
1175 {
1176  emplace_shared_string (std::move(new_value));
1177  type_ = TEXT_FILE;
1178 }
1179 
1180 // set the value_ to a string
1181 inline void
1182 KnowledgeRecord::set_jpeg (const unsigned char * new_value,
1183  size_t size)
1184 {
1185  emplace_file (new_value, new_value + size);
1186  type_ = IMAGE_JPEG;
1187 }
1188 
1189 inline void
1190 KnowledgeRecord::set_jpeg (std::vector <unsigned char> && new_value)
1191 {
1192  emplace_file (std::move(new_value));
1193  type_ = IMAGE_JPEG;
1194 }
1195 
1196 inline void
1197 KnowledgeRecord::set_jpeg (const std::vector <unsigned char> & new_value)
1198 {
1199  emplace_file (new_value);
1200  type_ = IMAGE_JPEG;
1201 }
1202 
1203 inline void
1205  std::shared_ptr<std::vector <unsigned char>> new_value)
1206 {
1207  emplace_shared_file (std::move(new_value));
1208  type_ = IMAGE_JPEG;
1209 }
1210 
1211 // set the value_ to a string
1212 inline void
1213 KnowledgeRecord::set_file (const unsigned char * new_value,
1214  size_t size)
1215 {
1216  emplace_file (new_value, new_value + size);
1218 }
1219 
1220 inline void
1221 KnowledgeRecord::set_file (std::vector <unsigned char> && new_value)
1222 {
1223  emplace_file (std::move(new_value));
1225 }
1226 
1227 inline void
1228 KnowledgeRecord::set_file (const std::vector <unsigned char> & new_value)
1229 {
1230  emplace_file (new_value);
1232 }
1233 
1234 inline void
1236  std::shared_ptr<std::vector <unsigned char>> new_value)
1237 {
1238  emplace_shared_file (std::move(new_value));
1240 }
1241 
1242 // set the value_ to an integer
1243 template<typename T,
1244  typename std::enable_if<std::is_integral<T>::value, void*>::type>
1245 inline void
1247 {
1248  if (type_ != INTEGER) {
1249  clear_union();
1250  type_ = INTEGER;
1251  }
1252  int_value_ = new_value;
1253 }
1254 
1255 // set the value_ to an array of doubles
1256 inline void
1257 KnowledgeRecord::set_value (const Integer * new_value, uint32_t size)
1258 {
1259  emplace_integers (new_value, new_value + size);
1260 }
1261 
1262 // set the value_ to an array of integers
1263 inline void
1264 KnowledgeRecord::set_value (std::vector <Integer> && new_value)
1265 {
1266  emplace_integers (std::move(new_value));
1267 }
1268 
1269 // set the value_ to an array of integers
1270 inline void
1271 KnowledgeRecord::set_value (const std::vector <Integer> & new_value)
1272 {
1273  emplace_integers (new_value);
1274 }
1275 
1276 // set the value_ to an array of integers
1277 inline void
1278 KnowledgeRecord::set_value (std::shared_ptr<std::vector <Integer>> new_value)
1279 {
1280  emplace_shared_integers (std::move(new_value));
1281 }
1282 
1283 // set the value_ to a double
1284 template<typename T,
1285  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
1286 inline void
1287 KnowledgeRecord::set_value (T new_value)
1288 {
1289  if (type_ != DOUBLE) {
1290  clear_union();
1291  type_ = DOUBLE;
1292  }
1293  double_value_ = new_value;
1294 }
1295 
1296 // set the value_ to an array of doubles
1297 inline void
1298 KnowledgeRecord::set_value (const double * new_value, uint32_t size)
1299 {
1300  emplace_doubles (new_value, new_value + size);
1301 }
1302 
1303 // set the value_ to an array of doubles
1304 inline void
1305 KnowledgeRecord::set_value (std::vector <double> && new_value)
1306 {
1307  emplace_doubles (std::move(new_value));
1308 }
1309 
1310 // set the value_ to an array of doubles
1311 inline void
1312 KnowledgeRecord::set_value (const std::vector <double> & new_value)
1313 {
1314  emplace_doubles (new_value);
1315 }
1316 
1317 // set the value_ to an array of doubles
1318 inline void
1319 KnowledgeRecord::set_value (std::shared_ptr<std::vector <double>> new_value)
1320 {
1321  emplace_shared_doubles (std::move(new_value));
1322 }
1323 
1329 template<typename T,
1330  typename std::enable_if<std::is_integral<T>::value, void*>::type>
1331 inline void
1332 KnowledgeRecord::set_index (size_t index, T value)
1333 {
1334  if (type_ == DOUBLE_ARRAY)
1335  {
1336  // let the set_index for doubles take care of this
1337  set_index (index, double (value));
1338  return;
1339  }
1340  else if (type_ == INTEGER_ARRAY)
1341  {
1342  unshare();
1343 
1344  if (index >= int_array_->size ())
1345  {
1346  int_array_->resize(index + 1);
1347  }
1348  }
1349  else
1350  {
1351  emplace_integers (index + 1);
1352  }
1353 
1354  int_array_->at (index) = value;
1355 }
1356 
1362 template<typename T,
1363  typename std::enable_if<std::is_floating_point<T>::value, void*>::type>
1364 inline void
1365 KnowledgeRecord::set_index (size_t index, T value)
1366 {
1367  if (type_ == INTEGER_ARRAY)
1368  {
1369  std::vector<double> tmp (int_array_->begin (), int_array_->end ());
1370  emplace_doubles (std::move(tmp));
1371  }
1372  else if (type_ != DOUBLE_ARRAY)
1373  {
1374  emplace_doubles (index + 1);
1375  }
1376  else
1377  {
1378  unshare();
1379 
1380  if (index >= double_array_->size ())
1381  {
1382  double_array_->resize (index + 1);
1383  }
1384  }
1385 
1386  double_array_->at (index) = value;
1387 }
1388 
1389 inline std::shared_ptr<std::string>
1391 {
1392  if (is_string_type()) {
1393  shared_ = SHARED;
1394  return str_value_;
1395  }
1396  return nullptr;
1397 }
1398 
1399 inline std::shared_ptr<std::string>
1401 {
1402  if (is_string_type()) {
1403  std::shared_ptr<std::string> ret;
1404 
1405  using std::swap;
1406  swap(ret, str_value_);
1407 
1408  reset_value();
1409 
1410  return ret;
1411  }
1412  return nullptr;
1413 }
1414 
1415 inline std::shared_ptr<std::vector<KnowledgeRecord::Integer>>
1417 {
1418  if (type_ == INTEGER_ARRAY) {
1419  shared_ = SHARED;
1420  return int_array_;
1421  }
1422  return nullptr;
1423 }
1424 
1425 inline std::shared_ptr<std::vector<KnowledgeRecord::Integer>>
1427 {
1428  if (type_ == INTEGER_ARRAY) {
1429  std::shared_ptr<std::vector<Integer>> ret;
1430 
1431  using std::swap;
1432  swap(ret, int_array_);
1433 
1434  reset_value();
1435 
1436  return ret;
1437  }
1438  return nullptr;
1439 }
1440 
1441 inline std::shared_ptr<std::vector<double>>
1443 {
1444  if (type_ == DOUBLE_ARRAY) {
1445  shared_ = SHARED;
1446  return double_array_;
1447  }
1448  return nullptr;
1449 }
1450 
1451 inline std::shared_ptr<std::vector<double>>
1453 {
1454  if (type_ == DOUBLE_ARRAY) {
1455  std::shared_ptr<std::vector<double>> ret;
1456 
1457  using std::swap;
1458  swap(ret, double_array_);
1459 
1460  reset_value();
1461 
1462  return ret;
1463  }
1464  return nullptr;
1465 }
1466 
1467 inline std::shared_ptr<std::vector<unsigned char>>
1469 {
1470  if (is_binary_file_type()) {
1471  shared_ = SHARED;
1472  return file_value_;
1473  }
1474  return nullptr;
1475 }
1476 
1477 inline std::shared_ptr<std::vector<unsigned char>>
1479 {
1480  if (is_binary_file_type()) {
1481  std::shared_ptr<std::vector<unsigned char>> ret;
1482 
1483  using std::swap;
1484  swap(ret, file_value_);
1485 
1486  reset_value();
1487 
1488  return ret;
1489  }
1490  return nullptr;
1491 }
1492 
1493 inline
1494 KnowledgeRecord::operator bool (void) const
1495 {
1496  return is_true();
1497 }
1498 
1499 inline char *
1500 KnowledgeRecord::write (char * buffer,
1501  int64_t & buffer_remaining) const
1502 {
1503  // format is [type | value_size | value]
1504 
1505  char * size_location = 0;
1506  uint32_t size_intermediate = 0;
1507  uint32_t uint32_temp;
1508  Integer integer_temp;
1509  double double_temp;
1510  uint32_t size = this->size ();
1511 
1512  int64_t encoded_size = get_encoded_size ();
1513 
1514  if (buffer_remaining >= encoded_size)
1515  {
1516  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1517  " encoding %" PRId64 " byte message\n", encoded_size);
1518 
1519  // Remove the type of value from the buffer
1520  if (buffer_remaining >= (int64_t) sizeof (type_))
1521  {
1522  decltype(type_) tmp = madara::utility::endian_swap (type_);
1523  memcpy (buffer, &tmp, sizeof (tmp));
1524  buffer += sizeof (tmp);
1525  }
1526  buffer_remaining -= sizeof (type_);
1527 
1528  // Remove the size of value from the buffer
1529  if (buffer_remaining >= (int64_t) sizeof (size))
1530  {
1531  // set a pointer to size, in case we need to modify it during
1532  // value copy (e.g. during double conversion)
1533  size_location = buffer;
1534  size_intermediate = size;
1535 
1536  uint32_temp = madara::utility::endian_swap (size);
1537  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1538 
1539  // note that we do not encode the size yet because it may change
1540  // and we need the architectural-specific version for other checks
1541 
1542  buffer += sizeof (size);
1543  }
1544  buffer_remaining -= sizeof (size);
1545 
1546  // Remove the value from the buffer
1547  if (is_string_type ())
1548  {
1549  // strings do not have to be converted
1550  if (buffer_remaining >= int64_t (size))
1551  {
1552  memcpy (buffer, &(*str_value_)[0], size);
1553  }
1554  }
1555  else if (type_ == INTEGER)
1556  {
1557  if (buffer_remaining >= int64_t (sizeof (Integer)))
1558  {
1559  integer_temp = madara::utility::endian_swap (int_value_);
1560  memcpy (buffer, &integer_temp, sizeof (integer_temp));
1561 
1562  size_intermediate = sizeof (Integer);
1563  }
1564  }
1565  else if (type_ == INTEGER_ARRAY)
1566  {
1567  if (buffer_remaining >= int64_t (size * sizeof (Integer)))
1568  {
1569  // convert integers to network byte order
1570  const Integer * ptr_temp = &(*int_array_)[0];
1571  Integer * target_buffer = (Integer *)buffer;
1572 
1573  for (uint32_t i = 0; i < size; ++i, ++ptr_temp, ++target_buffer)
1574  {
1575  integer_temp = madara::utility::endian_swap (*ptr_temp);
1576  memcpy (target_buffer, &integer_temp, sizeof (Integer));
1577  }
1578 
1579  size_intermediate = size * sizeof (Integer);
1580  }
1581  }
1582  else if (type_ == DOUBLE)
1583  {
1584  if (buffer_remaining >= int64_t (sizeof (double)))
1585  {
1587  memcpy (buffer, &double_temp, sizeof (double));
1588 
1589  size_intermediate = sizeof (double);
1590  }
1591  }
1592  else if (type_ == DOUBLE_ARRAY)
1593  {
1594  if (buffer_remaining >= int64_t (size * sizeof (double)))
1595  {
1596  // convert integers to network byte order
1597  const double * ptr_temp = &(*double_array_)[0];
1598  double * target_buffer = (double *)buffer;
1599 
1600  for (uint32_t i = 0; i < size; ++i, ++ptr_temp, ++target_buffer)
1601  {
1602  double_temp = madara::utility::endian_swap (*ptr_temp);
1603  memcpy (target_buffer, &double_temp, sizeof (double_temp));
1604  }
1605 
1606  size_intermediate = size * sizeof (double);
1607 
1618  }
1619  }
1620  else if (is_binary_file_type ())
1621  {
1622  // strings do not have to be converted
1623  if (buffer_remaining >= size)
1624  {
1625  memcpy (buffer, &(*file_value_)[0], size);
1626  }
1627  }
1628 
1629  if (size_location)
1630  {
1631  buffer_remaining -= size_intermediate;
1632  buffer += size_intermediate;
1633  }
1634  }
1635  else
1636  {
1637  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1638  " %" PRId64 " byte buffer cannot contain %" PRId64 " byte message\n",
1639  buffer_remaining, encoded_size);
1640  }
1641  return buffer;
1642 }
1643 
1644 inline char *
1645 KnowledgeRecord::write (char * buffer, const std::string & key,
1646 int64_t & buffer_remaining) const
1647 
1648 {
1649  // format is [key_size | key | type | value_size | value]
1650 
1651  uint32_t key_size = uint32_t (key.size () + 1);
1652  uint32_t uint32_temp;
1653 
1654  int64_t encoded_size = get_encoded_size (key);
1655 
1656  if (buffer_remaining >= encoded_size)
1657  {
1658  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1659  " encoding %" PRId64 " byte message\n", encoded_size);
1660 
1661  // Remove the key size from the buffer
1662  if (buffer_remaining >= (int64_t) sizeof (key_size))
1663  {
1664  uint32_temp = madara::utility::endian_swap (key_size);
1665  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1666  buffer += sizeof (key_size);
1667  }
1668  buffer_remaining -= sizeof (key_size);
1669 
1670  // Remove the key from the buffer
1671  if (buffer_remaining >= (int64_t) sizeof (char) * key_size)
1672  {
1673  // copy the string and set null terminator in buffer
1674  strncpy (buffer, key.c_str (), key_size - 1);
1675  buffer[key_size - 1] = 0;
1676 
1677  buffer += sizeof (char) * key_size;
1678  }
1679  buffer_remaining -= sizeof (char) * key_size;
1680 
1681  // write the type and value of the record
1682  buffer = write (buffer, buffer_remaining);
1683  }
1684  else
1685  {
1686  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1687  " %" PRId64 " byte buffer cannot contain %" PRId64 " byte message\n",
1688  buffer_remaining, encoded_size);
1689  }
1690  return buffer;
1691 }
1692 
1693 inline char *
1694 KnowledgeRecord::write (char * buffer, uint32_t key_id,
1695  int64_t & buffer_remaining) const
1696 {
1697  // format is [key_id | type | value_size | value]
1698 
1699  uint32_t uint32_temp;
1700 
1701  int64_t encoded_size = get_encoded_size () + sizeof (key_id);
1702 
1703  if (buffer_remaining >= encoded_size)
1704  {
1705  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1706  " encoding %" PRId64 " byte message\n", encoded_size);
1707 
1708  // write the key id to the buffer
1709  if (buffer_remaining >= (int64_t)sizeof (key_id))
1710  {
1711  uint32_temp = madara::utility::endian_swap (key_id);
1712  memcpy (buffer, &uint32_temp, sizeof (uint32_temp));
1713  buffer += sizeof (key_id);
1714  }
1715  buffer_remaining -= sizeof (key_id);
1716 
1717  // write the type and value of the record
1718  buffer = write (buffer, buffer_remaining);
1719  }
1720  else
1721  {
1722  madara_logger_ptr_log (logger_, logger::LOG_MINOR, "KnowledgeRecord::write:" \
1723  " %" PRId64 " byte buffer cannot contain %" PRId64 " byte message\n",
1724  buffer_remaining, encoded_size);
1725  }
1726  return buffer;
1727 }
1728 
1729 } }
1730 
1731 #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
Returns a shared_ptr, sharing with the internal one.
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
Returns a shared_ptr, sharing with the internal one.
bool is_image_type(void) const
returns true if the knowledge record has an image type
std::shared_ptr< std::string > share_string() const
Returns a shared_ptr, sharing with the internal one.
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
Returns a shared_ptr, sharing with the internal one.
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()
Returns a shared_ptr, while resetting this record to empty.
KnowledgeRecord & operator=(const KnowledgeRecord &rhs)
Assignment.
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.
MADARA_Export uint64_t endian_swap(uint64_t value)
Converts a host format uint64_t into big endian.
Definition: Utility.cpp:625
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()
Returns a shared_ptr, while resetting this record to empty.
::std::map< std::string, KnowledgeRecord > KnowledgeMap
std::shared_ptr< std::vector< double > > double_array_
KnowledgeRecord operator%(const KnowledgeRecord &rhs) const
Modulus operator.
std::shared_ptr< std::vector< Integer > > take_integers()
Returns a shared_ptr, while resetting this record to empty.
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
static constexpr struct madara::knowledge::tags::string_t string
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()
Returns a shared_ptr, while resetting this record to empty.
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_