GnuCash  4.11-11-ge9df8d41d2+
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  KvpFrameImpl
 Implements KvpFrame. More...
 
class  KvpFrameImpl::cstring_comparer
 
struct  KvpValue
 Implements KvpValue using boost::variant. More...
 

Typedefs

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

Functions

bool KvpFrameImpl::cstring_comparer::operator() (const char *one, const char *two) const
 
 KvpFrameImpl::KvpFrameImpl (const KvpFrameImpl &) noexcept
 Performs a deep copy.
 
 KvpFrameImpl::~KvpFrameImpl () noexcept
 Perform a deep delete.
 
KvpValue * KvpFrameImpl::set (Path path, 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 * KvpFrameImpl::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 KvpFrameImpl::to_string () const noexcept
 Make a string representation of the frame. More...
 
std::string KvpFrameImpl::to_string (std::string const &) const noexcept
 Make a string representation of the frame with the specified string prefixed to every item in the frame. More...
 
std::vector< std::string > KvpFrameImpl::get_keys () const noexcept
 Report the keys in the immediate frame. More...
 
KvpValue * KvpFrameImpl::get_slot (Path keys) noexcept
 Get the value for the tail of the path or nullptr if it doesn't exist. More...
 
template<typename func_type , typename data_type >
void KvpFrameImpl::for_each_slot_temp (func_type const &, data_type &) const noexcept
 The function should be of the form: <anything> func (char const *, KvpValue *, data_type &); Do not pass nullptr as the function.
 
template<typename func_type >
void KvpFrameImpl::for_each_slot_temp (func_type const &) const noexcept
 
template<typename func_type , typename data_type >
void KvpFrameImpl::for_each_slot_prefix (std::string const &prefix, func_type const &, data_type &) const noexcept
 Like for_each_slot, but doesn't traverse nested values. More...
 
template<typename func_type >
void KvpFrameImpl::for_each_slot_prefix (std::string const &prefix, func_type const &) const noexcept
 
std::vector< KvpEntry > KvpFrameImpl::flatten_kvp (void) const noexcept
 Returns all keys and values of this frame recursively, flattening the frame-containing values.
 
bool KvpFrameImpl::empty () const noexcept
 Test for emptiness. More...
 
map_type::iterator KvpFrameImpl::begin ()
 
map_type::iterator KvpFrameImpl::end ()
 
int compare (const KvpValueImpl *, const KvpValue *) noexcept
 

Friends

int KvpFrameImpl::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
 If the first KvpFrameImpl has an item that the second does not, 1 is returned. More...
 
int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept
 
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...
 
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 *, GValue const *value, unsigned count,...)
 Sets a KVP slot to a value from a GValue. More...
 
void qof_instance_get_kvp (QofInstance *, GValue *value, unsigned count,...)
 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 221 of file kvp-frame.cpp.

222 {
223  for (const auto & a : one.m_valuemap)
224  {
225  auto otherspot = two.m_valuemap.find(a.first);
226  if (otherspot == two.m_valuemap.end())
227  {
228  return 1;
229  }
230  auto comparison = compare(a.second,otherspot->second);
231 
232  if (comparison != 0)
233  return comparison;
234  }
235 
236  if (one.m_valuemap.size() < two.m_valuemap.size())
237  return -1;
238  return 0;
239 }
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:221

◆ empty()

bool KvpFrameImpl::empty ( ) const
inlinenoexcept

Test for emptiness.

Returns
true if the frame contains nothing.

Definition at line 226 of file kvp-frame.hpp.

226 { return m_valuemap.empty(); }

◆ for_each_slot_prefix()

template<typename func_type , typename data_type >
void KvpFrameImpl::for_each_slot_prefix ( std::string const &  prefix,
func_type const &  ,
data_type &   
) const
noexcept

Like for_each_slot, but doesn't traverse nested values.

This will only loop over root-level values whose keys match the specified prefix.

◆ get_keys()

std::vector< std::string > KvpFrameImpl::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 193 of file kvp-frame.cpp.

