MADARA  3.2.3
Utility.cpp
Go to the documentation of this file.
1 #include <ctype.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <ios>
5 #include <iostream>
6 #include <sstream>
7 #include <fstream>
8 #include <thread>
9 
11 #include "madara/utility/Utility.h"
13 
15 
16 #include "Utility.h"
17 #include "Timer.h"
18 
19 namespace madara { namespace utility {
20 
23 {
24 #include "madara/Version.h"
25 
26  return version + std::string (" compiled on ") +
27  __DATE__ + " at " + __TIME__;
28 }
29 
30 
31 uint32_t
33 {
34  std::string str_version = get_version ();
35  unsigned char version_buffer[4] = {0,0,0,0};
36  uint32_t * return_value = (uint32_t *) version_buffer;
37  unsigned int major, minor, revision;
38  char version_delimiter;
39 
40  std::stringstream buffer;
41 
42  // copy the stringified version
43  buffer << str_version;
44 
45  // major version
46  buffer >> major;
47 
48  buffer >> version_delimiter;
49 
50  // minor version
51  buffer >> minor;
52 
53  buffer >> version_delimiter;
54 
55  // revision number
56  buffer >> revision;
57 
58  // copy these into the version_buffer
59 
60  version_buffer[1] = (unsigned char)major;
61  version_buffer[2] = (unsigned char)minor;
62  version_buffer[3] = (unsigned char)revision;
63 
64  return *return_value;
65 }
66 
68 to_string_version (uint32_t version)
69 {
70  std::stringstream new_version;
71  unsigned char * version_ptr = (unsigned char *)&version;
72  unsigned int major, minor, revision;
73 
74  major = (unsigned int)version_ptr[1];
75  minor = (unsigned int)version_ptr[2];
76  revision = (unsigned int)version_ptr[3];
77 
78  new_version << major;
79  new_version << '.';
80  new_version << minor;
81  new_version << '.';
82  new_version << revision;
83 
84  return new_version.str ();
85 }
86 
91 {
92  std::string::iterator cur = input.begin ();
93  char prev = 0;
94 
95  for (std::string::iterator eval = cur;
96  eval != input.end (); ++eval)
97  {
98  // if it isn't whitespace, then copy it over immediately
99  if (*eval != ' ' && *eval != '\t' && *eval != '\n' && *eval != '\r')
100  {
101  prev = *cur = *eval;
102  ++cur;
103  }
104  // if it is whitespace, only insert whitespace if the previous char
105  // was non-whitespace
106  else if (prev)
107  {
108  *cur = ' ';
109  prev = 0;
110  ++cur;
111  }
112  }
113 
114  // if the last char is actually whitespace, then move cur back one spot
115  if (cur != input.end ())
116  {
117  --cur;
118  if (*cur != ' ' && *cur != '\t' && *cur != '\n' && *cur != '\r')
119  ++cur;
120  }
121 
122  // erase everything from cur to end of input string
123  if (cur != input.end ())
124  input.erase (cur, input.end ());
125 
126  return input;
127 }
128 
129 
131 std::string &
133 {
134  std::string::iterator cur = input.begin ();
135 
136  for (std::string::iterator eval = cur;
137  eval != input.end (); ++eval)
138  {
139  // if it isn't whitespace, then copy it over immediately
140  if (*eval != ' ' && *eval != '\t' && *eval != '\n' && *eval != '\r')
141  {
142  *cur = *eval;
143  ++cur;
144  }
145  }
146 
147  // erase everything from cur to end of input string
148  if (cur != input.end ())
149  input.erase (cur, input.end ());
150 
151  return input;
152 }
153 
154 
159 std::string &
160 string_remove (std::string & input, char unwanted)
161 {
162  std::string::iterator cur = input.begin ();
163 
164  for (std::string::iterator eval = cur;
165  eval != input.end (); ++eval)
166  {
167  // if it isn't whitespace, then copy it over immediately
168  if (*eval != unwanted)
169  {
170  *cur = *eval;
171  ++cur;
172  }
173  }
174 
175  // erase everything from cur to end of input string
176  if (cur != input.end ())
177  input.erase (cur, input.end ());
178 
179  return input;
180 }
181 
182 size_t
184  const std::string & old_phrase,
185  const std::string & new_phrase,
186  bool replace_all)
187 {
188  // return value
189  size_t replacements = 0;
190 
191  if (old_phrase != "")
192  {
193  for (std::string::size_type i = source.find (old_phrase, 0);
194  i != source.npos; i = source.find (old_phrase, i))
195  {
196  source.replace (i, old_phrase.size (), new_phrase);
197  i += new_phrase.size ();
198 
199  ++replacements;
200 
201  if (!replace_all)
202  break;
203  }
204  }
205 
206  return replacements;
207 }
208 
209 std::string &
211 {
212  std::stringstream source, dest;
213  std::string cur;
214  std::vector <std::string> splitters;
215  splitters.resize (2);
216 
217  splitters[0] = "//";
218 
219  // place the input in the string stream
220  source << input;
221 
222  while (std::getline (source, cur))
223  {
224  std::vector <std::string> tokens;
225  std::vector <std::string> pivots;
226  tokenizer (cur, splitters, tokens, pivots);
227 
228  if (tokens.size ())
229  {
230  dest << tokens[0];
231  dest << "\n";
232  }
233  }
234 
235  input = dest.str ();
236  return input;
237 }
238 
239 
241 void
242 tokenizer (const std::string & input,
243  const ::std::vector< std::string> & splitters,
244  ::std::vector< std::string> & tokens,
245  ::std::vector< std::string> & pivots)
246 {
247  std::string::size_type last = 0;
248  std::string::size_type cur = 0;
249  tokens.clear ();
250  pivots.clear ();
251 
252  for (; cur < input.size (); ++cur)
253  {
254  for (std::string::size_type i = 0; i < splitters.size (); ++i)
255  {
256  // if the splitter string length is greater than zero
257  if (splitters[i].size () > 0)
258  {
259  // if the first char of the splitter string is equal to the char
260  if (input[cur] == splitters[i][0])
261  {
262  std::string::size_type checker = cur;
263  std::string::size_type j = 1;
264  for (++checker;
265  checker < input.size () && j < splitters[i].size () &&
266  input[checker] == splitters[i][j];
267  ++j, ++checker);
268 
269  // we have found a splitter. Tokenize from last to splitter.
270  if (j == splitters[i].size ())
271  {
272  // need to update this to only have as many pivots as tokens - 1
273  pivots.push_back (input.substr (cur, j));
274 
275  if (cur - last >= splitters[i].size () - 1)
276  tokens.push_back (input.substr (last, cur - last));
277  else
278  tokens.push_back ("");
279 
280  // we want last to point to the last valid token begin
281  cur = checker - 1;
282  last = checker;
283  } // if found a splitter
284  } // if first char == splitter first char
285  } // if splitter length >= 1
286  } // for splitters
287 
288  } // for chars
289 
290  if (last != cur)
291  {
292  tokens.push_back (input.substr (last, cur - last));
293  }
294 }
295 
296 // split a key into a corresponding host and port
297 int
299  std::string & host, std::string & port)
300 {
301  // delimiter is either a : or an @
302  std::string::size_type delim = key.rfind (':');
303  delim = delim == key.npos ? key.rfind ('@') : delim;
304 
305  // no delimiter found
306  if (delim == key.npos)
307  {
308  host = key;
309  port = "";
310 
311  return 1;
312  }
313 
314  // otherwise, set the host and port appropriately
315  host = key.substr (0, delim);
316  port = key.substr (delim + 1, key.size () - delim);
317 
318  return 0;
319 }
320 
321 // merge a host and port into a key
322 int
324  const std::string & host, const std::string & port)
325 {
326  if ((const std::string *)&key != &host)
327  key = host;
328 
329  key += ':';
330  key += port;
331 
332  return 0;
333 }
334 
335 // merge a host and ushort port into a key
336 int
338  const std::string & host, unsigned short u_port)
339 {
340  std::stringstream port_stream;
341  port_stream << u_port;
342 
343  return merge_hostport_identifier (key, host, port_stream.str ());
344 }
345 
347 file_to_string (const std::string & filename)
348 {
349  std::string line;
350  std::stringstream buffer;
351 
352  std::ifstream file (filename.c_str ());
353 
354  // if the file was able to open
355  if (file.is_open ())
356  {
357  std::getline (file, line);
358 
359  if (line != "")
360  buffer << line;
361 
362  // while there is still a line left in the file, read that line
363  // into our stringstream buffer
364  while (std::getline (file, line))
365  buffer << "\n" << line;
366  file.close ();
367  }
368  else
369  {
371  "utility::file_to_string:" \
372  " failed to open file: %s\n", filename.c_str());
373  }
374 
375  return buffer.str ();
376 }
377 
378 
380 extract_path (const std::string & name)
381 {
382  std::string::size_type start = 0;
383  for (std::string::size_type i = 0; i < name.size (); ++i)
384  {
385  // check for directory delimiters and update start
386  if (name[i] == '/' || name[i] == '\\')
387  {
388  // if they have supplied a directory with an
389  // ending slash, then use the previous start
390  if (i != name.size () - 1)
391  start = i + 1;
392  }
393  }
394 
395  // return the substring from 0 with start number of elements
396  return name.substr (0, start);
397 }
398 
401 {
402  std::string::size_type start = 0;
403  for (std::string::size_type i = 0; i < name.size (); ++i)
404  {
405  // check for directory delimiters and update start
406  if (name[i] == '/' || name[i] == '\\')
407  {
408  // if they have supplied a directory with an
409  // ending slash, then use the previous start
410  if (i != name.size () - 1)
411  start = i + 1;
412  }
413  }
414 
415  // return the substring from start to the end of the filename
416  return name.substr (start, name.size () - start);
417 }
418 
421 expand_envs (const std::string & source)
422 {
423  std::stringstream buffer;
424 
425  for (size_t i = 0; i < source.size (); ++i)
426  {
427  // environment variable must be larger than $()
428  if (source[i] == '$' && i + 3 < source.size ())
429  {
430  char * value = get_var (source, i+2, i);
431  if (value)
432  buffer << value;
433  }
434  else
435  buffer << source[i];
436  }
437  return buffer.str ();
438 }
439 
441 char *
442 get_var (const std::string & source,
443  size_t cur, size_t & end)
444 {
445  for (end = cur; end < source.size (); ++end)
446  {
447  if (source[end] == ')' || source[end] == '}')
448  {
449  return getenv (source.substr (cur, end - cur).c_str ());
450  }
451  }
452 
453  return getenv (source.substr (cur,source.size () - cur).c_str ());
454 }
455 
457 clean_dir_name (const std::string & source)
458 {
459  // define the characters we'll want to replace
460 #ifdef _WIN32
461  #define REPLACE_THIS '/'
462  #define REPLACE_WITH '\\'
463 #else
464  #define REPLACE_THIS '\\'
465  #define REPLACE_WITH '/'
466 #endif
467 
468  std::string target (source);
469 
470  for (std::string::iterator i = target.begin (); i != target.end(); ++i)
471  {
472  if (*i == REPLACE_THIS)
473  *i = REPLACE_WITH;
474  }
475 
476  return target;
477 }
478 
479 int
480  read_file (const std::string & filename,
481  void *& buffer, size_t & size, bool add_zero_char)
482 {
483  int ret_value = 0;
484  if (filename != "")
485  {
486  try
487  {
488  std::ifstream file (filename, std::ifstream::binary);
489 
490  if (file)
491  {
492  file.seekg (0, file.end);
493  size = (size_t) file.tellg ();
494  file.seekg (0, file.beg);
495 
498  "utility::read_file:"
499  " reading %d bytes from %s\n",
500  (int)size, filename.c_str ());
501 
502  if (add_zero_char)
503  {
504  ++size;
505  }
506 
507  buffer = new unsigned char [size];
508 
509  if (size > 0)
510  {
511  file.read ((char *)buffer, size);
512 
515  "utility::read_file:"
516  " successfully read %d bytes from %s\n",
517  (int)size, filename.c_str ());
518 
519  if (add_zero_char)
520  {
521  unsigned char * zeroed = (unsigned char *)buffer;
522  zeroed[size - 1] = 0;
523  } // end if adding a zero char
524 
525  ret_value = 0;
526  }
527 
528  file.close ();
529  } // end if file is open
530  else ret_value = -1;
531  } // end try
532  catch (const std::exception& e)
533  {
535  "utility::read_file:"
536  " exception: %s\n", e.what());
537 
538  ret_value = -1;
539  }
540  }
541  else ret_value = -1;
542 
543  return ret_value;
544 }
545 
546 ssize_t
547  write_file (const std::string & filename,
548  void * buffer, size_t size)
549 {
550  // error is -1
551  ssize_t actual = -1;
552 
553  std::ofstream file;
554 
555  try
556  {
557  file.open (filename, std::ios::out | std::ios::binary);
558  if (file.write ((char *)buffer, size))
559  {
560  actual = size;
561  }
562  file.close ();
563 
565  "utility::write_file:"
566  " wrote %d bytes to %s\n", (int)actual, filename.c_str ());
567  }
568  catch(const std::exception& e)
569  {
571  "utility::write_file:"
572  " exception: %s\n", e.what());
573  }
574 
575  // return the actual bytes written. -1 if error
576  return actual;
577 }
578 
579 double
580 rand_double (double floor, double ceiling, bool set_seed_to_time)
581 {
582  // check if the user has specified setting through srand
583  if (set_seed_to_time)
584  {
585  srand ((unsigned int)get_time ());
586  }
587 
588  // Get a double number between 0 and 1.
589  double position_in_range = ((double)rand()) / ((double)RAND_MAX);
590 
591  if (floor < ceiling)
592  return (position_in_range * (ceiling - floor)) + floor;
593  else
594  return (position_in_range * (floor - ceiling)) + ceiling;
595 }
596 
597 int64_t
598 rand_int (int64_t floor, int64_t ceiling,
599  bool set_seed_to_time)
600 {
601  double random = rand_double ((double)floor, (double)ceiling, set_seed_to_time);
602  return nearest_int (random);
603 }
604 
605 int64_t
606 nearest_int (double input)
607 {
608  int change = input >= 0 ? 1 : -1;
609  int64_t left = (int64_t)input;
610  int64_t right = (int64_t)input + change;
611 
612  if (input - left < -input + right)
613  return left;
614  else
615  return right;
616 }
617 
618 
619 double sleep (double sleep_time)
620 {
621  SecondsDuration period = seconds_to_seconds_duration (sleep_time);
622  period = sleep (period);
623 
624  return period.count ();
625 }
626 
628 {
629  TimeValue start = get_time_value ();
630  TimeValue current = start;
631  TimeValue target = current;
632 
633 #ifdef MADARA_FEATURE_SIMTIME
634  // @David feel free to change this as SimTime is implemented
635  double rate = SimTime::rate ();
636  SecondsDuration dilated_time = sleep_time;
637  dilated_time /= rate;
638  target += std::chrono::duration_cast <Duration> (dilated_time);
639 #else
640  target += std::chrono::duration_cast <Duration> (sleep_time);
641 #endif
642 
643  while (current < target)
644  {
645  std::this_thread::sleep_until(target);
646  current = get_time_value ();
647  }
648 
649  return current - start;
650 }
651 
652 bool
655  const std::string & variable,
656  const knowledge::WaitSettings & settings)
657 {
658  // use the EpochEnforcer utility to keep track of sleeps
660  settings.poll_frequency, settings.max_wait_time);
661 
662  knowledge::VariableReference ref = knowledge.get_ref (variable);
663 
664  // print the post statement at highest log level (cannot be masked)
665  if (settings.pre_print_statement != "")
666  knowledge.print (settings.pre_print_statement, logger::LOG_ALWAYS);
667 
668  knowledge::KnowledgeRecord last_value = knowledge.get (ref, settings);
669 
671  "utility::wait_true:" \
672  " variable returned %s\n",
673  last_value.to_string ().c_str ());
674 
675  // wait for expression to be true
676  while (!last_value.is_true () &&
677  (settings.max_wait_time < 0 || !enforcer.is_done ()))
678  {
680  "utility::wait_true:" \
681  " last value didn't result in success\n");
682 
683  // Unlike the other wait statements, we allow for a time based wait.
684  // To do this, we allow a user to specify a
685  if (settings.poll_frequency > 0)
686  {
687  enforcer.sleep_until_next ();
688  }
689  else
690  {
691  knowledge.wait_for_change ();
692  }
693 
695  "utility::wait_true:" \
696  " waiting on %s\n", variable.c_str ());
697 
698  last_value = knowledge.get (ref, settings);
699 
701  "utility::wait_true:" \
702  " completed eval to get %s\n",
703  last_value.to_string ().c_str ());
704  } // end while (!last)
705 
706  if (enforcer.is_done ())
707  {
709  "utility::wait_true:" \
710  " Evaluate did not succeed. Timeout occurred\n",
711  last_value.to_string ().c_str ());
712  }
713 
714  // print the post statement at highest log level (cannot be masked)
715  if (settings.post_print_statement != "")
716  knowledge.print (settings.post_print_statement, logger::LOG_ALWAYS);
717 
718  return last_value.is_true ();
719 }
720 
723  const std::string & variable,
724  const knowledge::WaitSettings & settings)
725 {
726  // use the EpochEnforcer utility to keep track of sleeps
728  settings.poll_frequency, settings.max_wait_time);
729 
730  knowledge::VariableReference ref = knowledge.get_ref (variable);
731 
732  // print the post statement at highest log level (cannot be masked)
733  if (settings.pre_print_statement != "")
734  knowledge.print (settings.pre_print_statement, logger::LOG_ALWAYS);
735 
736  knowledge::KnowledgeRecord last_value (!knowledge.get (ref, settings));
737 
739  "utility::wait_false:" \
740  " variable returned %s\n",
741  last_value.to_string ().c_str ());
742 
743  // wait for expression to be true
744  while (last_value.is_true () &&
745  (settings.max_wait_time < 0 || !enforcer.is_done ()))
746  {
748  "utility::wait_false:"
749  " last value didn't result in success\n");
750 
751  // Unlike the other wait statements, we allow for a time based wait.
752  // To do this, we allow a user to specify a
753  if (settings.poll_frequency > 0)
754  {
755  enforcer.sleep_until_next ();
756  }
757  else
758  {
759  knowledge.wait_for_change ();
760  }
761 
763  "utility::wait_false:"
764  " waiting on %s\n", variable.c_str ());
765 
766  last_value = knowledge::KnowledgeRecord (!knowledge.get (ref, settings));
767 
769  "utility::wait_false:"
770  " completed eval to get %s\n",
771  last_value.to_string ().c_str ());
772  } // end while (!last)
773 
774  if (enforcer.is_done ())
775  {
777  "utility::wait_false:"
778  " Evaluate did not succeed. Timeout occurred\n",
779  last_value.to_string ().c_str ());
780  }
781 
782  // print the post statement at highest log level (cannot be masked)
783  if (settings.post_print_statement != "")
784  knowledge.print (settings.post_print_statement, logger::LOG_EMERGENCY);
785 
786  return last_value.is_true ();
787 }
788 
789 std::pair<std::string, uint16_t> parse_address (std::string addr)
790 {
791  size_t colon_pos = addr.find(':');
792  if (colon_pos == std::string::npos || colon_pos >= addr.size() - 1) {
793  return {addr, 0};
794  }
795 
796  int16_t port = std::atoi(addr.c_str() + colon_pos + 1);
797  addr.resize(colon_pos);
798  return {std::move(addr), port};
799 }
800 
801 } }
This class encapsulates an entry in a KnowledgeBase.
bool is_true(void) const
Checks to see if the record is true.
double max_wait_time
Maximum time to wait for an expression to become true (in seconds)
Definition: WaitSettings.h:113
std::string extract_filename(const std::string &name)
Extracts the file name of an absolute or relative path.
Definition: Utility.cpp:400
std::chrono::duration< double > SecondsDuration
default clock duration
Definition: Utility.h:33
void tokenizer(const std::string &input, const ::std::vector< std::string > &splitters,::std::vector< std::string > &tokens,::std::vector< std::string > &pivots)
Split a string into tokens.
Definition: Utility.cpp:242
std::pair< std::string, uint16_t > parse_address(std::string addr)
Definition: Utility.cpp:789
madara::knowledge::KnowledgeRecord KnowledgeRecord
int read_file(const std::string &filename, void *&buffer, size_t &size, bool add_zero_char)
Reads a file into a provided void pointer.
Definition: Utility.cpp:480
std::string & strip_comments(std::string &input)
Strips all comments (single-line and multi-line).
Definition: Utility.cpp:210
int64_t get_time(void)
Returns a time of day in nanoseconds If simtime feature is enabled, this may be simulation time inste...
Definition: Utility.inl:253
std::string & strip_extra_white_space(std::string &input)
Strip whitespace from front and end of string and also condense multiple whitespace into a single spa...
Definition: Utility.cpp:90
std::string pre_print_statement
Statement to print before evaluations.
Definition: EvalSettings.h:120
SecondsDuration seconds_to_seconds_duration(double seconds)
Returns seconds in double format as seconds duration.
Definition: Utility.inl:272
bool wait_false(knowledge::KnowledgeBase &knowledge, const std::string &variable, const knowledge::WaitSettings &settings)
Waits on a knowledge record to be false without needing KaRL language.
Definition: Utility.cpp:721
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
std::string extract_path(const std::string &name)
Extracts the path of a filename.
Definition: Utility.cpp:380
std::chrono::time_point< Clock > TimeValue
time point
Definition: Utility.h:36
Optimized reference to a variable within the knowledge base.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Retrieves a knowledge value.
std::string post_print_statement
Statement to print after evaluations.
Definition: EvalSettings.h:125
double sleep(double sleep_time)
Sleeps for a certain amount of time.
Definition: Utility.cpp:619
bool is_done(void) const
Checks to see if max duration is finished.
TimeValue get_time_value(void)
Returns a time of day as a chrono time value If simtime feature is enabled, this may be simulation ti...
Definition: Utility.inl:243
static struct madara::knowledge::tags::string_t string
Enforces a periodic epoch.
Definition: EpochEnforcer.h:17
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
std::string to_string_version(uint32_t version)
Converts a MADARA uint32_t version number to human-readable.
Definition: Utility.cpp:68
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
int64_t nearest_int(double input)
Rounds a double to the nearest integer.
Definition: Utility.cpp:606
std::string file_to_string(const std::string &filename)
Reads a file into a string.
Definition: Utility.cpp:347
int split_hostport_identifier(const std::string &key, std::string &host, std::string &port)
Splits a key of host:port into a corresponding host and port.
Definition: Utility.cpp:298
uint32_t get_uint_version(void)
Gets the MADARA version number.
Definition: Utility.cpp:32
bool wait_true(knowledge::KnowledgeBase &knowledge, const std::string &variable, const knowledge::WaitSettings &settings)
Waits on a knowledge record to be true without needing KaRL language.
Definition: Utility.cpp:653
double poll_frequency
Frequency to poll an expression for truth (in seconds)
Definition: WaitSettings.h:108
std::string & strip_white_space(std::string &input)
Strip all whitespace.
Definition: Utility.cpp:132
std::string clean_dir_name(const std::string &source)
Substitutes the appropriate directory delimiter, which may help with portability between operating sy...
Definition: Utility.cpp:457
#define REPLACE_WITH
double rand_double(double floor, double ceiling, bool set_seed_to_time)
Returns a random double between floor and ceiling.
Definition: Utility.cpp:580
std::string expand_envs(const std::string &source)
Expand any environment variables in a string.
Definition: Utility.cpp:421
int64_t rand_int(int64_t floor, int64_t ceiling, bool set_seed_to_time)
Returns a random integer between a floor and ceiling.
Definition: Utility.cpp:598
Provides utility functions and classes for common tasks and needs.
Definition: IteratorImpl.h:14
Provides functions and classes for the distributed knowledge base.
#define REPLACE_THIS
std::string & string_remove(std::string &input, char unwanted)
Strips an unwanted character.
Definition: Utility.cpp:160
Copyright (c) 2015 Carnegie Mellon University.
int merge_hostport_identifier(std::string &key, const std::string &host, const std::string &port)
Merges a host and port into a host:port key.
Definition: Utility.cpp:323
Encapsulates settings for a wait statement.
Definition: WaitSettings.h:23
std::string get_version(void)
Gets the MADARA version number.
Definition: Utility.cpp:22
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
ssize_t write_file(const std::string &filename, void *buffer, size_t size)
Writes a file with provided contents.
Definition: Utility.cpp:547
void sleep_until_next(void)
Sleeps until the next epoch.
Definition: EpochEnforcer.h:92
char * get_var(const std::string &source, size_t cur, size_t &end)
grab an environment variable value (
Definition: Utility.cpp:442
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Atomically returns a reference to the variable.
std::chrono::nanoseconds Duration
default clock duration
Definition: Utility.h:30
void print(unsigned int level=0) const
Prints all knowledge variables and values in the context.
size_t string_replace(std::string &source, const std::string &old_phrase, const std::string &new_phrase, bool replace_all)
Replaces an old phrase with a new phrase within a string.
Definition: Utility.cpp:183
void wait_for_change(void)
Wait for a change to happen to the context (e.g., from transports)
static struct madara::knowledge::tags::binary_t binary