GnuCash  2.6.99
Data Structures | Typedefs | Functions | Friends
KVP: Key-Value Pairs

A KvpFrame is a set of associations between character strings (keys) and KvpValues. More...

Data Structures

struct  KvpValue
 Implements KvpValue using boost::variant. More...
 
struct  KvpFrame
 Implements KvpFrame. More...
 
class  KvpFrame::cstring_comparer
 

Typedefs

using Path = std::vector< std::string >
 
using KvpFrame::map_type = std::map< const char *, KvpValue *, cstring_comparer >
 

Functions

int compare (const KvpValueImpl *, const KvpValue *) noexcept
 
bool KvpFrame::cstring_comparer::operator() (const char *one, const char *two) const
 
 KvpFrame::KvpFrameImpl (const KvpFrameImpl &) noexcept
 Performs a deep copy.
 
 KvpFrame::~KvpFrameImpl () noexcept
 Perform a deep delete.
 
KvpValue * KvpFrame::set (const char *key, KvpValue *newvalue) noexcept
 Set the value with the key in the immediate frame, replacing and returning the old value if it exists or nullptr if it doesn't. More...
 
KvpValue * KvpFrame::set (Path path, KvpValue *newvalue) noexcept
 Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't. More...
 
KvpValue * KvpFrame::set_path (const char *path, KvpValue *newvalue) noexcept
 Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't. More...
 
KvpValue * KvpFrame::set_path (Path path, KvpValue *newvalue) noexcept
 Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't. More...
 
std::string KvpFrame::to_string () const noexcept
 Make a string representation of the frame. More...
 
std::vector< std::string > KvpFrame::get_keys () const noexcept
 Report the keys in the immediate frame. More...
 
KvpValue * KvpFrame::get_slot (const char *key) const noexcept
 Get the value for the key or nullptr if it doesn't exist. More...
 
KvpValue * KvpFrame::get_slot (Path keys) const noexcept
 Get the value for the tail of the path or nullptr if it doesn't exist. More...
 
void KvpFrame::for_each_slot (void(*proc)(const char *key, KvpValue *value, void *data), void *data) const noexcept
 Convenience wrapper for std::for_each, which should be preferred.
 
bool KvpFrame::empty () const noexcept
 Test for emptiness. More...
 

Friends

int KvpFrame::compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept
 If the first KvpFrameImpl has an item that the second does not, 1 is returned. More...
 
GValue * gvalue_from_kvp_value (const KvpValue *kval)
 Convert a kvp_value into a GValue. More...
 
KvpValue * kvp_value_from_gvalue (const GValue *gval)
 Convert a gvalue into a kvpvalue. More...
 
void gnc_gvalue_free (GValue *value)
 Convenience function to release the value in a GValue acquired by kvp_frame_get_gvalue and to free the GValue. More...
 
int compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept
 If the first KvpFrameImpl has an item that the second does not, 1 is returned. More...
 
int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept
 
void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb)
 Load a GNCOptionsDB from KVP data. More...
 
void qof_book_save_options (QofBook *book, GNCOptionSave save_cb, GNCOptionDB *odb, gboolean clear)
 Save a GNCOptionsDB back to the book's KVP. More...
 
void qof_book_set_option (QofBook *book, KvpValue *value, GSList *path)
 Save a single option value. More...
 
KvpValue * qof_book_get_option (QofBook *book, GSList *path)
 Read a single option value. More...
 
void qof_book_options_delete (QofBook *book, GSList *path)
 Delete the options. More...
 
gboolean qof_instance_has_kvp (QofInstance *inst)
 Report whether a QofInstance has anything stored in KVP. More...
 
void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value)
 Sets a KVP slot to a value from a GValue. More...
 
void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value)
 Retrieves the contents of a KVP slot into a provided GValue. More...
 

Detailed Description

A KvpFrame is a set of associations between character strings (keys) and KvpValues.

A KvpValue is notionally a union with possible types enumerated in the KvpValue::Type enum, and includes, among other things, ints, doubles, strings, guids, lists, time and numeric values. KvpValues may also be other frames, so KVP is inherently hierarchical.

Values are stored in a 'slot' associated with a key. Pointers passed as arguments into set_slot and get_slot are the responsibility of the caller. Pointers returned by get_slot are owned by the kvp_frame. Make copies as needed.

A 'path' is a sequence of keys that can be followed to a value. Paths are passed as either '/'-delimited strings or as std::vectors of keys. Unlike file system paths, the tokens '.' and '..' have no special meaning.