194 {
195  std::vector<std::string> ret;
196  ret.reserve (m_valuemap.size());
197  std::for_each(m_valuemap.begin(), m_valuemap.end(),
198  [&ret](const KvpFrameImpl::map_type::value_type &a)
199  {
200  ret.push_back(a.first);
201  }
202  );
203  return ret;
204 }

◆ get_slot()

KvpValue * KvpFrameImpl::get_slot ( Path  keys)
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 149 of file kvp-frame.cpp.

150 {
151  auto key = path.back();
152  path.pop_back();
153  auto target = get_child_frame_or_nullptr (path);
154  if (!target)
155  return nullptr;
156  auto spot = target->m_valuemap.find (key.c_str ());
157  if (spot != target->m_valuemap.end ())
158  return spot->second;
159  return nullptr;
160 }

◆ 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 396 of file kvp-frame.cpp.

397 {
398  if (val == NULL || ! G_IS_VALUE (val)) return;
399  g_value_unset (val);
400  g_slice_free (GValue, val);
401 }

◆ 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 264 of file kvp-frame.cpp.

265 {
266  GValue *val;
267  gnc_numeric num;
268  Time64 tm;
269  GDate gdate;
270 
271  if (kval == NULL) return NULL;
272  val = g_slice_new0 (GValue);
273 
274  switch (kval->get_type())
275  {
276  case KvpValue::Type::INT64:
277  g_value_init (val, G_TYPE_INT64);
278  g_value_set_int64 (val, kval->get<int64_t>());
279  break;
280  case KvpValue::Type::DOUBLE:
281  g_value_init (val, G_TYPE_DOUBLE);
282  g_value_set_double (val, kval->get<double>());
283  break;
284  case KvpValue::Type::NUMERIC:
285  g_value_init (val, GNC_TYPE_NUMERIC);
286  num = kval->get<gnc_numeric>();
287  g_value_set_boxed (val, &num);
288  break;
289  case KvpValue::Type::STRING:
290  g_value_init (val, G_TYPE_STRING);
291  g_value_set_string (val, kval->get<const char*>());
292  break;
293  case KvpValue::Type::GUID:
294  g_value_init (val, GNC_TYPE_GUID);
295  g_value_set_boxed (val, kval->get<GncGUID*>());
296  break;
297  case KvpValue::Type::TIME64:
298  g_value_init (val, GNC_TYPE_TIME64);
299  tm = kval->get<Time64>();
300  g_value_set_boxed (val, &tm);
301  break;
302  case KvpValue::Type::GDATE:
303  g_value_init (val, G_TYPE_DATE);
304  gdate = kval->get<GDate>();
305  g_value_set_boxed (val, &gdate);
306  break;
307  case KvpValue::Type::GLIST:
308  {
309  GList *gvalue_list = NULL;
310  GList *kvp_list = kval->get<GList*>();
311  g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value,
312  &gvalue_list);
313  g_value_init (val, GNC_TYPE_VALUE_LIST);
314  gvalue_list = g_list_reverse (gvalue_list);
315  g_value_set_boxed (val, gvalue_list);
316  break;
317  }
318 /* No transfer of KVP frames outside of QofInstance-derived classes! */
319  case KvpValue::Type::FRAME:
320  PWARN ("Error! Attempt to transfer KvpFrame!");
321  default:
322  PWARN ("Error! Invalid KVP Transfer Request!");
323  g_slice_free (GValue, val);
324  val = NULL;
325  break;
326  }
327  return val;
328 }
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
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 331 of file kvp-frame.cpp.

