31 #include "kvp-value.hpp" 32 #include "kvp-frame.hpp" 40 static QofLogModule log_module =
"qof.kvp";
44 std::for_each(rhs.m_valuemap.begin(), rhs.m_valuemap.end(),
45 [
this](
const map_type::value_type & a)
49 this->m_valuemap.insert({key,val});
56 std::for_each(m_valuemap.begin(), m_valuemap.end(),
57 [](
const map_type::value_type &a){
66 KvpFrame::get_child_frame_or_nullptr (Path
const & path) noexcept
70 auto key = path.front ();
71 auto map_iter = m_valuemap.find (key.c_str ());
72 if (map_iter == m_valuemap.end ())
74 auto child = map_iter->second->get <KvpFrame *> ();
78 std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
79 return child->get_child_frame_or_nullptr (send);
83 KvpFrame::get_child_frame_or_create (Path
const & path) noexcept
87 auto key = path.front ();
88 auto spot = m_valuemap.find (key.c_str ());
89 if (spot == m_valuemap.end () || spot->second->get_type () != KvpValue::Type::FRAME)
90 delete set_impl (key.c_str (),
new KvpValue {
new KvpFrame});
92 std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
93 auto child_val = m_valuemap.at (key.c_str ());
94 auto child = child_val->get <KvpFrame *> ();
95 return child->get_child_frame_or_create (send);
100 KvpFrame::set_impl (std::string
const & key, KvpValue * value) noexcept
103 auto spot = m_valuemap.find (key.c_str ());
104 if (spot != m_valuemap.end ())
108 m_valuemap.erase (spot);
113 m_valuemap.emplace (cachedkey, value);
123 auto key = path.back ();
125 auto target = get_child_frame_or_nullptr (path);
128 return target->set_impl (key, value);
134 auto key = path.back();
136 auto target = get_child_frame_or_create (path);
139 return target->set_impl (key, value);
145 auto key = path.back();
147 auto target = get_child_frame_or_nullptr (path);
150 auto spot = target->m_valuemap.find (key.c_str ());
151 if (spot != target->m_valuemap.end ())
165 if (!m_valuemap.size())
167 std::ostringstream ret;
168 std::for_each(m_valuemap.begin(), m_valuemap.end(),
169 [&ret,&prefix](
const map_type::value_type &a)
171 std::string new_prefix {prefix};
174 new_prefix += a.first;
178 ret << a.second->to_string(new_prefix) <<
"\n";
180 ret << new_prefix <<
"(null)\n";
186 std::vector<std::string>
189 std::vector<std::string> ret;
190 ret.reserve (m_valuemap.size());
191 std::for_each(m_valuemap.begin(), m_valuemap.end(),
192 [&ret](
const KvpFrameImpl::map_type::value_type &a)
194 ret.push_back(a.first);
202 if (one && !two)
return 1;
203 if (!one && two)
return -1;
204 if (!one && !two)
return 0;
217 for (
const auto & a : one.m_valuemap)
219 auto otherspot = two.m_valuemap.find(a.first);
220 if (otherspot == two.m_valuemap.end())
224 auto comparison =
compare(a.second,otherspot->second);
230 if (one.m_valuemap.size() < two.m_valuemap.size())
238 if (kval == NULL)
return;
241 switch (kval->get_type())
243 case KvpValue::Type::INT64:
244 g_value_init (val, G_TYPE_INT64);
245 g_value_set_int64 (val, kval->get<int64_t>());
247 case KvpValue::Type::DOUBLE:
248 g_value_init (val, G_TYPE_DOUBLE);
249 g_value_set_double (val, kval->get<
double>());
251 case KvpValue::Type::NUMERIC:
252 g_value_init (val, GNC_TYPE_NUMERIC);
253 g_value_set_static_boxed (val, kval->get_ptr<gnc_numeric>());
255 case KvpValue::Type::STRING:
256 g_value_init (val, G_TYPE_STRING);
257 g_value_set_static_string (val, kval->get<
const char*>());
259 case KvpValue::Type::GUID:
260 g_value_init (val, GNC_TYPE_GUID);
261 g_value_set_static_boxed (val, kval->get<
GncGUID*>());
263 case KvpValue::Type::TIME64:
264 g_value_init (val, GNC_TYPE_TIME64);
265 g_value_set_boxed (val, kval->get_ptr<
Time64>());
267 case KvpValue::Type::GDATE:
268 g_value_init (val, G_TYPE_DATE);
269 g_value_set_static_boxed (val, kval->get_ptr<GDate>());
273 PWARN (
"Error! Invalid attempt to transfer Kvp type %d", kval->get_type());
281 KvpValue *val = NULL;
285 type = G_VALUE_TYPE (gval);
286 g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
288 if (type == G_TYPE_INT64)
289 val =
new KvpValue(g_value_get_int64 (gval));
290 else if (type == G_TYPE_DOUBLE)
291 val =
new KvpValue(g_value_get_double (gval));
292 else if (type == G_TYPE_BOOLEAN)
294 auto bval = g_value_get_boolean(gval);
296 val =
new KvpValue(g_strdup(
"true"));
298 else if (type == GNC_TYPE_NUMERIC)
299 val =
new KvpValue(*(gnc_numeric*)g_value_get_boxed (gval));
300 else if (type == G_TYPE_STRING)
302 auto string = g_value_get_string(gval);
303 if (
string !=
nullptr)
304 val =
new KvpValue(g_strdup(
string));
306 else if (type == GNC_TYPE_GUID)
308 auto boxed = g_value_get_boxed(gval);
309 if (boxed !=
nullptr)
310 val =
new KvpValue(
guid_copy(static_cast<GncGUID*>(boxed)));
312 else if (type == GNC_TYPE_TIME64)
313 val =
new KvpValue(*(
Time64*)g_value_get_boxed (gval));
314 else if (type == G_TYPE_DATE)
315 val =
new KvpValue(*(GDate*)g_value_get_boxed (gval));
317 PWARN (
"Error! Don't know how to make a KvpValue from a %s",
318 G_VALUE_TYPE_NAME (gval));
324 KvpFrame::flatten_kvp_impl(std::vector <std::string> path, std::vector <KvpEntry> & entries)
const noexcept
326 for (
auto const & entry : m_valuemap)
328 std::vector<std::string> new_path {path};
329 new_path.push_back(
"/");
330 if (entry.second->get_type() == KvpValue::Type::FRAME)
332 new_path.push_back(entry.first);
333 entry.second->get<KvpFrame*>()->flatten_kvp_impl(new_path, entries);
337 new_path.emplace_back (entry.first);
338 entries.emplace_back (new_path, entry.second);
343 std::vector <KvpEntry>
344 KvpFrame::flatten_kvp(
void)
const noexcept
346 std::vector <KvpEntry> ret;
347 flatten_kvp_impl({}, ret);
~KvpFrameImpl() noexcept
Perform a deep delete.
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
void gvalue_from_kvp_value(const KvpValue *kval, GValue *val)
Convert a kvp_value into a GValue.
std::string to_string() const noexcept
Make a string representation of the frame.
KvpValue * kvp_value_from_gvalue(const GValue *gval)
Convert a gvalue into a kvpvalue.
KvpValue * 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...
const char * qof_string_cache_insert(const char *key)
You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the ...
#define PWARN(format, args...)
Log a warning.
int compare(const KvpFrameImpl &one, const KvpFrameImpl &two) noexcept
If the first KvpFrameImpl has an item that the second does not, 1 is returned.
std::vector< std::string > get_keys() const noexcept
Report the keys in the immediate frame.
Implements KvpValue using boost::variant.
KvpValue * get_slot(Path keys) noexcept
Get the value for the tail of the path or nullptr if it doesn't exist.
KvpValue * 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 ...
The type used to store guids in C.
void qof_string_cache_remove(const char *key)
You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or...