File indexing completed on 2024-04-28 16:59:46

0001 /*
0002    Copyright (C) 2013 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 #include "message.h"
0025 #include "message_p.h"
0026 
0027 #include "arguments_p.h"
0028 #include "basictypeio.h"
0029 #include "malloccache.h"
0030 #include "stringtools.h"
0031 
0032 #ifndef DFERRY_SERDES_ONLY
0033 #include "icompletionlistener.h"
0034 #include "itransport.h"
0035 #endif
0036 
0037 #include <cassert>
0038 #include <cstring>
0039 #include <sstream>
0040 #include <thread>
0041 
0042 #include <iostream>
0043 
0044 #ifdef __unix__
0045 #include <unistd.h>
0046 #endif
0047 
0048 #ifdef BIGENDIAN
0049 static const byte s_thisMachineEndianness = 'B';
0050 #else
0051 static const byte s_thisMachineEndianness = 'l';
0052 #endif
0053 
0054 struct MsgAllocCaches
0055 {
0056     MallocCache<sizeof(MessagePrivate), 4> msgPrivate;
0057     MallocCache<256, 4> msgBuffer;
0058 };
0059 
0060 thread_local static MsgAllocCaches msgAllocCaches;
0061 
0062 static const byte s_storageForHeader[Message::UnixFdsHeader + 1] = {
0063     0, // dummy entry: there is no enum value for 0
0064     0x80 | 0, // PathHeader
0065     0x80 | 1, // InterfaceHeader
0066     0x80 | 2, // MethodHeader
0067     0x80 | 3, // ErrorNameHeader
0068        0 | 0, // ReplySerialHeader
0069     0x80 | 4, // DestinationHeader
0070     0x80 | 5, // SenderHeader
0071     0x80 | 6, // SignatureHeader
0072        0 | 1  // UnixFdsHeader
0073 };
0074 
0075 static bool isStringHeader(int field)
0076 {
0077     return s_storageForHeader[field] & 0x80;
0078 }
0079 
0080 static int indexOfHeader(int field)
0081 {
0082     return s_storageForHeader[field] & 0x7f;
0083 }
0084 
0085 static const Message::VariableHeader s_stringHeaderAtIndex[VarHeaderStorage::s_stringHeaderCount] = {
0086     Message::PathHeader,
0087     Message::InterfaceHeader,
0088     Message::MethodHeader,
0089     Message::ErrorNameHeader,
0090     Message::DestinationHeader,
0091     Message::SenderHeader,
0092     Message::SignatureHeader
0093 };
0094 
0095 static const Message::VariableHeader s_intHeaderAtIndex[VarHeaderStorage::s_intHeaderCount] = {
0096     Message::ReplySerialHeader,
0097     Message::UnixFdsHeader
0098 };
0099 
0100 VarHeaderStorage::VarHeaderStorage()
0101 {} // initialization values are in class declaration
0102 
0103 VarHeaderStorage::VarHeaderStorage(const VarHeaderStorage &other)
0104 {
0105     // ### very suboptimal
0106     for (int i = 0; i < Message::UnixFdsHeader + 1; i++) {
0107         Message::VariableHeader vh = static_cast<Message::VariableHeader>(i);
0108         if (other.hasHeader(vh)) {
0109             if (isStringHeader(vh)) {
0110                 setStringHeader(vh, other.stringHeader(vh));
0111             } else {
0112                 setIntHeader(vh, other.intHeader(vh));
0113             }
0114         }
0115     }
0116 }
0117 
0118 VarHeaderStorage::~VarHeaderStorage()
0119 {
0120     for (int i = 0; i < s_stringHeaderCount; i++) {
0121         const Message::VariableHeader field = s_stringHeaderAtIndex[i];
0122         if (hasHeader(field)) {
0123             // ~basic_string() instead of ~string() to work around a GCC bug
0124             stringHeaders()[i].~basic_string();
0125         }
0126     }
0127 }
0128 
0129 VarHeaderStorage &VarHeaderStorage::operator=(const VarHeaderStorage &other)
0130 {
0131     // ### very suboptimal
0132     for (int i = 0; i < Message::UnixFdsHeader + 1; i++) {
0133         Message::VariableHeader vh = static_cast<Message::VariableHeader>(i);
0134         if (other.hasHeader(vh)) {
0135             if (isStringHeader(vh)) {
0136                 setStringHeader(vh, other.stringHeader(vh));
0137             } else {
0138                 setIntHeader(vh, other.intHeader(vh));
0139             }
0140         } else {
0141             if (isStringHeader(vh)) {
0142                 clearStringHeader(vh);
0143             } else {
0144                 clearIntHeader(vh);
0145             }
0146         }
0147     }
0148     return *this;
0149 }
0150 
0151 bool VarHeaderStorage::hasHeader(Message::VariableHeader header) const
0152 {
0153     return m_headerPresenceBitmap & (1u << header);
0154 }
0155 
0156 bool VarHeaderStorage::hasStringHeader(Message::VariableHeader header) const
0157 {
0158     return hasHeader(header) && isStringHeader(header);
0159 }
0160 
0161 bool VarHeaderStorage::hasIntHeader(Message::VariableHeader header) const
0162 {
0163     return hasHeader(header) && !isStringHeader(header);
0164 }
0165 
0166 std::string VarHeaderStorage::stringHeader(Message::VariableHeader header) const
0167 {
0168     return hasStringHeader(header) ? stringHeaders()[indexOfHeader(header)] : std::string();
0169 }
0170 
0171 cstring VarHeaderStorage::stringHeaderRaw(Message::VariableHeader header)
0172 {
0173     // this one is supposed to be a const method in the intended use, but it is dangerous so
0174     // outwardly non-const is kind of okay as a warning
0175     cstring ret;
0176     assert(isStringHeader(header));
0177     if (hasHeader(header)) {
0178         std::string &str = stringHeaders()[indexOfHeader(header)];
0179         ret.ptr = const_cast<char *>(str.c_str());
0180         ret.length = str.length();
0181     }
0182     return ret;
0183 }
0184 
0185 void VarHeaderStorage::setStringHeader(Message::VariableHeader header, const std::string &value)
0186 {
0187     if (!isStringHeader(header)) {
0188         return;
0189     }
0190     const int idx = indexOfHeader(header);
0191     if (hasHeader(header)) {
0192         stringHeaders()[idx] = value;
0193     } else {
0194         m_headerPresenceBitmap |= 1u << header;
0195         new(stringHeaders() + idx) std::string(value);
0196     }
0197 }
0198 
0199 bool VarHeaderStorage::setStringHeader_deser(Message::VariableHeader header, cstring value)
0200 {
0201     assert(isStringHeader(header));
0202     if (hasHeader(header)) {
0203         return false;
0204     }
0205     m_headerPresenceBitmap |= 1u << header;
0206     new(stringHeaders() + indexOfHeader(header)) std::string(value.ptr, value.length);
0207     return true;
0208 }
0209 
0210 void VarHeaderStorage::clearStringHeader(Message::VariableHeader header)
0211 {
0212     if (!isStringHeader(header)) {
0213         return;
0214     }
0215     if (hasHeader(header)) {
0216         m_headerPresenceBitmap &= ~(1u << header);
0217         stringHeaders()[indexOfHeader(header)].~basic_string();
0218     }
0219 }
0220 
0221 uint32 VarHeaderStorage::intHeader(Message::VariableHeader header) const
0222 {
0223     return hasIntHeader(header) ? m_intHeaders[indexOfHeader(header)] : 0;
0224 }
0225 
0226 void VarHeaderStorage::setIntHeader(Message::VariableHeader header, uint32 value)
0227 {
0228     if (isStringHeader(header)) {
0229         return;
0230     }
0231     m_headerPresenceBitmap |= 1u << header;
0232     m_intHeaders[indexOfHeader(header)] = value;
0233 }
0234 
0235 bool VarHeaderStorage::setIntHeader_deser(Message::VariableHeader header, uint32 value)
0236 {
0237     assert(!isStringHeader(header));
0238     if (hasHeader(header)) {
0239         return false;
0240     }
0241     m_headerPresenceBitmap |= 1u << header;
0242     m_intHeaders[indexOfHeader(header)] = value;
0243     return true;
0244 }
0245 
0246 void VarHeaderStorage::clearIntHeader(Message::VariableHeader header)
0247 {
0248     if (isStringHeader(header)) {
0249         return;
0250     }
0251     m_headerPresenceBitmap &= ~(1u << header);
0252 }
0253 
0254 // TODO think of copying signature from and to output!
0255 
0256 MessagePrivate::MessagePrivate(Message *parent)
0257    : m_message(parent),
0258      m_bufferPos(0),
0259      m_isByteSwapped(false),
0260      m_state(Empty),
0261      m_messageType(Message::InvalidMessage),
0262      m_flags(0),
0263      m_protocolVersion(1),
0264      m_dirty(true),
0265      m_headerLength(0),
0266      m_headerPadding(0),
0267      m_bodyLength(0),
0268      m_serial(0)
0269 {}
0270 
0271 MessagePrivate::MessagePrivate(const MessagePrivate &other, Message *parent)
0272    : m_message(parent),
0273      m_bufferPos(other.m_bufferPos),
0274      m_isByteSwapped(other.m_isByteSwapped),
0275      m_state(other.m_state),
0276      m_messageType(other.m_messageType),
0277      m_flags(other.m_flags),
0278      m_protocolVersion(other.m_protocolVersion),
0279      m_dirty(other.m_dirty),
0280      m_headerLength(other.m_headerLength),
0281      m_headerPadding(other.m_headerPadding),
0282      m_bodyLength(other.m_bodyLength),
0283      m_serial(other.m_serial),
0284      m_error(other.m_error),
0285      m_mainArguments(other.m_mainArguments),
0286      m_varHeaders(other.m_varHeaders)
0287 {
0288     if (other.m_buffer.ptr) {
0289         // we don't keep pointers into the buffer (only indexes), right? right?
0290         m_buffer.ptr = static_cast<byte *>(malloc(other.m_buffer.length));
0291         m_buffer.length = other.m_buffer.length;
0292         // Simplification: don't try to figure out which part of other.m_buffer contains "valid" data,
0293         // just copy everything.
0294         memcpy(m_buffer.ptr, other.m_buffer.ptr, other.m_buffer.length);
0295 #ifdef __unix__
0296         // TODO ensure all "actual" file descriptor handling everywhere is inside this ifdef
0297         // (note conditional compilation of whole file localsocket.cpp)
0298         argUnixFds()->clear();
0299         std::vector<int> *otherUnixFds = const_cast<MessagePrivate &>(other).argUnixFds();
0300         argUnixFds()->reserve(otherUnixFds->size());
0301         for (int fd : *otherUnixFds) {
0302             int fdCopy = ::dup(fd);
0303             if (fdCopy == -1) {
0304                 // TODO error...
0305             }
0306             argUnixFds()->push_back(fdCopy);
0307         }
0308 #endif
0309     } else {
0310         assert(!m_buffer.length);
0311     }
0312     // ### Maybe warn when copying a Message which is currently (de)serializing. It might even be impossible
0313     //     to do that from client code. If that is the case, the "warning" could even be an assertion because
0314     //     we should never do such a thing.
0315 }
0316 
0317 MessagePrivate::~MessagePrivate()
0318 {
0319     clear(/* onlyReleaseResources = */ true);
0320 }
0321 
0322 Message::Message()
0323    : d(new(msgAllocCaches.msgPrivate.allocate()) MessagePrivate(this))
0324 {
0325 }
0326 
0327 Message::Message(Message &&other)
0328    : d(other.d)
0329 {
0330     other.d = nullptr;
0331     d->m_message = this;
0332 }
0333 
0334 Message &Message::operator=(Message &&other)
0335 {
0336     if (this != &other) {
0337         if (d) {
0338             d->~MessagePrivate();
0339             msgAllocCaches.msgPrivate.free(d);
0340         }
0341         d = other.d;
0342         if (other.d) {
0343             other.d = nullptr;
0344             d->m_message = this;
0345         }
0346     }
0347     return *this;
0348 }
0349 
0350 Message::Message(const Message &other)
0351    : d(nullptr)
0352 {
0353     if (!other.d) {
0354         return;
0355     }
0356     d = new(msgAllocCaches.msgPrivate.allocate()) MessagePrivate(*other.d, this);
0357 }
0358 
0359 Message &Message::operator=(const Message &other)
0360 {
0361     if (this != &other) {
0362         if (d) {
0363             d->~MessagePrivate();
0364             msgAllocCaches.msgPrivate.free(d);
0365         }
0366         if (other.d) {
0367             // ### can be optimized by implementing and using assignment of MessagePrivate
0368             d = new(msgAllocCaches.msgPrivate.allocate()) MessagePrivate(*other.d, this);
0369         } else {
0370             d = nullptr;
0371         }
0372     }
0373     return *this;
0374 }
0375 
0376 Message::~Message()
0377 {
0378     if (d) {
0379         d->~MessagePrivate();
0380         msgAllocCaches.msgPrivate.free(d);
0381         d = nullptr;
0382     }
0383 }
0384 
0385 Error Message::error() const
0386 {
0387     return d->m_error;
0388 }
0389 
0390 void Message::setCall(const std::string &path, const std::string &interface, const std::string &method)
0391 {
0392     setType(MethodCallMessage);
0393     setPath(path);
0394     setInterface(interface);
0395     setMethod(method);
0396 }
0397 
0398 void Message::setCall(const std::string &path, const std::string &method)
0399 {
0400     setType(MethodCallMessage);
0401     setPath(path);
0402     setMethod(method);
0403 }
0404 
0405 void Message::setReplyTo(const Message &call)
0406 {
0407     setType(MethodReturnMessage);
0408     setDestination(call.sender());
0409     setReplySerial(call.serial());
0410 }
0411 
0412 void Message::setErrorReplyTo(const Message &call, const std::string &errorName)
0413 {
0414     setType(ErrorMessage);
0415     setErrorName(errorName);
0416     setDestination(call.sender());
0417     setReplySerial(call.serial());
0418 }
0419 
0420 void Message::setSignal(const std::string &path, const std::string &interface, const std::string &method)
0421 {
0422     setType(SignalMessage);
0423     setPath(path);
0424     setInterface(interface);
0425     setMethod(method);
0426 }
0427 
0428 Message Message::createCall(const std::string &path, const std::string &interface, const std::string &method)
0429 {
0430     Message ret;
0431     ret.setCall(path, interface, method);
0432     return ret;
0433 }
0434 
0435 Message Message::createCall(const std::string &path, const std::string &method)
0436 {
0437     Message ret;
0438     ret.setCall(path, method);
0439     return ret;
0440 }
0441 
0442 Message Message::createReplyTo(const Message &call)
0443 {
0444     Message ret;
0445     ret.setReplyTo(call);
0446     return ret;
0447 }
0448 
0449 Message Message::createErrorReplyTo(const Message &call, const std::string &errorName)
0450 {
0451     Message ret;
0452     ret.setErrorReplyTo(call, errorName);
0453     return ret;
0454 }
0455 
0456 Message Message::createSignal(const std::string &path, const std::string &interface, const std::string &method)
0457 {
0458     Message ret;
0459     ret.setSignal(path, interface, method);
0460     return ret;
0461 }
0462 
0463 struct VarHeaderPrinter
0464 {
0465     Message::VariableHeader field;
0466     const char *name;
0467 };
0468 
0469 static const int stringHeadersCount = 7;
0470 static VarHeaderPrinter stringHeaderPrinters[stringHeadersCount] = {
0471     { Message::PathHeader, "path" },
0472     { Message::InterfaceHeader, "interface" },
0473     { Message::MethodHeader, "method" },
0474     { Message::ErrorNameHeader, "error name" },
0475     { Message::DestinationHeader, "destination" },
0476     { Message::SenderHeader, "sender" },
0477     { Message::SignatureHeader, "signature" }
0478 };
0479 
0480 static const int intHeadersCount = 2;
0481 static VarHeaderPrinter intHeaderPrinters[intHeadersCount] = {
0482     { Message::ReplySerialHeader, "reply serial" },
0483     { Message::UnixFdsHeader, "#unix fds" }
0484 };
0485 
0486 static const int messageTypeCount = 5;
0487 static const char *printableMessageTypes[messageTypeCount] = {
0488     "", // handled in code
0489     "Method call",
0490     "Method return",
0491     "Method error return",
0492     "Signal"
0493 };
0494 
0495 std::string Message::prettyPrint() const
0496 {
0497     std::string ret;
0498     if (d->m_messageType >= 1 && d->m_messageType < messageTypeCount) {
0499         ret += printableMessageTypes[d->m_messageType];
0500     } else {
0501         return std::string("Invalid message.\n");
0502     }
0503 
0504     std::ostringstream os;
0505     for (int i = 0; i < stringHeadersCount; i++ ) {
0506         bool isPresent = false;
0507         std::string str = stringHeader(stringHeaderPrinters[i].field, &isPresent);
0508         if (isPresent) {
0509             os << "; " << stringHeaderPrinters[i].name << ": \"" << str << '"';
0510 
0511         }
0512     }
0513     for (int i = 0; i < intHeadersCount; i++ ) {
0514         bool isPresent = false;
0515         uint32 intValue = intHeader(intHeaderPrinters[i].field, &isPresent);
0516         if (isPresent) {
0517             os << "; " << intHeaderPrinters[i].name << ": " << intValue;
0518         }
0519     }
0520     ret += os.str();
0521 
0522     ret += '\n';
0523     ret += d->m_mainArguments.prettyPrint();
0524     return ret;
0525 }
0526 
0527 Message::Type Message::type() const
0528 {
0529     return d->m_messageType;
0530 }
0531 
0532 void Message::setType(Type type)
0533 {
0534     if (d->m_messageType == type) {
0535         return;
0536     }
0537     d->m_dirty = true;
0538     d->m_messageType = type;
0539     setExpectsReply(d->m_messageType == MethodCallMessage);
0540 }
0541 
0542 uint32 Message::protocolVersion() const
0543 {
0544     return d->m_protocolVersion;
0545 }
0546 
0547 void Message::setSerial(uint32 serial)
0548 {
0549     d->m_serial = serial;
0550     if (d->m_state == MessagePrivate::Serialized && !d->m_dirty) {
0551         // performance hack: setSerial is likely to happen just before sending - don't re-serialize,
0552         // just patch it.
0553         byte *p = d->m_buffer.ptr;
0554         basic::writeUint32(p + 4 /* bytes */ + sizeof(uint32), d->m_serial);
0555         return;
0556     }
0557     d->m_dirty = true;
0558 }
0559 
0560 uint32 Message::serial() const
0561 {
0562     return d->m_serial;
0563 }
0564 
0565 std::string Message::path() const
0566 {
0567     return stringHeader(PathHeader, nullptr);
0568 }
0569 
0570 void Message::setPath(const std::string &path)
0571 {
0572     setStringHeader(PathHeader, path);
0573 }
0574 
0575 std::string Message::interface() const
0576 {
0577     return stringHeader(InterfaceHeader, nullptr);
0578 }
0579 
0580 void Message::setInterface(const std::string &interface)
0581 {
0582     setStringHeader(InterfaceHeader, interface);
0583 }
0584 
0585 std::string Message::method() const
0586 {
0587     return stringHeader(MethodHeader, nullptr);
0588 }
0589 
0590 void Message::setMethod(const std::string &method)
0591 {
0592     setStringHeader(MethodHeader, method);
0593 }
0594 
0595 std::string Message::errorName() const
0596 {
0597     return stringHeader(ErrorNameHeader, nullptr);
0598 }
0599 
0600 void Message::setErrorName(const std::string &errorName)
0601 {
0602     setStringHeader(ErrorNameHeader, errorName);
0603 }
0604 
0605 uint32 Message::replySerial() const
0606 {
0607     return intHeader(ReplySerialHeader, nullptr);
0608 }
0609 
0610 void Message::setReplySerial(uint32 replySerial)
0611 {
0612     setIntHeader(ReplySerialHeader, replySerial);
0613 }
0614 
0615 std::string Message::destination() const
0616 {
0617     return stringHeader(DestinationHeader, nullptr);
0618 }
0619 
0620 void Message::setDestination(const std::string &destination)
0621 {
0622     setStringHeader(DestinationHeader, destination);
0623 }
0624 
0625 std::string Message::sender() const
0626 {
0627     return stringHeader(SenderHeader, nullptr);
0628 }
0629 
0630 void Message::setSender(const std::string &sender)
0631 {
0632     setStringHeader(SenderHeader, sender);
0633 }
0634 
0635 std::string Message::signature() const
0636 {
0637     return stringHeader(SignatureHeader, nullptr);
0638 }
0639 
0640 uint32 Message::unixFdCount() const
0641 {
0642     return intHeader(UnixFdsHeader, nullptr);
0643 }
0644 
0645 std::string Message::stringHeader(VariableHeader header, bool *isPresent) const
0646 {
0647     const bool exists = d->m_varHeaders.hasStringHeader(header);
0648     if (isPresent) {
0649         *isPresent = exists;
0650     }
0651     return exists ? d->m_varHeaders.stringHeader(header) : std::string();
0652 }
0653 
0654 void Message::setStringHeader(VariableHeader header, const std::string &value)
0655 {
0656     if (header == SignatureHeader) {
0657         // ### warning? - this is a public method, and setting the signature separately does not make sense
0658         return;
0659     }
0660     d->m_dirty = true;
0661     d->m_varHeaders.setStringHeader(header, value);
0662 }
0663 
0664 uint32 Message::intHeader(VariableHeader header, bool *isPresent) const
0665 {
0666     const bool exists = d->m_varHeaders.hasIntHeader(header);
0667     if (isPresent) {
0668         *isPresent = exists;
0669     }
0670     return d->m_varHeaders.intHeader(header);
0671 }
0672 
0673 void Message::setIntHeader(VariableHeader header, uint32 value)
0674 {
0675     d->m_dirty = true;
0676     d->m_varHeaders.setIntHeader(header, value);
0677 }
0678 
0679 bool Message::expectsReply() const
0680 {
0681     return (d->m_flags & MessagePrivate::NoReplyExpectedFlag) == 0;
0682 }
0683 
0684 void Message::setExpectsReply(bool expectsReply)
0685 {
0686     if (expectsReply) {
0687         d->m_flags &= ~MessagePrivate::NoReplyExpectedFlag;
0688     } else {
0689         d->m_flags |= MessagePrivate::NoReplyExpectedFlag;
0690     }
0691 }
0692 
0693 bool Message::autoStartService() const
0694 {
0695     return (d->m_flags & MessagePrivate::NoAutoStartServiceFlag) == 0;
0696 }
0697 
0698 void Message::setAutoStartService(bool autoStart) const
0699 {
0700     if (autoStart) {
0701         d->m_flags &= ~MessagePrivate::NoAutoStartServiceFlag;
0702     } else {
0703         d->m_flags |= MessagePrivate::NoAutoStartServiceFlag;
0704     }
0705 }
0706 
0707 bool Message::interactiveAuthorizationAllowed() const
0708 {
0709     return (d->m_flags & MessagePrivate::NoAllowInteractiveAuthorizationFlag) == 0;
0710 }
0711 
0712 void Message::setInteractiveAuthorizationAllowed(bool allowInteractive) const
0713 {
0714     if (allowInteractive) {
0715         d->m_flags &= ~MessagePrivate::NoAllowInteractiveAuthorizationFlag;
0716     } else {
0717         d->m_flags |= MessagePrivate::NoAllowInteractiveAuthorizationFlag;
0718     }
0719 }
0720 
0721 void Message::setArguments(Arguments arguments)
0722 {
0723     d->m_dirty = true;
0724     d->m_error = arguments.error();
0725     const size_t fdCount = arguments.fileDescriptors().size();
0726     if (fdCount) {
0727         d->m_varHeaders.setIntHeader(Message::UnixFdsHeader, fdCount);
0728     } else {
0729         d->m_varHeaders.clearIntHeader(Message::UnixFdsHeader);
0730     }
0731 
0732     cstring signature = arguments.signature();
0733     if (signature.length) {
0734         d->m_varHeaders.setStringHeader(Message::SignatureHeader, toStdString(signature));
0735     } else {
0736         d->m_varHeaders.clearStringHeader(Message::SignatureHeader);
0737     }
0738     d->m_mainArguments = std::move(arguments);
0739 }
0740 
0741 const Arguments &Message::arguments() const
0742 {
0743     return d->m_mainArguments;
0744 }
0745 
0746 static const uint32 s_properFixedHeaderLength = 12;
0747 static const uint32 s_extendedFixedHeaderLength = 16;
0748 
0749 #ifndef DFERRY_SERDES_ONLY
0750 void MessagePrivate::receive(ITransport *transport)
0751 {
0752     if (m_state >= FirstIoState) { // Can only do one I/O operation at a time
0753         return;
0754     }
0755     transport->setReadListener(this);
0756     m_state = MessagePrivate::Receiving;
0757     m_headerLength = 0;
0758     m_bodyLength = 0;
0759 }
0760 
0761 bool Message::isReceiving() const
0762 {
0763     return d->m_state == MessagePrivate::Receiving;
0764 }
0765 
0766 void MessagePrivate::send(ITransport *transport)
0767 {
0768     if (!serialize()) {
0769         m_state = Serialized;
0770         assert(m_error.isError());
0771         if (!m_error.isError()) {
0772             // TODO This error code makes no sense here. We don't have a "generic error" code, and a specific
0773             // error code should have been set by whatever code detected the error. Hence the assertion.
0774             m_error = Error::MalformedReply;
0775         }
0776         // Note: We don't call notifyCompletionListener(); since all our timers are internal, we can
0777         // expect them to check for errors after this returns. Specifically, Connection::send() has
0778         // access to the timer in the PendingReply, so it can produce a deferred error notification
0779         // just like success notifications are deferred.
0780         return;
0781     }
0782     if (m_state != MessagePrivate::Sending) {
0783         transport->setWriteListener(this);
0784         m_state = MessagePrivate::Sending;
0785     }
0786 }
0787 
0788 bool Message::isSending() const
0789 {
0790     return d->m_state == MessagePrivate::Sending;
0791 }
0792 
0793 void MessagePrivate::setCompletionListener(ICompletionListener *listener)
0794 {
0795     m_completionListener = listener;
0796 }
0797 
0798 void MessagePrivate::notifyCompletionListener()
0799 {
0800     if (m_completionListener) {
0801         m_completionListener->handleCompletion(m_message);
0802     }
0803 }
0804 
0805 IO::Status MessagePrivate::handleTransportCanRead()
0806 {
0807     if (m_state != Receiving) {
0808         return IO::Status::InternalError;
0809     }
0810     IO::Status ret = IO::Status::OK;
0811     IO::Result ioRes;
0812     do {
0813         uint32 readMax = 0;
0814         if (!m_headerLength) {
0815             // the message might only consist of the header, so we must be careful to avoid reading
0816             // data meant for the next message
0817             readMax = s_extendedFixedHeaderLength - m_bufferPos;
0818         } else {
0819             // reading variable headers and/or body
0820             readMax = m_headerLength + m_bodyLength - m_bufferPos;
0821         }
0822         reserveBuffer(m_bufferPos + readMax);
0823 
0824         const bool headersDone = m_headerLength > 0 && m_bufferPos >= m_headerLength;
0825 
0826         if (m_bufferPos == 0) {
0827             // According to the DBus spec, file descriptors can arrive anywhere in the message, but
0828             // (assuming the message is written in one sendmsg() call) according to UNIX domain socket
0829             // documentation, file descriptors will arrive in the first byte of the sent block they are
0830             // attached to. We go with the UNIX domain socket documentation.
0831             // TODO review and test this for very large messages that cannot be sent in one call
0832             ioRes = readTransport()->readWithFileDescriptors(m_buffer.ptr + m_bufferPos, readMax,
0833                                                              argUnixFds());
0834         } else {
0835             ioRes = readTransport()->read(m_buffer.ptr + m_bufferPos, readMax);
0836         }
0837         m_bufferPos += ioRes.length;
0838         assert(m_bufferPos <= m_buffer.length);
0839 
0840         if (!headersDone) {
0841             if (m_headerLength == 0 && m_bufferPos >= s_extendedFixedHeaderLength) {
0842                 if (!deserializeFixedHeaders()) {
0843                     ret = IO::Status::RemoteClosed;
0844                     m_error = Error::MalformedReply;
0845                     break;
0846                 }
0847             }
0848             if (m_headerLength > 0 && m_bufferPos >= m_headerLength) {
0849                 // ### If we expected to receive the FDs at any point in the message (as opposed to just the
0850                 //     first byte), we'd have to verify FD count later. But we don't, so this is expedient.
0851                 if (!deserializeVariableHeaders() ||
0852                         m_varHeaders.intHeader(Message::UnixFdsHeader) != argUnixFds()->size()) {
0853                     ret = IO::Status::RemoteClosed;
0854                     m_error = Error::MalformedReply;
0855                     break;
0856                 }
0857             }
0858         }
0859         if (m_headerLength > 0 && m_bufferPos >= m_headerLength + m_bodyLength) {
0860             // all done!
0861             assert(m_bufferPos == m_headerLength + m_bodyLength);
0862             m_state = Serialized;
0863             chunk bodyData(m_buffer.ptr + m_headerLength, m_bodyLength);
0864             m_mainArguments = Arguments(nullptr, m_varHeaders.stringHeaderRaw(Message::SignatureHeader),
0865                                         bodyData, std::move(*argUnixFds()), m_isByteSwapped);
0866             assert(ioRes.status == IO::Status::OK && ret == IO::Status::OK);
0867             readTransport()->setReadListener(nullptr);
0868             notifyCompletionListener(); // do not access members after this because it might delete us!
0869             break;
0870         }
0871         if (!readTransport()->isOpen()) {
0872             ret = IO::Status::RemoteClosed;
0873             break;
0874         }
0875     } while (ioRes.status == IO::Status::OK);
0876 
0877     if (ret != IO::Status::OK) {
0878         clear();
0879         readTransport()->setReadListener(nullptr);
0880         if (!m_error.isError()) {
0881             // catch-all, we know that SOME error happened
0882             m_error = Error::RemoteDisconnect;
0883         }
0884         notifyCompletionListener();
0885     }
0886     return ret;
0887 }
0888 
0889 IO::Status MessagePrivate::handleTransportCanWrite()
0890 {
0891     if (m_state != Sending) {
0892         return IO::Status::InternalError;
0893     }
0894     while (true) {
0895         assert(m_buffer.length >= m_bufferPos);
0896         const uint32 toWrite = m_buffer.length - m_bufferPos;
0897         if (!toWrite) {
0898             m_state = Serialized;
0899             writeTransport()->setWriteListener(nullptr);
0900             notifyCompletionListener();
0901             break;
0902         }
0903         IO::Result ioRes;
0904         if (m_bufferPos == 0) {
0905             const size_t sendFdsCount = m_mainArguments.fileDescriptors().size();
0906             if (sendFdsCount == 0) {
0907                 ioRes = writeTransport()->write(chunk(m_buffer.ptr + m_bufferPos, toWrite));
0908             } else if (sendFdsCount > writeTransport()->supportedPassingUnixFdsCount()) {
0909                 m_error.setCode(Error::SendingTooManyUnixFds);
0910                 m_state = Serialized;
0911                 writeTransport()->setWriteListener(nullptr);
0912                 // ### Oh well, now we have a special Error value to pass through the stack
0913                 // (for error handling), but also notifyCompletionListener() for sucessful completion
0914                 // handling. Can we get rid of one or the other, or are there actually good reasons for
0915                 // the difference?
0916                 // Pro separation:
0917                 // - the arguments I came up with for not doing error handling through callbacks
0918                 // - the ...convenience?... of using callbacks
0919                 // - possibly better performance of happy path
0920                 //
0921                 // Contra separation:
0922                 // - two different mechanisms for similar things...
0923                 // - inconsistency - though is that really a problem? the situations are different.
0924                 // - suddenly IO code needs to ~know (at least pass through and be technically exposed to)
0925                 //   error values it doesn't know and can't handle itself; theoretically could use some
0926                 //   error value wrapping mechanism to pass through opaque errors).
0927                 return IO::Status::PayloadError; // the connection is fine, only this message has a problem
0928             } else {
0929                 ioRes = writeTransport()
0930                     ->writeWithFileDescriptors(chunk(m_buffer.ptr + m_bufferPos, toWrite),
0931                                                m_mainArguments.fileDescriptors());
0932             }
0933         } else {
0934             ioRes = writeTransport()->write(chunk(m_buffer.ptr + m_bufferPos, toWrite));
0935         }
0936         if (ioRes.status != IO::Status::OK) {
0937             m_error = Error::RemoteDisconnect;
0938             m_state = Serialized; // in a way... serialization has completed, unsuccessfully
0939             writeTransport()->setWriteListener(nullptr);
0940             notifyCompletionListener();
0941             return IO::Status::RemoteClosed;
0942         }
0943         m_bufferPos += ioRes.length;
0944     }
0945     return IO::Status::OK;
0946 }
0947 #endif // !DFERRY_SERDES_ONLY
0948 
0949 chunk Message::serializeAndView()
0950 {
0951     chunk ret; // one return variable to enable return value optimization (RVO) in gcc
0952     if (!d->serialize()) {
0953         return ret;
0954     }
0955     ret = d->m_buffer;
0956     return ret;
0957 }
0958 
0959 std::vector<byte> Message::save()
0960 {
0961     std::vector<byte> ret;
0962     if (!d->serialize()) {
0963         return ret;
0964     }
0965     ret.reserve(d->m_buffer.length);
0966     for (uint32 i = 0; i < d->m_buffer.length; i++) {
0967         ret.push_back(d->m_buffer.ptr[i]);
0968     }
0969     return ret;
0970 }
0971 
0972 void Message::deserializeAndTake(chunk memOwnership)
0973 {
0974     if (d->m_state >= MessagePrivate::FirstIoState) {
0975         free(memOwnership.ptr);
0976         return;
0977     }
0978     d->m_headerLength = 0;
0979     d->m_bodyLength = 0;
0980 
0981     d->clearBuffer();
0982     d->m_buffer = memOwnership;
0983     d->m_bufferPos = d->m_buffer.length;
0984 
0985     bool ok = d->m_buffer.length >= s_extendedFixedHeaderLength;
0986     ok = ok && d->deserializeFixedHeaders();
0987     ok = ok && d->m_buffer.length >= d->m_headerLength;
0988     ok = ok && d->deserializeVariableHeaders();
0989     ok = ok && d->m_buffer.length == d->m_headerLength + d->m_bodyLength;
0990 
0991     if (!ok) {
0992         if (!d->m_error.isError()) {
0993             d->m_error = Error::MalformedReply;
0994         }
0995         d->clear();
0996         return;
0997     }
0998 
0999     chunk bodyData(d->m_buffer.ptr + d->m_headerLength, d->m_bodyLength);
1000     d->m_mainArguments = Arguments(nullptr, d->m_varHeaders.stringHeaderRaw(SignatureHeader),
1001                                    bodyData, d->m_isByteSwapped);
1002     d->m_state = MessagePrivate::Serialized;
1003 }
1004 
1005 // This does not return bool because full validation of the main arguments would take quite
1006 // a few cycles. Validating only the header of the message doesn't seem to be worth it.
1007 void Message::load(const std::vector<byte> &data)
1008 {
1009     if (d->m_state >= MessagePrivate::FirstIoState || data.empty()) {
1010         return;
1011     }
1012     chunk buf;
1013     buf.length = data.size();
1014     buf.ptr = reinterpret_cast<byte *>(malloc(buf.length));
1015     memcpy(buf.ptr, &data[0], buf.length);
1016 
1017     deserializeAndTake(buf);
1018 }
1019 
1020 bool MessagePrivate::requiredHeadersPresent()
1021 {
1022     m_error = checkRequiredHeaders();
1023     return !m_error.isError();
1024 }
1025 
1026 Error MessagePrivate::checkRequiredHeaders() const
1027 {
1028     if (m_serial == 0) {
1029         return Error::MessageSerial;
1030     }
1031     if (m_protocolVersion != 1) {
1032         return Error::MessageProtocolVersion;
1033     }
1034 
1035     // might want to check for DestinationHeader if the transport is a bus (not peer-to-peer)
1036     // very strange that this isn't in the spec!
1037 
1038     switch (m_messageType) {
1039     case Message::SignalMessage:
1040         // required: PathHeader, InterfaceHeader, MethodHeader
1041         if (!m_varHeaders.hasStringHeader(Message::InterfaceHeader)) {
1042             return Error::MessageInterface;
1043         }
1044         // fall through
1045     case Message::MethodCallMessage:
1046         // required: PathHeader, MethodHeader
1047         if (!m_varHeaders.hasStringHeader(Message::PathHeader)) {
1048             return Error::MessagePath;
1049         }
1050         if (!m_varHeaders.hasStringHeader(Message::MethodHeader)) {
1051             return Error::MessageMethod;
1052         }
1053         break;
1054 
1055     case Message::ErrorMessage:
1056         // required: ErrorNameHeader, ReplySerialHeader
1057         if (!m_varHeaders.hasStringHeader(Message::ErrorNameHeader)) {
1058             return Error::MessageErrorName;
1059         }
1060         // fall through
1061     case Message::MethodReturnMessage:
1062         // required: ReplySerialHeader
1063         if (!m_varHeaders.hasIntHeader(Message::ReplySerialHeader) ) {
1064             return Error::MessageReplySerial;
1065         }
1066         break;
1067 
1068     case Message::InvalidMessage:
1069     default:
1070         return Error::MessageType;
1071     }
1072 
1073     return Error::NoError;
1074 }
1075 
1076 bool MessagePrivate::deserializeFixedHeaders()
1077 {
1078     assert(m_bufferPos >= s_extendedFixedHeaderLength);
1079     byte *p = m_buffer.ptr;
1080 
1081     byte endianness = *p++;
1082     if (endianness != 'l' && endianness != 'B') {
1083         return false;
1084     }
1085     m_isByteSwapped = endianness != s_thisMachineEndianness;
1086 
1087     // TODO validate the values read here
1088     m_messageType = static_cast<Message::Type>(*p++);
1089     m_flags = *p++;
1090     m_protocolVersion = *p++;
1091 
1092     m_bodyLength = basic::readUint32(p, m_isByteSwapped);
1093     m_serial = basic::readUint32(p + sizeof(uint32), m_isByteSwapped);
1094     // peek into the var-length header and use knowledge about array serialization to infer the
1095     // number of bytes still required for the header
1096     uint32 varArrayLength = basic::readUint32(p + 2 * sizeof(uint32), m_isByteSwapped);
1097     uint32 unpaddedHeaderLength = s_extendedFixedHeaderLength + varArrayLength;
1098     m_headerLength = align(unpaddedHeaderLength, 8);
1099     m_headerPadding = m_headerLength - unpaddedHeaderLength;
1100 
1101     return m_headerLength + m_bodyLength <= Arguments::MaxMessageLength;
1102 }
1103 
1104 bool MessagePrivate::deserializeVariableHeaders()
1105 {
1106     // use Arguments to parse the variable header fields
1107     // HACK: the fake first int argument is there to start the Arguments's data 8 byte aligned
1108     byte *base = m_buffer.ptr + s_properFixedHeaderLength - sizeof(int32);
1109     chunk headerData(base, m_headerLength - m_headerPadding - s_properFixedHeaderLength + sizeof(int32));
1110     cstring varHeadersSig("ia(yv)");
1111     Arguments argList(nullptr, varHeadersSig, headerData, m_isByteSwapped);
1112 
1113     Arguments::Reader reader(argList);
1114     assert(reader.isValid());
1115 
1116     if (reader.state() != Arguments::Int32) {
1117         return false;
1118     }
1119     reader.readInt32();
1120     if (reader.state() != Arguments::BeginArray) {
1121         return false;
1122     }
1123     reader.beginArray();
1124 
1125     while (reader.state() == Arguments::BeginStruct) {
1126         reader.beginStruct();
1127         const byte headerField = reader.readByte();
1128         if (headerField < Message::PathHeader || headerField > Message::UnixFdsHeader) {
1129             return false;
1130         }
1131         const Message::VariableHeader eHeader = static_cast<Message::VariableHeader>(headerField);
1132 
1133         reader.beginVariant();
1134 
1135         bool ok = true; // short-circuit evaluation ftw
1136         if (isStringHeader(headerField)) {
1137             if (headerField == Message::PathHeader) {
1138                 ok = ok && reader.state() == Arguments::ObjectPath;
1139                 ok = ok && m_varHeaders.setStringHeader_deser(eHeader, reader.readObjectPath());
1140             } else if (headerField == Message::SignatureHeader) {
1141                 ok = ok && reader.state() == Arguments::Signature;
1142                 // The spec allows having no signature header, which means "empty signature". However...
1143                 // We do not drop empty signature headers when deserializing, in order to preserve
1144                 // the original message contents. This could be useful for debugging and testing.
1145                 ok = ok && m_varHeaders.setStringHeader_deser(eHeader, reader.readSignature());
1146             } else {
1147                 ok = ok && reader.state() == Arguments::String;
1148                 ok = ok && m_varHeaders.setStringHeader_deser(eHeader, reader.readString());
1149             }
1150         } else {
1151             ok = ok && reader.state() == Arguments::Uint32;
1152             ok = ok && m_varHeaders.setIntHeader_deser(eHeader, reader.readUint32());
1153         }
1154 
1155         if (!ok) {
1156             return false;
1157         }
1158         reader.endVariant();
1159         reader.endStruct();
1160     }
1161     reader.endArray();
1162 
1163     // check that header->body padding is in fact zero filled
1164     base = m_buffer.ptr;
1165     for (uint32 i = m_headerLength - m_headerPadding; i < m_headerLength; i++) {
1166         if (base[i] != '\0') {
1167             return false;
1168         }
1169     }
1170 
1171     return reader.isFinished();
1172 }
1173 
1174 bool MessagePrivate::serialize()
1175 {
1176     if ((m_state == Serialized || m_state == Sending) && !m_dirty) {
1177         return true;
1178     }
1179     if (m_state >= FirstIoState) { // Marshalled data must not be touched while doing I/O
1180         return false;
1181     }
1182 
1183     clearBuffer();
1184 
1185     if (m_error.isError() || !requiredHeadersPresent()) {
1186         return false;
1187     }
1188 
1189     Arguments headerArgs = serializeVariableHeaders();
1190     if (headerArgs.data().length <= 0) {
1191         return false;
1192     }
1193 
1194     // we need to cut out alignment padding bytes 4 to 7 in the variable header data stream because
1195     // the original dbus code aligns based on address in the final data stream
1196     // (offset s_properFixedHeaderLength == 12), we align based on address in the Arguments's buffer
1197     // (offset 0) - note that our modification keeps the stream valid because length is measured from end
1198     // of padding
1199 
1200     assert(headerArgs.data().length > 0); // if this fails the headerLength hack will break down
1201 
1202     const uint32 unalignedHeaderLength = s_properFixedHeaderLength + headerArgs.data().length - sizeof(uint32);
1203     m_headerLength = align(unalignedHeaderLength, 8);
1204     m_bodyLength = m_mainArguments.data().length;
1205     const uint32 messageLength = m_headerLength + m_bodyLength;
1206 
1207     if (messageLength > Arguments::MaxMessageLength) {
1208         m_error.setCode(Error::ArgumentsTooLong);
1209         return false;
1210     }
1211 
1212     reserveBuffer(messageLength);
1213 
1214     serializeFixedHeaders();
1215 
1216     // copy header data: uint32 length...
1217     memcpy(m_buffer.ptr + s_properFixedHeaderLength, headerArgs.data().ptr, sizeof(uint32));
1218     // skip four bytes of padding and copy the rest
1219     memcpy(m_buffer.ptr + s_properFixedHeaderLength + sizeof(uint32),
1220            headerArgs.data().ptr + 2 * sizeof(uint32),
1221            headerArgs.data().length - 2 * sizeof(uint32));
1222     // zero padding between variable headers and message body
1223     for (uint32 i = unalignedHeaderLength; i < m_headerLength; i++) {
1224         m_buffer.ptr[i] = '\0';
1225     }
1226     // copy message body (if any - arguments are not mandatory)
1227     if (m_mainArguments.data().length) {
1228         memcpy(m_buffer.ptr + m_headerLength, m_mainArguments.data().ptr, m_mainArguments.data().length);
1229     }
1230     m_bufferPos = m_headerLength + m_mainArguments.data().length;
1231     assert(m_bufferPos <= m_buffer.length);
1232 
1233     // for the upcoming message sending, "reuse" m_bufferPos for read position (formerly write position),
1234     // and m_buffer.length for end of data to read (formerly buffer capacity)
1235     m_buffer.length = m_bufferPos;
1236     m_bufferPos = 0;
1237 
1238     m_dirty = false;
1239     m_state = Serialized;
1240     return true;
1241 }
1242 
1243 void MessagePrivate::serializeFixedHeaders()
1244 {
1245     assert(m_buffer.length >= s_extendedFixedHeaderLength);
1246     byte *p = m_buffer.ptr;
1247 
1248     *p++ = s_thisMachineEndianness;
1249     *p++ = byte(m_messageType);
1250     *p++ = m_flags;
1251     *p++ = m_protocolVersion;
1252 
1253     basic::writeUint32(p, m_bodyLength);
1254     basic::writeUint32(p + sizeof(uint32), m_serial);
1255 }
1256 
1257 static void doVarHeaderPrologue(Arguments::Writer *writer, Message::VariableHeader field)
1258 {
1259     writer->beginStruct();
1260     writer->writeByte(byte(field));
1261 }
1262 
1263 Arguments MessagePrivate::serializeVariableHeaders()
1264 {
1265     Arguments::Writer writer;
1266 
1267     // note that we don't have to deal with empty arrays because all valid message types require
1268     // at least one of the variable headers
1269     writer.beginArray();
1270 
1271     for (int i = 0; i < VarHeaderStorage::s_stringHeaderCount; i++) {
1272         const Message::VariableHeader field = s_stringHeaderAtIndex[i];
1273         if (m_varHeaders.hasHeader(field)) {
1274             doVarHeaderPrologue(&writer, field);
1275 
1276             const std::string &str = m_varHeaders.stringHeaders()[i];
1277             if (field == Message::PathHeader) {
1278                 writer.writeVariantForMessageHeader('o');
1279                 writer.writeObjectPath(cstring(str.c_str(), str.length()));
1280             } else if (field == Message::SignatureHeader) {
1281                 writer.writeVariantForMessageHeader('g');
1282                 writer.writeSignature(cstring(str.c_str(), str.length()));
1283             } else {
1284                 writer.writeVariantForMessageHeader('s');
1285                 writer.writeString(cstring(str.c_str(), str.length()));
1286             }
1287 
1288             writer.fixupAfterWriteVariantForMessageHeader();
1289             writer.endStruct();
1290 
1291             if (unlikely(writer.error().isError())) {
1292                 static const Error::Code stringHeaderErrors[VarHeaderStorage::s_stringHeaderCount] = {
1293                     Error::MessagePath,
1294                     Error::MessageInterface,
1295                     Error::MessageMethod,
1296                     Error::MessageErrorName,
1297                     Error::MessageDestination,
1298                     Error::MessageSender,
1299                     Error::MessageSignature
1300                 };
1301                 m_error.setCode(stringHeaderErrors[i]);
1302                 return Arguments();
1303             }
1304         }
1305     }
1306 
1307     for (int i = 0; i < VarHeaderStorage::s_intHeaderCount; i++) {
1308         const Message::VariableHeader field = s_intHeaderAtIndex[i];
1309         if (m_varHeaders.hasHeader(field)) {
1310             doVarHeaderPrologue(&writer, field);
1311             writer.writeVariantForMessageHeader('u');
1312             writer.writeUint32(m_varHeaders.m_intHeaders[i]);
1313             writer.fixupAfterWriteVariantForMessageHeader();
1314             writer.endStruct();
1315         }
1316     }
1317 
1318     writer.endArray();
1319     return writer.finish();
1320 }
1321 
1322 void MessagePrivate::clearBuffer()
1323 {
1324     if (m_buffer.ptr) {
1325         free(m_buffer.ptr);
1326         m_buffer = chunk();
1327         m_bufferPos = 0;
1328     } else {
1329         assert(m_buffer.length == 0);
1330         assert(m_bufferPos == 0);
1331     }
1332 }
1333 
1334 void MessagePrivate::clear(bool onlyReleaseResources)
1335 {
1336     clearBuffer();
1337 #ifdef __unix__
1338     for (int fd : *argUnixFds()) {
1339         ::close(fd);
1340     }
1341 #endif
1342     if (!onlyReleaseResources) { // get into a clean state again
1343         m_state = Empty;
1344         m_mainArguments = Arguments();
1345         m_varHeaders = VarHeaderStorage();
1346     }
1347 }
1348 
1349 static uint32 nextPowerOf2(uint32 x)
1350 {
1351     --x;
1352     x |= x >> 1;
1353     x |= x >> 2;
1354     x |= x >> 4;
1355     x |= x >> 8;
1356     x |= x >> 16;
1357     return ++x;
1358 }
1359 
1360 void MessagePrivate::reserveBuffer(uint32 newLen)
1361 {
1362     const uint32 oldLen = m_buffer.length;
1363     if (newLen <= oldLen) {
1364         return;
1365     }
1366     if (newLen <= 256) {
1367         assert(oldLen == 0);
1368         newLen = 256;
1369         m_buffer.ptr = reinterpret_cast<byte *>(msgAllocCaches.msgBuffer.allocate());
1370     } else {
1371         newLen = nextPowerOf2(newLen);
1372         if (oldLen == 256) {
1373             byte *newAlloc = reinterpret_cast<byte *>(malloc(newLen));
1374             memcpy(newAlloc, m_buffer.ptr, oldLen);
1375 
1376             msgAllocCaches.msgBuffer.free(m_buffer.ptr);
1377             m_buffer.ptr = newAlloc;
1378         } else {
1379             m_buffer.ptr = reinterpret_cast<byte *>(realloc(m_buffer.ptr, newLen));
1380         }
1381     }
1382 
1383     m_buffer.length = newLen;
1384 }
1385 
1386 std::vector<int> *MessagePrivate::argUnixFds()
1387 {
1388     return &Arguments::Private::get(&m_mainArguments)->m_fileDescriptors;
1389 }