22
33#include < gdkmm.h>
44
5- template <class T >
6- static void iterTo (Glib::VariantIter & iter, T & to)
5+ namespace
76{
8- Glib::Variant<T> var;
9- iter.next_value (var);
10- to = var.get ();
7+ template <class ... T>
8+ void extractValues (const Glib::VariantBase & variant, T&... values)
9+ {
10+ std::tie (values...) = Glib::VariantBase::cast_dynamic<Glib::Variant<std::tuple<T...>>>(variant).get ();
1111}
1212
1313template <class K >
14- static K getHint (const std::map<std::string, Glib::VariantBase> & map, const std::string & key)
14+ K getHint (const std::map<std::string, Glib::VariantBase> & map, const std::string & key)
1515{
1616 if (map.count (key) != 0 )
1717 {
1818 const auto & val = map.at (key);
1919 if (val.is_of_type (Glib::Variant<K>::variant_type ()))
2020 {
21- return Glib::VariantBase::cast_dynamic<Glib::Variant<K>>(map. at (key) ).get ();
21+ return Glib::VariantBase::cast_dynamic<Glib::Variant<K>>(val ).get ();
2222 }
2323 }
2424
@@ -27,41 +27,29 @@ static K getHint(const std::map<std::string, Glib::VariantBase> & map, const std
2727
2828Glib::RefPtr<Gdk::Pixbuf> pixbufFromVariant (const Glib::VariantBase & variant)
2929{
30- if (!variant.is_of_type (Glib::VariantType (" iiibiiay" )))
31- {
32- throw std::invalid_argument (" Cannot create pixbuf from variant." );
33- }
34-
35- auto iter = Glib::VariantIter (variant);
3630 gint32 width;
3731 gint32 height;
3832 gint32 rowstride;
3933 bool has_alpha;
4034 gint32 bits_per_sample;
4135 gint32 channels;
42-
43- iterTo (iter, width);
44- iterTo (iter, height);
45- iterTo (iter, rowstride);
46- iterTo (iter, has_alpha);
47- iterTo (iter, bits_per_sample);
48- iterTo (iter, channels);
49-
50- Glib::VariantBase data_var;
51- iter.next_value (data_var);
36+ std::vector<guint8> data;
37+ extractValues (variant, width, height, rowstride, has_alpha, bits_per_sample, channels, data);
5238
5339 // for integer positive A, floor((A + 7) / 8) = ceil(A / 8)
5440 gulong pixel_size = (channels * bits_per_sample + 7 ) / 8 ;
55- if (data_var. get_size () != ((gulong)height - 1 ) * (gulong)rowstride + (gulong)width * pixel_size)
41+ if (data. size () != ((gulong)height - 1 ) * (gulong)rowstride + (gulong)width * pixel_size)
5642 {
5743 throw std::invalid_argument (
5844 " Cannot create pixbuf from variant: expected data size doesn't equal actual one." );
5945 }
6046
61- const auto *data = (guint8*)(g_memdup2 (data_var.get_data (), data_var.get_size ()));
62- return Gdk::Pixbuf::create_from_data (data, Gdk::COLORSPACE_RGB , has_alpha, bits_per_sample, width, height,
63- rowstride);
47+ auto *data_ptr = new auto (std::move (data));
48+ return Gdk::Pixbuf::create_from_data (data_ptr->data (),
49+ Gdk::COLORSPACE_RGB , has_alpha, bits_per_sample, width, height,
50+ rowstride, [data_ptr] (auto *) { delete data_ptr; });
6451}
52+ } // namespace
6553
6654Notification::Hints::Hints (const std::map<std::string, Glib::VariantBase> & map)
6755{
@@ -73,7 +61,7 @@ Notification::Hints::Hints(const std::map<std::string, Glib::VariantBase> & map)
7361 image_data = pixbufFromVariant (map.at (" image-data" ));
7462 } else if (map.count (" icon_data" ) != 0 )
7563 {
76- image_data = pixbufFromVariant (map.at (" image_data " ));
64+ image_data = pixbufFromVariant (map.at (" icon_data " ));
7765 }
7866
7967 image_path = getHint<Glib::ustring>(map, " image-path" );
@@ -94,29 +82,13 @@ Notification::Hints::Hints(const std::map<std::string, Glib::VariantBase> & map)
9482
9583Notification::Notification (const Glib::VariantContainerBase & parameters, const Glib::ustring & sender)
9684{
97- static const auto REQUIRED_TYPE = Glib::VariantType (" (susssasa{sv}i)" );
98- if (!parameters.is_of_type (REQUIRED_TYPE ))
99- {
100- throw std::invalid_argument (" NotificationInfo: parameters type must be (susssasa{sv}i)" );
101- }
102-
103- Glib::VariantBase params_var;
104- parameters.get_normal_form (params_var);
105- auto iter = Glib::VariantIter (params_var);
106- iterTo (iter, app_name);
107- iterTo (iter, id);
85+ std::map<std::string, Glib::VariantBase> hints_map;
86+ extractValues (parameters, app_name, id, app_icon, summary, body, actions, hints_map, expire_time);
10887 if (id == 0 )
10988 {
11089 id = ++Notification::notifications_count;
11190 }
11291
113- iterTo (iter, app_icon);
114- iterTo (iter, summary);
115- iterTo (iter, body);
116- iterTo (iter, actions);
117-
118- std::map<std::string, Glib::VariantBase> hints_map;
119- iterTo (iter, hints_map);
12092 hints = Hints (hints_map);
12193
12294 additional_info.recv_time = std::time (nullptr );
0 commit comments