~mandel/dbus-cpp/name-acquired

11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
1
/*
2
 * Copyright © 2012 Canonical Ltd->
3
 *
4
 * This program is free software: you can redistribute it and/or modify it
5
 * under the terms of the GNU Lesser General Public License version 3,
6
 * as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public License
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 *
16
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17
 */
18
11.2.33 by thomas-voss
Adjusted directory layout to match namespacing.
19
#include <core/dbus/message.h>
20
21
#include <core/dbus/codec.h>
22
#include <core/dbus/error.h>
23
#include <core/dbus/visibility.h>
24
25
#include <core/dbus/types/object_path.h>
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
26
11.2.30 by thomas-voss
More cleanup.
27
#include "message_p.h"
28
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
29
#include <dbus/dbus.h>
30
31
#include <exception>
32
#include <map>
33
#include <memory>
34
#include <ostream>
11.2.23 by thomas-voss
Further refactor and streamline the interface.
35
#include <sstream>
36
#include <stack>
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
37
#include <stdexcept>
38
11.2.32 by thomas-voss
Adjusted namespace to core::dbus.
39
namespace core
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
40
{
41
namespace dbus
42
{
16.1.5 by thomas-voss
Make sure that decoding of Variant and Any values is tested and works correctly.
43
Message::Reader::Reader()
44
{
45
}
46
11.2.23 by thomas-voss
Further refactor and streamline the interface.
47
Message::Reader::Reader(const std::shared_ptr<Message>& msg)
48
    : d(new Private(msg))
49
{
50
    if (!msg)
51
        throw std::runtime_error(
52
                "Precondition violated, cannot construct Reader for null message.");
53
}
54
55
Message::Reader::Reader(Message::Reader&& that) : d(std::move(that.d))
56
{
57
}
58
59
Message::Reader& Message::Reader::operator=(Message::Reader&& rhs)
60
{
61
    d = std::move(rhs.d);
62
    return *this;
63
}
64
65
Message::Reader::~Reader()
66
{
67
}
68
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
69
ArgumentType Message::Reader::type() const
70
{
71
    return static_cast<ArgumentType>(
72
                dbus_message_iter_get_arg_type(
73
                    std::addressof(d->iter)));
74
}
75
76
void Message::Reader::pop()
77
{
78
    dbus_message_iter_next(std::addressof(d->iter));
79
}
80
11.2.23 by thomas-voss
Further refactor and streamline the interface.
81
std::int8_t Message::Reader::pop_byte()
82
{
83
    d->ensure_argument_type_or_throw(ArgumentType::byte);
84
85
    std::int8_t result;
86
    dbus_message_iter_get_basic(
87
                std::addressof(d->iter),
88
                std::addressof(result));
89
    dbus_message_iter_next(std::addressof(d->iter));
90
    return result;
91
}
92
93
bool Message::Reader::pop_boolean()
94
{
95
    d->ensure_argument_type_or_throw(ArgumentType::boolean);
96
33.1.2 by Antti Kaijanmäki
use the existing dbus_bool_t
97
    dbus_bool_t result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
98
    dbus_message_iter_get_basic(
99
                std::addressof(d->iter),
100
                std::addressof(result));
101
    dbus_message_iter_next(std::addressof(d->iter));
33.1.2 by Antti Kaijanmäki
use the existing dbus_bool_t
102
    return !!result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
103
}
104
105
std::int16_t Message::Reader::pop_int16()
106
{
107
    d->ensure_argument_type_or_throw(ArgumentType::int16);
108
109
    std::int16_t result;
110
    dbus_message_iter_get_basic(
111
                std::addressof(d->iter),
112
                std::addressof(result));
113
    dbus_message_iter_next(std::addressof(d->iter));
114
    return result;
115
}
116
117
std::uint16_t Message::Reader::pop_uint16()
118
{
119
    d->ensure_argument_type_or_throw(ArgumentType::uint16);
120
121
    std::uint16_t result;
122
    dbus_message_iter_get_basic(
123
                std::addressof(d->iter),
124
                std::addressof(result));
125
    dbus_message_iter_next(std::addressof(d->iter));
126
    return result;
127
}
128
129
std::int32_t Message::Reader::pop_int32()
130
{
131
    d->ensure_argument_type_or_throw(ArgumentType::int32);
132
133
    std::int32_t result;
134
    dbus_message_iter_get_basic(
135
                std::addressof(d->iter),
136
                std::addressof(result));
137
    dbus_message_iter_next(std::addressof(d->iter));
138
    return result;
139
}
140
141
std::uint32_t Message::Reader::pop_uint32()
142
{
143
    d->ensure_argument_type_or_throw(ArgumentType::uint32);
144
    std::uint32_t result;
145
    dbus_message_iter_get_basic(
146
                std::addressof(d->iter),
147
                std::addressof(result));
148
    dbus_message_iter_next(std::addressof(d->iter));
149
    return result;
150
}
151
152
std::int64_t Message::Reader::pop_int64()
153
{
154
    d->ensure_argument_type_or_throw(ArgumentType::int64);
155
156
    std::int64_t result;
157
    dbus_message_iter_get_basic(
158
                std::addressof(d->iter),
159
                std::addressof(result));
160
    dbus_message_iter_next(std::addressof(d->iter));
161
    return result;
162
}
163
164
std::uint64_t Message::Reader::pop_uint64()
165
{
166
    d->ensure_argument_type_or_throw(ArgumentType::uint64);
167
168
    std::uint64_t result;
169
    dbus_message_iter_get_basic(
170
                std::addressof(d->iter),
171
                std::addressof(result));
172
    dbus_message_iter_next(std::addressof(d->iter));
173
    return result;
174
}
175
176
double Message::Reader::pop_floating_point()
177
{
178
    d->ensure_argument_type_or_throw(ArgumentType::floating_point);
179
180
    double result;
181
    dbus_message_iter_get_basic(
182
                std::addressof(d->iter),
183
                std::addressof(result));
184
    dbus_message_iter_next(std::addressof(d->iter));
185
    return result;
186
}
187
188
const char* Message::Reader::pop_string()
189
{
190
    d->ensure_argument_type_or_throw(ArgumentType::string);
191
192
    return d->pop_string_unchecked();
193
}
194
195
types::ObjectPath Message::Reader::pop_object_path()
196
{
197
    d->ensure_argument_type_or_throw(ArgumentType::object_path);
198
199
    return types::ObjectPath(d->pop_string_unchecked());
200
}
201
202
types::Signature Message::Reader::pop_signature()
203
{
204
    d->ensure_argument_type_or_throw(ArgumentType::signature);
205
206
    return types::Signature(d->pop_string_unchecked());
207
}
208
209
types::UnixFd Message::Reader::pop_unix_fd()
210
{
211
    d->ensure_argument_type_or_throw(ArgumentType::unix_fd);
212
213
    int result = -1;
214
    dbus_message_iter_get_basic(
215
                std::addressof(d->iter),
216
                std::addressof(result));
217
    dbus_message_iter_next(std::addressof(d->iter));
218
    return types::UnixFd(result);
219
}
220
221
Message::Reader Message::Reader::pop_array()
222
{
223
    Reader result(d->msg);
224
    dbus_message_iter_recurse(
225
                std::addressof(d->iter),
226
                std::addressof(result.d->iter));
227
    dbus_message_iter_next(std::addressof(d->iter));
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
228
    return result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
229
}
230
231
Message::Reader Message::Reader::pop_structure()
232
{
233
    Reader result(d->msg);
234
    dbus_message_iter_recurse(
235
                std::addressof(d->iter),
236
                std::addressof(result.d->iter));
237
    dbus_message_iter_next(std::addressof(d->iter));
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
238
    return result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
239
}
240
241
Message::Reader Message::Reader::pop_variant()
242
{
243
    Reader result(d->msg);
244
    dbus_message_iter_recurse(
245
                std::addressof(d->iter),
246
                std::addressof(result.d->iter));
247
    dbus_message_iter_next(std::addressof(d->iter));
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
248
    return result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
249
}
250
251
Message::Reader Message::Reader::pop_dict_entry()
252
{
253
    Reader result(d->msg);
254
    dbus_message_iter_recurse(
255
                std::addressof(d->iter),
256
                std::addressof(result.d->iter));
257
    dbus_message_iter_next(std::addressof(d->iter));
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
258
    return result;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
259
}
260
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
261
const std::shared_ptr<Message>& Message::Reader::access_message()
262
{
263
    return d->msg;
264
}
265
11.2.23 by thomas-voss
Further refactor and streamline the interface.
266
Message::Writer::Writer(const std::shared_ptr<Message>& msg)
267
    : d(new Private{msg, DBusMessageIter()})
268
{
269
    if (!msg)
270
        throw std::runtime_error(
271
                "Precondition violated, cannot construct Writer for null message.");
272
273
    ::memset(std::addressof(d->iter), 0, sizeof(d->iter));
274
}
275
276
Message::Writer::~Writer()
277
{
278
}
279
280
Message::Writer::Writer(Message::Writer&& that) : d(std::move(that.d))
281
{
282
}
283
284
Message::Writer& Message::Writer::operator=(Message::Writer&& rhs)
285
{
286
    d = std::move(rhs.d);
287
    return *this;
288
}
289
290
void Message::Writer::push_byte(std::int8_t value)
291
{
292
    if (!dbus_message_iter_append_basic(
293
                std::addressof(d->iter),
294
                static_cast<int>(ArgumentType::byte),
295
                std::addressof(value)))
296
        throw std::runtime_error("Not enough memory to append data to message.");
297
}
298
299
void Message::Writer::push_boolean(bool value)
300
{
301
    if (!dbus_message_iter_append_basic(
302
                std::addressof(d->iter),
303
                static_cast<int>(ArgumentType::boolean),
99 by Manuel de la Pena
No need to add that extra step in the push_boolean method.
304
                std::addressof(value)))
11.2.23 by thomas-voss
Further refactor and streamline the interface.
305
        throw std::runtime_error("Not enough memory to append data to message.");
306
}
307
308
void Message::Writer::push_int16(std::int16_t value)
309
{
310
    if (!dbus_message_iter_append_basic(
311
                std::addressof(d->iter),
312
                static_cast<int>(ArgumentType::int16),
313
                std::addressof(value)))
314
        throw std::runtime_error("Not enough memory to append data to message.");
315
}
316
317
void Message::Writer::push_uint16(std::uint16_t value)
318
{
319
    if (!dbus_message_iter_append_basic(
320
                std::addressof(d->iter),
321
                static_cast<int>(ArgumentType::uint16),
322
                std::addressof(value)))
323
        throw std::runtime_error("Not enough memory to append data to message.");
324
}
325
326
void Message::Writer::push_int32(std::int32_t value)
327
{
328
    if (!dbus_message_iter_append_basic(
329
                std::addressof(d->iter),
330
                static_cast<int>(ArgumentType::int32),
331
                std::addressof(value)))
332
        throw std::runtime_error("Not enough memory to append data to message.");
333
}
334
335
void Message::Writer::push_uint32(std::uint32_t value)
336
{
337
    if (!dbus_message_iter_append_basic(
338
                std::addressof(d->iter),
339
                static_cast<int>(ArgumentType::uint32),
340
                std::addressof(value)))
341
        throw std::runtime_error("Not enough memory to append data to message.");
342
}
343
344
void Message::Writer::push_int64(std::int64_t value)
345
{
346
    if (!dbus_message_iter_append_basic(
347
                std::addressof(d->iter),
348
                static_cast<int>(ArgumentType::int64),
349
                std::addressof(value)))
350
        throw std::runtime_error("Not enough memory to append data to message.");
351
}
352
353
void Message::Writer::push_uint64(std::uint64_t value)
354
{
355
    if (!dbus_message_iter_append_basic(
356
                std::addressof(d->iter),
357
                static_cast<int>(ArgumentType::uint64),
358
                std::addressof(value)))
359
        throw std::runtime_error("Not enough memory to append data to message.");
360
}
361
362
void Message::Writer::push_floating_point(double value)
363
{
364
    if (!dbus_message_iter_append_basic(
365
                std::addressof(d->iter),
366
                static_cast<int>(ArgumentType::floating_point),
367
                std::addressof(value)))
368
        throw std::runtime_error("Not enough memory to append data to message.");
369
}
370
371
void Message::Writer::push_stringn(const char* value, std::size_t)
372
{
373
    if (!dbus_message_iter_append_basic(
374
                std::addressof(d->iter),
375
                static_cast<int>(ArgumentType::string),
376
                std::addressof(value)))
377
        throw std::runtime_error("Not enough memory to append data to message.");
378
}
379
380
void Message::Writer::push_object_path(const types::ObjectPath& value)
381
{
382
    const char* s = value.as_string().c_str();
383
    if (!dbus_message_iter_append_basic(
384
                std::addressof(d->iter),
385
                static_cast<int>(ArgumentType::object_path),
386
                &s))
387
        throw std::runtime_error("Not enough memory to append data to message.");
388
}
389
390
void Message::Writer::push_signature(const types::Signature& value)
391
{
392
    const char* s = value.as_string().c_str();
393
394
    if (!dbus_message_iter_append_basic(
395
                std::addressof(d->iter),
396
                static_cast<int>(ArgumentType::signature),
397
                &s))
398
        throw std::runtime_error("Not enough memory to append data to message.");
399
}
400
401
void Message::Writer::push_unix_fd(const types::UnixFd& value)
402
{
403
    if (!dbus_message_iter_append_basic(
404
                std::addressof(d->iter),
405
                static_cast<int>(ArgumentType::unix_fd),
406
                std::addressof(value.to_int())))
407
        throw std::runtime_error("Not enough memory to append data to message.");
408
}
409
410
Message::Writer Message::Writer::open_array(const types::Signature& signature)
411
{
412
    Writer w(d->msg);
413
    if (!dbus_message_iter_open_container(
414
                std::addressof(d->iter),
415
                static_cast<int>(ArgumentType::array),
416
                signature.as_string().c_str(),
417
                std::addressof(w.d->iter)))
418
        throw std::runtime_error("Problem opening container");
419
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
420
    return w;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
421
}
422
423
void Message::Writer::close_array(Message::Writer w)
424
{
425
    dbus_message_iter_close_container(
426
                std::addressof(d->iter),
427
                std::addressof(w.d->iter));
428
}
429
430
Message::Writer Message::Writer::open_structure()
431
{
432
    Writer w(d->msg);
433
    if (!dbus_message_iter_open_container(
434
                std::addressof(d->iter),
435
                static_cast<int>(ArgumentType::structure),
436
                nullptr,
437
                std::addressof(w.d->iter)))
438
        throw std::runtime_error("Problem opening container");
439
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
440
    return w;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
441
}
442
443
void Message::Writer::close_structure(Message::Writer w)
444
{
445
    dbus_message_iter_close_container(
446
                std::addressof(d->iter),
447
                std::addressof(w.d->iter));
448
}
449
450
Message::Writer Message::Writer::open_variant(const types::Signature& signature)
451
{
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
452
    // TODO(tvoss): We really should check that the signature refers to a
453
    // single complete type here.
454
11.2.23 by thomas-voss
Further refactor and streamline the interface.
455
    Writer w(d->msg);
456
    if (!dbus_message_iter_open_container(
457
                std::addressof(d->iter),
458
                static_cast<int>(ArgumentType::variant),
459
                signature.as_string().c_str(),
460
                std::addressof(w.d->iter)))
461
        throw std::runtime_error("Problem opening container");
462
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
463
    return w;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
464
}
465
466
void Message::Writer::close_variant(Writer w)
467
{
468
    dbus_message_iter_close_container(
469
                std::addressof(d->iter),
470
                std::addressof(w.d->iter));
471
}
472
473
Message::Writer Message::Writer::open_dict_entry()
474
{
475
    Writer w(d->msg);
476
    if (!dbus_message_iter_open_container(
477
                std::addressof(d->iter),
24.1.2 by thomas-voss
Clean up patch and augment test case.
478
                static_cast<int>(ArgumentType::dictionary_entry),
11.2.23 by thomas-voss
Further refactor and streamline the interface.
479
                nullptr,
480
                std::addressof(w.d->iter)))
481
        throw std::runtime_error("Problem opening container");
482
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
483
    return w;
11.2.23 by thomas-voss
Further refactor and streamline the interface.
484
}
485
486
void Message::Writer::close_dict_entry(Message::Writer w)
487
{
488
    dbus_message_iter_close_container(
489
                std::addressof(d->iter),
490
                std::addressof(w.d->iter));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
491
}
492
493
std::shared_ptr<Message> Message::make_method_call(
494
        const std::string& destination,
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
495
        const types::ObjectPath& path,
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
496
        const std::string& interface,
497
        const std::string& method)
498
{
499
    return std::shared_ptr<Message>(
500
                new Message(
11.2.30 by thomas-voss
More cleanup.
501
                    std::unique_ptr<Message::Private>(
502
                        new Message::Private(
503
                            dbus_message_new_method_call(
504
                                destination.c_str(),
505
                                path.as_string().c_str(),
506
                                interface.c_str(),
507
                                method.c_str())))));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
508
}
509
11.2.23 by thomas-voss
Further refactor and streamline the interface.
510
std::shared_ptr<Message> Message::make_method_return(const Message::Ptr& msg)
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
511
{
512
    return std::shared_ptr<Message>(
513
                new Message(
11.2.30 by thomas-voss
More cleanup.
514
                    std::unique_ptr<Message::Private>(
515
                        new Message::Private(
516
                            dbus_message_new_method_return(
517
                                msg->d->dbus_message.get())))));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
518
}
519
520
std::shared_ptr<Message> Message::make_signal(
521
        const std::string& path,
522
        const std::string& interface,
523
        const std::string& signal)
524
{
525
    return std::shared_ptr<Message>(
526
                new Message(
11.2.30 by thomas-voss
More cleanup.
527
                    std::unique_ptr<Message::Private>(
528
                        new Message::Private(
529
                            dbus_message_new_signal(
530
                                path.c_str(),
531
                                interface.c_str(),
532
                                signal.c_str())))));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
533
}
534
535
std::shared_ptr<Message> Message::make_error(
11.2.23 by thomas-voss
Further refactor and streamline the interface.
536
        const Message::Ptr& in_reply_to,
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
537
        const std::string& error_name,
538
        const std::string& error_desc)
539
{
540
    return std::shared_ptr<Message>(
541
                new Message(
11.2.30 by thomas-voss
More cleanup.
542
                    std::unique_ptr<Message::Private>(
543
                        new Message::Private(
544
                            dbus_message_new_error(
545
                                in_reply_to->d->dbus_message.get(),
546
                                error_name.c_str(),
547
                                error_desc.c_str())))));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
548
}
549
550
std::shared_ptr<Message> Message::from_raw_message(DBusMessage* msg)
551
{
11.2.30 by thomas-voss
More cleanup.
552
    return std::shared_ptr<Message>(
553
                new Message(
554
                    std::unique_ptr<Message::Private>(
555
                        new Message::Private(
556
                            msg, true))));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
557
}
558
559
Message::Type Message::type() const
560
{
11.2.30 by thomas-voss
More cleanup.
561
    return static_cast<Type>(dbus_message_get_type(d->dbus_message.get()));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
562
}
563
564
bool Message::expects_reply() const
565
{
11.2.30 by thomas-voss
More cleanup.
566
    return !dbus_message_get_no_reply(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
567
}
568
569
types::ObjectPath Message::path() const
570
{
11.2.30 by thomas-voss
More cleanup.
571
    return types::ObjectPath(dbus_message_get_path(d->dbus_message.get()));
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
572
}
573
574
std::string Message::member() const
575
{
11.2.30 by thomas-voss
More cleanup.
576
    return dbus_message_get_member(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
577
}
578
579
std::string Message::signature() const
580
{
11.2.30 by thomas-voss
More cleanup.
581
    return dbus_message_get_signature(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
582
}
583
584
std::string Message::interface() const
585
{
11.2.30 by thomas-voss
More cleanup.
586
    return dbus_message_get_interface(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
587
}
588
589
std::string Message::destination() const
590
{
11.2.30 by thomas-voss
More cleanup.
591
    return dbus_message_get_destination(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
592
}
593
594
std::string Message::sender() const
595
{
11.2.30 by thomas-voss
More cleanup.
596
    return dbus_message_get_sender(d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
597
}
598
599
Error Message::error() const
600
{
601
    if (type() != Message::Type::error)
602
        throw std::runtime_error("Message does not contain error information");
603
604
    Error result;
11.2.30 by thomas-voss
More cleanup.
605
    dbus_set_error_from_message(std::addressof(result.raw()), d->dbus_message.get());
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
606
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
607
    return result;
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
608
}
609
610
Message::Reader Message::reader()
611
{
11.2.23 by thomas-voss
Further refactor and streamline the interface.
612
    Reader result{shared_from_this()};
613
    if (!dbus_message_iter_init(
11.2.30 by thomas-voss
More cleanup.
614
                d->dbus_message.get(),
11.2.23 by thomas-voss
Further refactor and streamline the interface.
615
                std::addressof(result.d->iter)))
616
        throw std::runtime_error(
617
                "Could not initialize reader, message does not have arguments");
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
618
    return result;
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
619
}
620
621
Message::Writer Message::writer()
622
{
11.2.23 by thomas-voss
Further refactor and streamline the interface.
623
    Writer w(shared_from_this());
624
625
    dbus_message_iter_init_append(
11.2.30 by thomas-voss
More cleanup.
626
                d->dbus_message.get(),
11.2.23 by thomas-voss
Further refactor and streamline the interface.
627
                std::addressof(w.d->iter));
628
53.2.1 by Jussi Pakkanen
Get rid of unnecessary std::move in return statements.
629
    return w;
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
630
}
631
11.2.30 by thomas-voss
More cleanup.
632
void Message::ensure_serial_larger_than_zero_for_testing()
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
633
{
11.2.30 by thomas-voss
More cleanup.
634
    dbus_message_set_serial(d->dbus_message.get(), 2);
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
635
}
636
11.2.30 by thomas-voss
More cleanup.
637
Message::Message(std::unique_ptr<Message::Private> p)
638
    : d(std::move(p))
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
639
{
11.2.30 by thomas-voss
More cleanup.
640
    if (!d->dbus_message)
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
641
        throw std::runtime_error(
11.2.30 by thomas-voss
More cleanup.
642
                "Precondition violated, cannot construct Message from null DBusMessage.");
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
643
}
11.2.24 by thomas-voss
Fixed a test case that made a reader go out of scope.
644
645
Message::~Message()
646
{
647
}
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
648
649
std::shared_ptr<Message> Message::clone()
650
{
11.2.30 by thomas-voss
More cleanup.
651
    return std::shared_ptr<Message>(new Message(d->clone()));
11.2.29 by thomas-voss
Before refactoring message to be a pure virtual interface.
652
}
11.2.22 by thomas-voss
Add correct move semantics for Error and Result.
653
}
654
}