32 #include "kvp-value.hpp" 33 #include "kvp-frame.hpp" 41 static QofLogModule log_module =
"qof.kvp";
45 std::for_each(rhs.m_valuemap.begin(), rhs.m_valuemap.end(),
46 [
this](
const map_type::value_type & a)
50 this->m_valuemap.insert({key,val});
57 std::for_each(m_valuemap.begin(), m_valuemap.end(),
58 [](
const map_type::value_type &a){
67 KvpFrame::get_child_frame_or_nullptr (Path
const & path) noexcept
71 auto key = path.front ();
72 auto map_iter = m_valuemap.find (key.c_str ());
73 if (map_iter == m_valuemap.end ())
75 auto child = map_iter->second->get <KvpFrame *> ();
79 std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
80 return child->get_child_frame_or_nullptr (send);
84 KvpFrame::get_child_frame_or_create (Path
const & path) noexcept
88 auto key = path.front ();
89 auto spot = m_valuemap.find (key.c_str ());
90 if (spot == m_valuemap.end () || spot->second->get_type () != KvpValue::Type::FRAME)
91 delete set_impl (key.c_str (),
new KvpValue {
new KvpFrame});
93 std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
94 auto child_val = m_valuemap.at (key.c_str ());
95 auto child = child_val->get <KvpFrame *> ();
96 return child->get_child_frame_or_create (send);
101 KvpFrame::set_impl (std::string
const & key, KvpValue * value) noexcept
104 auto spot = m_valuemap.find (key.c_str ());
105 if (spot != m_valuemap.end ())
109 m_valuemap.erase (spot);
114 m_valuemap.emplace (cachedkey, value);
124 auto key = path.back ();
126 auto target = get_child_frame_or_nullptr (path);
129 return target->set_impl (key, value);
135 auto key = path.back();
137 auto target = get_child_frame_or_create (path);
140 return target->set_impl (key, value);
146 auto key = path.back();
148 auto target = get_child_frame_or_nullptr (path);
151 auto spot = target->m_valuemap.find (key.c_str ());
152 if (spot != target->m_valuemap.end ())
166 if (!m_valuemap.size())
168 std::ostringstream ret;
169 std::for_each(m_valuemap.begin(), m_valuemap.end(),
170 [&ret,&prefix](
const map_type::value_type &a)
172 std::string new_prefix {prefix};
175 new_prefix += a.first;
179 ret << a.second->to_string(new_prefix) <<
"\n";
181 ret << new_prefix <<
"(null)\n";
187 std::vector<std::string>
190 std::vector<std::string> ret;
191 ret.reserve (m_valuemap.size());
192 std::for_each(m_valuemap.begin(), m_valuemap.end(),
193 [&ret](
const KvpFrameImpl::map_type::value_type &a)
195 ret.push_back(a.first);
203 if (one && !two)
return 1;
204 if (!one && two)
return -1;
205 if (!one && !two)
return 0;
218 for (
const auto & a : one.m_valuemap)
220 auto otherspot = two.m_valuemap.find(a.first);
221 if (otherspot == two.m_valuemap.end())
225 auto comparison =
compare(a.second,otherspot->second);
231 if (one.m_valuemap.size() < two.m_valuemap.size())
239 if (kval == NULL)
return;
242 switch (kval->get_type())
244 case KvpValue::Type::INT64:
245 g_value_init (val, G_TYPE_INT64);
246 g_value_set_int64 (val, kval->get<int64_t>());
248 case KvpValue::Type::DOUBLE:
249 g_value_init (val, G_TYPE_DOUBLE);
250 g_value_set_double (val, kval->get<
double>());
252 case KvpValue::Type::NUMERIC:
253 g_value_init (val, GNC_TYPE_NUMERIC);
254 g_value_set_static_boxed (val, kval->get_ptr<gnc_numeric>());
256 case KvpValue::Type::STRING:
257 g_value_init (val, G_TYPE_STRING);
258 g_value_set_static_string (val, kval->get<
const char*>());
260 case KvpValue::Type::GUID:
261 g_value_init (val, GNC_TYPE_GUID);
262 g_value_set_static_boxed (val, kval->get<
GncGUID*>());
264 case KvpValue::Type::TIME64:
265 g_value_init (val, GNC_TYPE_TIME64);
266 g_value_set_boxed (val, kval->get_ptr<
Time64>());
268 case KvpValue::Type::GDATE:
269 g_value_init (val, G_TYPE_DATE);
270 g_value_set_static_boxed (val, kval->get_ptr<GDate>());
274 PWARN (
"Error! Invalid attempt to transfer Kvp type %d", kval->get_type());
282 KvpValue *val = NULL;
286 type = G_VALUE_TYPE (gval);
287 g_return_val_if_fail (G_VALUE_TYPE (gval), NULL);
289 if (type == G_TYPE_INT64)
290 val =
new KvpValue(g_value_get_int64 (gval));
291 else if (type == G_TYPE_DOUBLE)
292 val =
new KvpValue(g_value_get_double (gval));
293 else if (type == G_TYPE_BOOLEAN)
295 auto bval = g_value_get_boolean(gval);
297 val =
new KvpValue(g_strdup(
"true"));
299 else if (type == GNC_TYPE_NUMERIC)
300 val =
new KvpValue(*(gnc_numeric*)g_value_get_boxed (gval));
301 else if (type == G_TYPE_STRING)
303 auto string = g_value_get_string(gval);
304 if (
string !=
nullptr)
305 val =
new KvpValue(g_strdup(
string));
307 else if (type == GNC_TYPE_GUID)
309 auto boxed = g_value_get_boxed(gval);
310 if (boxed !=
nullptr)
311 val =
new KvpValue(
guid_copy(static_cast<GncGUID*>(boxed)));
313 else if (type == GNC_TYPE_TIME64)
314 val =
new KvpValue(*(
Time64*)g_value_get_boxed (gval));
315 else if (type == G_TYPE_DATE)
316 val =
new KvpValue(*(GDate*)g_value_get_boxed (gval));
318 PWARN (
"Error! Don't know how to make a KvpValue from a %s",
319 G_VALUE_TYPE_NAME (gval));
325 KvpFrame::flatten_kvp_impl(std::vector <std::string> path, std::vector <KvpEntry> & entries)
const noexcept
327 for (
auto const & entry : m_valuemap)
329 std::vector<std::string> new_path {path};
330 new_path.push_back(
"/");
331 if (entry.second->get_type() == KvpValue::Type::FRAME)
333 new_path.push_back(entry.first);
334 entry.second->get<KvpFrame*>()->flatten_kvp_impl(new_path, entries);
338 new_path.emplace_back (entry.first);
339 entries.emplace_back (new_path, entry.second);
344 std::vector <KvpEntry>
345 KvpFrame::flatten_kvp(
void)
const noexcept
347 std::vector <KvpEntry> ret;
348 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...