332 {
333  KvpValue *val = NULL;
334  GType type;
335  if (gval == NULL)
336  return NULL;
337  type = G_VALUE_TYPE (gval);
338  g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
339 
340  if (type == G_TYPE_INT64)
341  val = new KvpValue(g_value_get_int64 (gval));
342  else if (type == G_TYPE_DOUBLE)
343  val = new KvpValue(g_value_get_double (gval));
344  else if (type == G_TYPE_BOOLEAN)
345  {
346  auto bval = g_value_get_boolean(gval);
347  if (bval)
348  val = new KvpValue(g_strdup("true"));
349  }
350  else if (type == GNC_TYPE_NUMERIC)
351  val = new KvpValue(*(gnc_numeric*)g_value_get_boxed (gval));
352  else if (type == G_TYPE_STRING)
353  {
354  auto string = g_value_get_string(gval);
355  if (string != nullptr)
356  val = new KvpValue(g_strdup(string));
357  }
358  else if (type == GNC_TYPE_GUID)
359  {
360  auto boxed = g_value_get_boxed(gval);
361  if (boxed != nullptr)
362  val = new KvpValue(guid_copy(static_cast<GncGUID*>(boxed)));
363  }
364  else if (type == GNC_TYPE_TIME64)
365  val = new KvpValue(*(Time64*)g_value_get_boxed (gval));
366  else if (type == G_TYPE_DATE)
367  val = new KvpValue(*(GDate*)g_value_get_boxed (gval));
368  else if (type == GNC_TYPE_VALUE_LIST)
369  {
370  GList *gvalue_list = (GList*)g_value_get_boxed (gval);
371  GList *kvp_list = NULL;
372  g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue,
373  &kvp_list);
374  kvp_list = g_list_reverse (kvp_list);
375  val = new KvpValue(kvp_list);
376 // g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset);
377 // gvalue_list = NULL;
378  }
379  else
380  PWARN ("Error! Don't know how to make a KvpValue from a %s",
381  G_VALUE_TYPE_NAME (gval));
382 
383  return val;
384 }
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:250

◆ 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 1317 of file qofbook.cpp.

1318 {
1319  KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1320  return root->get_slot(gslist_to_option_path(path));
1321 }

◆ 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 1259 of file qofbook.cpp.

1260 {
1261  load_cb (odb, book);
1262 }

◆ 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 1324 of file qofbook.cpp.

1325 {
1326  KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1327  if (path != nullptr)
1328  {
1329  Path path_v {str_KVP_OPTION_PATH};
1330  Path tmp_path;
1331  for (auto item = path; item != nullptr; item = g_slist_next(item))
1332  tmp_path.push_back(static_cast<const char*>(item->data));
1333  delete root->set_path(gslist_to_option_path(path), nullptr);
1334  }
1335  else
1336  delete root->set_path({str_KVP_OPTION_PATH}, nullptr);
1337 }

◆ 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 1265 of file qofbook.cpp.

1267 {
1268  /* Wrap this in begin/commit so that it commits only once instead of doing
1269  * so for every option. Qof_book_set_option will take care of dirtying the
1270  * book.
1271  */
1272  qof_book_begin_edit (book);
1273  save_cb (odb, book, clear);
1274  qof_book_commit_edit (book);
1275 }

◆ 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 1304 of file qofbook.cpp.

1305 {
1306  KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE (book));
1307  qof_book_begin_edit (book);
1308  delete root->set_path(gslist_to_option_path(path), value);
1309  qof_instance_set_dirty (QOF_INSTANCE (book));
1310  qof_book_commit_edit (book);
1311 
1312  // Also, mark any cached value as invalid
1313  book->cached_num_field_source_isvalid = FALSE;
1314 }

◆ qof_instance_get_kvp()

void qof_instance_get_kvp ( QofInstance *  ,
GValue *  value,
unsigned  count,
  ... 
)

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

Parameters
instThe QofInstance
keyThe 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 1085 of file qofinstance.cpp.