KVP is an implementation detail whose direct use should be avoided; create an abstraction object in libqof to keep KVP encapsulated here and ensure that KVP modifications are written to the database. Two generic abstractions are provided:

KVP Values used By GnuCash provides a catolog of KVP entries including what objects they're part of and how they're used.

Purpose

KVP is used to extend the class structure without directly reflecting the extension in the database or xML schema. The backend will directly load and store KVP slots without any checking, which allows older versions of GnuCash to load the database without complaint and without damaging the KVP data that they don't understand.

When a feature is entirely implemented in KVP and doesn't affect the meaning of the books or other features, this isn't a problem, but when it's not true then it should be registered in Features so that older versions of GnuCash will refuse to load the database.

Policy

Function Documentation

◆ compare()

int compare ( const KvpFrameImpl one,
const KvpFrameImpl two 
)
noexcept

If the first KvpFrameImpl has an item that the second does not, 1 is returned.

The first item within the two KvpFrameImpl that is not similar, that comparison is returned. If all the items within the first KvpFrameImpl match items within the second, but the second has more elements, -1 is returned. Otherwise, 0 is returned.

Definition at line 272 of file kvp_frame.cpp.

273 {
274  for (const auto & a : one.m_valuemap)
275  {
276  auto otherspot = two.m_valuemap.find(a.first);
277  if (otherspot == two.m_valuemap.end())
278  {
279  return 1;
280  }
281  auto comparison = compare(a.second,otherspot->second);
282 
283  if (comparison != 0)
284  return comparison;
285  }
286 
287  if (one.m_valuemap.size() < two.m_valuemap.size())
288  return -1;
289  return 0;
290 }
int compare(const KvpFrameImpl &one, const KvpFrameImpl &two) noexcept
If the first KvpFrameImpl has an item that the second does not, 1 is returned.
Definition: kvp_frame.cpp:272

◆ empty()

bool KvpFrame::empty ( ) const
inlinenoexcept

Test for emptiness.

Returns
true if the frame contains nothing.

Definition at line 216 of file kvp_frame.hpp.

216 { return m_valuemap.empty(); }

◆ get_keys()

std::vector< std::string > KvpFrame::get_keys ( ) const
noexcept

Report the keys in the immediate frame.

Be sensible about using this, it isn't a very efficient way to iterate.

Returns
std::vector of keys as std::strings.

Definition at line 205 of file kvp_frame.cpp.

206 {
207  std::vector<std::string> ret;
208  std::for_each(m_valuemap.begin(), m_valuemap.end(),
209  [&ret](const KvpFrameImpl::map_type::value_type &a)
210  {
211  ret.push_back(a.first);
212  }
213  );
214  return ret;
215 }

◆ get_slot() [1/2]

KvpValueImpl * KvpFrame::get_slot ( const char *  key) const
noexcept

Get the value for the key or nullptr if it doesn't exist.

Parameters
keyThe key.
Returns
The value at the key or nullptr.

Definition at line 232 of file kvp_frame.cpp.

233 {
234  if (!key) return nullptr;
235  if (strchr(key, delim))
236  return get_slot(make_vector(key));
237  auto spot = m_valuemap.find(key);
238  if (spot == m_valuemap.end())
239  return nullptr;
240  return spot->second;
241 }
KvpValue * get_slot(const char *key) const noexcept
Get the value for the key or nullptr if it doesn&#39;t exist.
Definition: kvp_frame.cpp:232

◆ get_slot() [2/2]

KvpValueImpl * KvpFrame::get_slot ( Path  keys) const
noexcept

Get the value for the tail of the path or nullptr if it doesn't exist.

Parameters
pathPath of keys leading to the desired value.
Returns
The value at the key or nullptr.

Definition at line 244 of file kvp_frame.cpp.

245 {
246  auto last_key = path.back();
247  path.pop_back();
248  auto cur_frame = walk_path_or_nullptr(this, path);
249  if (cur_frame == nullptr)
250  return nullptr;
251  if (last_key.find(delim) != std::string::npos)
252  return get_slot(make_vector(last_key));
253  return cur_frame->get_slot(last_key.c_str());
254 
255 }
KvpValue * get_slot(const char *key) const noexcept
Get the value for the key or nullptr if it doesn&#39;t exist.
Definition: kvp_frame.cpp:232

◆ gnc_gvalue_free()

void gnc_gvalue_free ( GValue *  value)

