1 /*
2 * Copyright (c) 2014-2019, Nils Christopher Brause, Philipp Kerling
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include <wayland-util.hpp>
27
28 #include <cerrno>
29 #include <limits>
30 #include <system_error>
31
32 using namespace wayland;
33 using namespace wayland::detail;
34
35 namespace wayland
36 {
37 namespace detail
38 {
check_return_value(int return_value,const std::string & function_name)39 int check_return_value(int return_value, const std::string &function_name)
40 {
41 if(return_value < 0)
42 throw std::system_error(errno, std::generic_category(), function_name);
43 return return_value;
44 }
45 }
46 }
47
argument_t(const argument_t & arg)48 argument_t::argument_t(const argument_t &arg)
49 {
50 operator=(arg);
51 }
52
operator =(const argument_t & arg)53 argument_t &argument_t::operator=(const argument_t &arg)
54 {
55 // Check for self-assignment
56 if(this == &arg)
57 return *this;
58
59 if(is_array)
60 {
61 wl_array_release(argument.a);
62 delete argument.a;
63 }
64
65 is_array = arg.is_array;
66
67 if(arg.is_array)
68 {
69 argument.a = new wl_array;
70 wl_array_init(argument.a);
71 if(wl_array_copy(argument.a, arg.argument.a) < 0)
72 throw std::runtime_error("wl_array_copy failed.");
73 }
74 else
75 argument = arg.argument;
76
77 return *this;
78 }
79
~argument_t()80 argument_t::~argument_t() noexcept
81 {
82 if(is_array)
83 {
84 wl_array_release(argument.a);
85 delete argument.a;
86 }
87 }
88
argument_t(uint32_t i)89 argument_t::argument_t(uint32_t i)
90 {
91 argument.u = i;
92 }
93
argument_t(int32_t i)94 argument_t::argument_t(int32_t i)
95 {
96 argument.i = i;
97 }
98
argument_t(double f)99 argument_t::argument_t(double f)
100 {
101 argument.f = wl_fixed_from_double(f);
102 }
103
argument_t(const std::string & s)104 argument_t::argument_t(const std::string &s)
105 {
106 argument.s = s.c_str();
107 }
108
argument_t(wl_object * o)109 argument_t::argument_t(wl_object *o)
110 {
111 argument.o = o;
112 is_array = false;
113 }
114
argument_t(std::nullptr_t)115 argument_t::argument_t(std::nullptr_t)
116 {
117 argument.n = 0;
118 }
119
argument_t(const array_t & a)120 argument_t::argument_t(const array_t& a)
121 {
122 argument.a = new wl_array;
123 a.get(argument.a);
124 is_array = true;
125 }
126
fd(int fileno)127 argument_t argument_t::fd(int fileno)
128 {
129 if(fileno > std::numeric_limits<int32_t>::max())
130 throw std::invalid_argument("FD number too big");
131 argument_t arg;
132 arg.argument.h = static_cast<int32_t> (fileno);
133 return arg;
134 }
135
get_c_argument() const136 wl_argument argument_t::get_c_argument() const
137 {
138 return argument;
139 }
140
array_t(wl_array * arr)141 array_t::array_t(wl_array *arr)
142 {
143 wl_array_init(&a);
144 wl_array_copy(&a, arr);
145 }
146
get(wl_array * arr) const147 void array_t::get(wl_array *arr) const
148 {
149 wl_array_init(arr);
150 wl_array_copy(arr, const_cast<wl_array*>(&a));
151 }
152
array_t()153 array_t::array_t()
154 {
155 wl_array_init(&a);
156 }
157
array_t(const array_t & arr)158 array_t::array_t(const array_t &arr)
159 {
160 wl_array_init(&a);
161 wl_array_copy(&a, const_cast<wl_array*>(&arr.a));
162 }
163
array_t(array_t && arr)164 array_t::array_t(array_t &&arr) noexcept
165 {
166 wl_array_init(&a);
167 std::swap(a, arr.a);
168 }
169
~array_t()170 array_t::~array_t()
171 {
172 wl_array_release(&a);
173 }
174
operator =(const array_t & arr)175 array_t &array_t::operator=(const array_t &arr)
176 {
177 // Check for self-assignment
178 if(this == &arr)
179 return *this;
180
181 wl_array_release(&a);
182 wl_array_init(&a);
183 wl_array_copy(&a, const_cast<wl_array*>(&arr.a));
184 return *this;
185 }
186
operator =(array_t && arr)187 array_t &array_t::operator=(array_t &&arr) noexcept
188 {
189 std::swap(a, arr.a);
190 return *this;
191 }
192