1086 {
1087  std::vector<std::string> path;
1088  va_list args;
1089  va_start (args, count);
1090  for (unsigned i{0}; i < count; ++i)
1091  path.push_back (va_arg (args, char const *));
1092  va_end (args);
1093  auto temp = gvalue_from_kvp_value (inst->kvp_data->get_slot (path));
1094  if (G_IS_VALUE (temp))
1095  {
1096  if (G_IS_VALUE (value))
1097  g_value_unset (value);
1098  g_value_init (value, G_VALUE_TYPE (temp));
1099  g_value_copy (temp, value);
1100  gnc_gvalue_free (temp);
1101  }
1102 }
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:396
GValue * gvalue_from_kvp_value(const KvpValue *kval)
Convert a kvp_value into a GValue.
Definition: kvp-frame.cpp:264

◆ 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 1049 of file qofinstance.cpp.

1050 {
1051  return (inst->kvp_data != NULL && !inst->kvp_data->empty());
1052 }

◆ qof_instance_set_kvp()

void qof_instance_set_kvp ( QofInstance *  ,
GValue const *  value,
unsigned  count,
  ... 
)

Sets a KVP slot to a value from a GValue.

Intermediate container frames will be created if necessary. Commits the change to the QofInstance.

Parameters
instThe QofInstance on which to set the value.
keyThe path to the slot.
valueA GValue containing an item of a type which KvpValue knows how to store.

Definition at line 1060 of file qofinstance.cpp.

1061 {
1062  std::vector<std::string> path;
1063  va_list args;
1064  va_start (args, count);
1065  for (unsigned i{0}; i < count; ++i)
1066  path.push_back (va_arg (args, char const *));
1067  va_end (args);
1068  delete inst->kvp_data->set_path (path, kvp_value_from_gvalue (value));
1069 }
KvpValue * kvp_value_from_gvalue(const GValue *gval)
Convert a gvalue into a kvpvalue.
Definition: kvp-frame.cpp:331

◆ set()

KvpValue * KvpFrameImpl::set ( Path  path,
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. 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 125 of file kvp-frame.cpp.

126 {
127  if (path.empty())
128  return nullptr;
129  auto key = path.back ();
130  path.pop_back ();
131  auto target = get_child_frame_or_nullptr (path);
132  if (!target)
133  return nullptr;
134  return target->set_impl (key, value);
135 }

◆ set_path()

KvpValue * KvpFrameImpl::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 138 of file kvp-frame.cpp.

139 {
140  auto key = path.back();
141  path.pop_back();
142  auto target = get_child_frame_or_create (path);
143  if (!target)
144  return nullptr;
145  return target->set_impl (key, value);
146 }

◆ to_string() [1/2]

std::string KvpFrameImpl::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 163 of file kvp-frame.cpp.

164 {
165  return to_string("");
166 }
std::string to_string() const noexcept
Make a string representation of the frame.
Definition: kvp-frame.cpp:163

◆ to_string() [2/2]

std::string KvpFrameImpl::to_string ( std::string const &  prefix) const
noexcept

Make a string representation of the frame with the specified string prefixed to every item in the frame.

Returns
A std::string representing all the children of the frame.

Definition at line 169 of file kvp-frame.cpp.

170 {
171  if (!m_valuemap.size())
172  return prefix;
173  std::ostringstream ret;
174  std::for_each(m_valuemap.begin(), m_valuemap.end(),
175  [this,&ret,&prefix](const map_type::value_type &a)
176  {
177  std::string new_prefix {prefix};
178  if (a.first)
179  {
180  new_prefix += a.first;
181  new_prefix += "/";
182  }
183  if (a.second)
184  ret << a.second->to_string(new_prefix) << "\n";
185  else
186  ret << new_prefix << "(null)\n";
187  }
188  );
189  return ret.str();
190 }

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 221 of file kvp-frame.cpp.

222 {
223  for (const auto & a : one.m_valuemap)
224  {
225  auto otherspot = two.m_valuemap.find(a.first);
226  if (otherspot == two.m_valuemap.end())
227  {
228  return 1;
229  }
230  auto comparison = compare(a.second,otherspot->second);
231 
232  if (comparison != 0)
233  return comparison;
234  }
235 
236  if (one.m_valuemap.size() < two.m_valuemap.size())
237  return -1;
238  return 0;
239 }
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:221