Convenience function to release the value in a GValue acquired by kvp_frame_get_gvalue and to free the GValue.

Parameters
valueA GValue* created by kvp_frame_get_gvalue

Definition at line 447 of file kvp_frame.cpp.

448 {
449  if (val == NULL || ! G_IS_VALUE (val)) return;
450  g_value_unset (val);
451  g_slice_free (GValue, val);
452 }

◆ gvalue_from_kvp_value()

GValue* gvalue_from_kvp_value ( const KvpValue *  kval)

Convert a kvp_value into a GValue.

Frames aren't converted.

Parameters
kvalA KvpValue.
Returns
GValue*. Must be freed with g_free().

Definition at line 315 of file kvp_frame.cpp.

316 {
317  GValue *val;
318  gnc_numeric num;
319  Timespec tm;
320  GDate gdate;
321 
322  if (kval == NULL) return NULL;
323  val = g_slice_new0 (GValue);
324 
325  switch (kval->get_type())
326  {
327  case KvpValue::Type::INT64:
328  g_value_init (val, G_TYPE_INT64);
329  g_value_set_int64 (val, kval->get<int64_t>());
330  break;
331  case KvpValue::Type::DOUBLE:
332  g_value_init (val, G_TYPE_DOUBLE);
333  g_value_set_double (val, kval->get<double>());
334  break;
335  case KvpValue::Type::NUMERIC:
336  g_value_init (val, GNC_TYPE_NUMERIC);
337  num = kval->get<gnc_numeric>();
338  g_value_set_boxed (val, &num);
339  break;
340  case KvpValue::Type::STRING:
341  g_value_init (val, G_TYPE_STRING);
342  g_value_set_string (val, kval->get<const char*>());
343  break;
344  case KvpValue::Type::GUID:
345  g_value_init (val, GNC_TYPE_GUID);
346  g_value_set_boxed (val, kval->get<GncGUID*>());
347  break;
348  case KvpValue::Type::TIMESPEC:
349  g_value_init (val, GNC_TYPE_TIMESPEC);
350  tm = kval->get<Timespec>();
351  g_value_set_boxed (val, &tm);
352  break;
353  case KvpValue::Type::GDATE:
354  g_value_init (val, G_TYPE_DATE);
355  gdate = kval->get<GDate>();
356  g_value_set_boxed (val, &gdate);
357  break;
358  case KvpValue::Type::GLIST:
359  {
360  GList *gvalue_list = NULL;
361  GList *kvp_list = kval->get<GList*>();
362  g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value,
363  &gvalue_list);
364  g_value_init (val, GNC_TYPE_VALUE_LIST);
365  gvalue_list = g_list_reverse (gvalue_list);
366  g_value_set_boxed (val, gvalue_list);
367  break;
368  }
369 /* No transfer of KVP frames outside of QofInstance-derived classes! */
370  case KvpValue::Type::FRAME:
371  PWARN ("Error! Attempt to transfer KvpFrame!");
372  default:
373  PWARN ("Error! Invalid KVP Transfer Request!");
374  g_slice_free (GValue, val);
375  val = NULL;
376  break;
377  }
378  return val;
379 }
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:243
The type used to store guids in C.
Definition: guid.h:75

◆ kvp_value_from_gvalue()

KvpValue* kvp_value_from_gvalue ( const GValue *  gval)

Convert a gvalue into a kvpvalue.

Parameters
gvalA GValue of a type KvpValue can digest.
Returns
KvpValue created from the GValue's contents.

Definition at line 382 of file kvp_frame.cpp.

383 {
384  KvpValue *val = NULL;
385  GType type;
386  if (gval == NULL)
387  return NULL;
388  type = G_VALUE_TYPE (gval);
389  g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
390 
391  if (type == G_TYPE_INT64)
392  val = new KvpValue(g_value_get_int64 (gval));
393  else if (type == G_TYPE_DOUBLE)
394  val = new KvpValue(g_value_get_double (gval));
395  else if (type == G_TYPE_BOOLEAN)
396  {
397  auto bval = g_value_get_boolean(gval);
398  if (bval)
399  val = new KvpValue(g_strdup("true"));
400  }
401  else if (type == GNC_TYPE_NUMERIC)
402  val = new KvpValue(*(gnc_numeric*)g_value_get_boxed (gval));
403  else if (type == G_TYPE_STRING)
404  {
405  auto string = g_value_get_string(gval);
406  if (string != nullptr)
407  val = new KvpValue(g_strdup(string));
408  }
409  else if (type == GNC_TYPE_GUID)
410  {
411  auto boxed = g_value_get_boxed(gval);
412  if (boxed != nullptr)
413  val = new KvpValue(guid_copy(static_cast<GncGUID*>(boxed)));
414  }
415  else if (type == GNC_TYPE_TIMESPEC)
416  val = new KvpValue(*(Timespec*)g_value_get_boxed (gval));
417  else if (type == G_TYPE_DATE)
418  val = new KvpValue(*(GDate*)g_value_get_boxed (gval));
419  else if (type == GNC_TYPE_VALUE_LIST)
420  {
421  GList *gvalue_list = (GList*)g_value_get_boxed (gval);
422  GList *kvp_list = NULL;
423  g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue,
424  &kvp_list);
425  kvp_list = g_list_reverse (kvp_list);
426  val = new KvpValue(kvp_list);
427 // g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset);
428 // gvalue_list = NULL;
429  }
430  else
431  PWARN ("Error! Don't know how to make a KvpValue from a %s",
432  G_VALUE_TYPE_NAME (gval));
433 
434  return val;
435 }
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
Definition: guid.cpp:121
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:243

◆ qof_book_get_option()

KvpValue* qof_book_get_option ( QofBook *  book,
GSList *  path 
)

Read a single option value.

Used from Scheme, the KvpValue<–>SCM translation is handled by the functions in kvp-scm.c and automated by SWIG. The starting element is set as KVP_OPTION_PATH in qofbookslots.h.

Parameters
bookThe book.
pathA GSList of keys which form a path under KVP_OPTION_PATH.

Definition at line 1195 of file qofbook.cpp.

1196 {
1197  KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1198  Path path_v {KVP_OPTION_PATH};
1199  for (auto item = path; item != nullptr; item = g_slist_next(item))
1200  path_v.push_back(static_cast<const char*>(item->data));
1201  return root->get_slot(path_v);
1202 }

◆ qof_book_load_options()

void qof_book_load_options ( QofBook *  book,
GNCOptionLoad  load_cb,
GNCOptionDB *  odb 
)

Load a GNCOptionsDB from KVP data.

Parameters
bookThe book.
load_cbA callback function that does the loading.
odbThe GNCOptionDB to load.

Definition at line 1154 of file qofbook.cpp.

1155 {
1156  load_cb (odb, book);
1157 }

◆ qof_book_options_delete()

void qof_book_options_delete ( QofBook *  book,
GSList *  path 
)

Delete the options.

Primarily used from Scheme to clear out the options before saving a new set.

Parameters
bookThe book.
listA GList of keys which from a path under KVP_OPTION_PATH. If GList is Null, the whole option is deleted.

Definition at line 1205 of file qofbook.cpp.

1206 {
1207  KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1208  if (path != nullptr)
1209  {
1210  Path path_v {KVP_OPTION_PATH};
1211  for (auto item = path; item != nullptr; item = g_slist_next(item))
1212  path_v.push_back(static_cast<const char*>(item->data));
1213  delete root->set_path(path_v, nullptr);
1214  }
1215  else
1216  delete root->set_path(KVP_OPTION_PATH, nullptr);
1217 }

◆ qof_book_save_options()

void qof_book_save_options ( QofBook *  book,
GNCOptionSave  save_cb,
GNCOptionDB *  odb,
gboolean  clear 
)

Save a GNCOptionsDB back to the book's KVP.

Parameters
bookThe book.
save_cbA callback function that does the saving.
odbThe GNCOptionsDB to save from.
clearShould the GNCOptionsDB be emptied after the save?

Definition at line 1160 of file qofbook.cpp.

1162 {
1163  /* Wrap this in begin/commit so that it commits only once instead of doing
1164  * so for every option. Qof_book_set_option will take care of dirtying the
1165  * book.
1166  */
1167  qof_book_begin_edit (book);
1168  save_cb (odb, book, clear);
1169  qof_book_commit_edit (book);
1170 }

◆ qof_book_set_option()

void qof_book_set_option ( QofBook *  book,
KvpValue *  value,
GSList *  path 
)

Save a single option value.

Used from Scheme, the KvpValue<–>SCM translation is handled by the functions in kvp-scm.c and automated by SWIG. The starting element is set as KVP_OPTION_PATH in qofbookslots.h.

Parameters
bookThe book.
valueThe KvpValue to store.
pathA GSList of keys which form a path under KVP_OPTION_PATH.

Definition at line 1182 of file qofbook.cpp.

1183 {
1184  KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE (book));
1185  Path path_v {KVP_OPTION_PATH};
1186  for (auto item = path; item != nullptr; item = g_slist_next(item))
1187  path_v.push_back(static_cast<const char*>(item->data));
1188  qof_book_begin_edit (book);
1189  delete root->set_path(path_v, value);
1190  qof_instance_set_dirty (QOF_INSTANCE (book));
1191  qof_book_commit_edit (book);
1192 }

◆ qof_instance_get_kvp()

void qof_instance_get_kvp ( const QofInstance *  inst,
const gchar *  key,
GValue *  value 
)

Retrieves the contents of a KVP slot into a provided GValue.

Parameters
instThe QofInstance
keyThe key of or '/'-delimited path to the slot.
valueA GValue into which to store the value of the slot. It will be set to the correct type.

Definition at line 1069 of file qofinstance.cpp.

1070 {
1071  auto temp = gvalue_from_kvp_value (inst->kvp_data->get_slot(key));
1072  if (G_IS_VALUE (temp))
1073  {
1074  if (G_IS_VALUE (value))
1075  g_value_unset (value);
1076  g_value_init (value, G_VALUE_TYPE (temp));
1077  g_value_copy (temp, value);
1078  gnc_gvalue_free (temp);
1079  }
1080 }
void gnc_gvalue_free(GValue *value)
Convenience function to release the value in a GValue acquired by kvp_frame_get_gvalue and to free th...
Definition: kvp_frame.cpp:447
GValue * gvalue_from_kvp_value(const KvpValue *kval)
Convert a kvp_value into a GValue.
Definition: kvp_frame.cpp:315

◆ qof_instance_has_kvp()

gboolean qof_instance_has_kvp ( QofInstance *  inst)

Report whether a QofInstance has anything stored in KVP.

Parameters
instThe QofInstance
Returns
TRUE if Kvp isn't empty.

Definition at line 1057 of file qofinstance.cpp.

1058 {
1059  return (inst->kvp_data != NULL && !inst->kvp_data->empty());
1060 }

◆ qof_instance_set_kvp()

void qof_instance_set_kvp ( QofInstance *  inst,
const gchar *  key,
const GValue *  value 
)

Sets a KVP slot to a value from a GValue.

The key can be a '/'-delimited path, and intermediate container frames will be created if necessary. Commits the change to the QofInstance.

Parameters
instThe QofInstance on which to set the value.
keyThe key for the slot or '/'-delimited path
valueA GValue containing an item of a type which KvpValue knows how to store.

Definition at line 1063 of file qofinstance.cpp.

1064 {
1065  delete inst->kvp_data->set_path(key, kvp_value_from_gvalue(value));
1066 }
KvpValue * kvp_value_from_gvalue(const GValue *gval)
Convert a gvalue into a kvpvalue.
Definition: kvp_frame.cpp:382

◆ set() [1/2]

KvpValue * KvpFrame::set ( const char *  key,
KvpValue *  newvalue 
)
noexcept

Set the value with the key in the immediate frame, replacing and returning the old value if it exists or nullptr if it doesn't.

Takes ownership of new value and releases ownership of the returned old value. Values must be allocated on the free store with operator new.

Parameters
keyThe key to insert/replace.
newvalueThe value to set at key.
Returns
The old value if there was one or nullptr.

Definition at line 87 of file kvp_frame.cpp.

88 {
89  if (!key) return nullptr;
90  if (strchr(key, delim))
91  return set(make_vector(key), value);
92  KvpValue* ret {nullptr};
93  auto spot = m_valuemap.find(key);
94  if (spot != m_valuemap.end())
95  {
96  qof_string_cache_remove(spot->first);
97  ret = spot->second;
98  m_valuemap.erase(spot);
99  }
100 
101  if (value)
102  {
103  auto cachedkey =
104  static_cast<const char *>(qof_string_cache_insert(key));
105  m_valuemap.insert({cachedkey,value});
106  }
107 
108  return ret;
109 }
void qof_string_cache_remove(gconstpointer key)
You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or...
gpointer qof_string_cache_insert(gconstpointer key)
You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the ...

◆ set() [2/2]

KvpValue * KvpFrame::set ( Path  path,
KvpValue *  newvalue 
)
noexcept

Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't.

Takes ownership of new value and releases ownership of the returned old value. Values must be allocated on the free store with operator new.

Parameters
keyThe key to insert/replace.
Exceptions
invalid_argumentif the path doesn't exist.
Parameters
pathThe path of subframes leading to the frame in which to insert/replace.
newvalueThe value to set at key.
Returns
The old value if there was one or nullptr.

Definition at line 126 of file kvp_frame.cpp.

127 {
128  auto last_key = path.back();
129  path.pop_back();
130  auto cur_frame = walk_path_or_nullptr(this, path);
131  if (cur_frame == nullptr)
132  return nullptr;
133  if (last_key.find(delim) != std::string::npos)
134  return set(make_vector(last_key), value);
135  return cur_frame->set(last_key.c_str(), value);
136 }

◆ set_path() [1/2]

KvpValue * KvpFrame::set_path ( const char *  path,
KvpValue *  newvalue 
)
noexcept

Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't.

Creates any missing intermediate frames. Takes ownership of new value and releases ownership of the returned old value. Values must be allocated on the free store with operator new.

Parameters
pathThe path of subframes as a '/'-delimited string leading to the frame in which to insert/replace.
newvalueThe value to set at key.
Returns
The old value if there was one or nullptr.

Definition at line 164 of file kvp_frame.cpp.

165 {
166  return set_path(make_vector(path), value);
167 }
KvpValue * set_path(const char *path, KvpValue *newvalue) noexcept
Set the value with the key in a subframe following the keys in path, replacing and returning the old ...
Definition: kvp_frame.cpp:164

◆ set_path() [2/2]

KvpValue * KvpFrame::set_path ( Path  path,
KvpValue *  newvalue 
)
noexcept

Set the value with the key in a subframe following the keys in path, replacing and returning the old value if it exists or nullptr if it doesn't.

Creates any missing intermediate frames.Takes ownership of new value and releases ownership of the returned old value. Values must be allocated on the free store with operator new.

Parameters
pathThe path of subframes as a std::vector leading to the frame in which to insert/replace.
newvalueThe value to set at key.
Returns
The old value if there was one or nullptr.

Definition at line 170 of file kvp_frame.cpp.

171 {
172  auto cur_frame = this;
173  auto last_key = path.back();
174  path.pop_back();
175  cur_frame = walk_path_and_create(const_cast<KvpFrame*>(this), path);
176  if (last_key.find(delim) != std::string::npos)
177  return set_path(make_vector(last_key), value);
178  return cur_frame->set(last_key.c_str(), value);
179 }
KvpValue * set_path(const char *path, KvpValue *newvalue) noexcept
Set the value with the key in a subframe following the keys in path, replacing and returning the old ...
Definition: kvp_frame.cpp:164

◆ to_string()

std::string KvpFrame::to_string ( ) const
noexcept

Make a string representation of the frame.

Mostly useful for debugging.

Returns
A std::string representing the frame and all its children.

Definition at line 182 of file kvp_frame.cpp.

183 {
184  std::ostringstream ret;
185  ret << "{\n";
186 
187  std::for_each(m_valuemap.begin(), m_valuemap.end(),
188  [this,&ret](const map_type::value_type &a)
189  {
190  ret << " ";
191  if (a.first)
192  ret << a.first;
193  ret << " => ";
194  if (a.second)
195  ret << a.second->to_string();
196  ret << ",\n";
197  }
198  );
199 
200  ret << "}\n";
201  return ret.str();
202 }

Friends

◆ compare

int compare ( const KvpFrameImpl ,
const KvpFrameImpl  
)
friend

If the first KvpFrameImpl has an item that the second does not, 1 is returned.

The first item within the two KvpFrameImpl that is not similar, that comparison is returned. If all the items within the first KvpFrameImpl match items within the second, but the second has more elements, -1 is returned. Otherwise, 0 is returned.

Definition at line 272 of file kvp_frame.cpp.

273 {
274  for (const auto & a : one.m_valuemap)
275  {
276  auto otherspot = two.m_valuemap.find(a.first);
277  if (otherspot == two.m_valuemap.end())
278  {
279  return 1;
280  }
281  auto comparison = compare(a.second,otherspot->second);
282 
283  if (comparison != 0)
284  return comparison;
285  }
286 
287  if (one.m_valuemap.size() < two.m_valuemap.size())
288  return -1;
289  return 0;
290 }
friend int compare(const KvpFrameImpl &, const KvpFrameImpl &) noexcept
If the first KvpFrameImpl has an item that the second does not, 1 is returned.
Definition: kvp_frame.cpp:272