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 #ifndef MESSAGE_H
0025 #define MESSAGE_H
0026 
0027 #include "arguments.h"
0028 #include "types.h"
0029 
0030 #include <string>
0031 #include <vector>
0032 
0033 class Arguments;
0034 class Error;
0035 class MessagePrivate;
0036 
0037 class DFERRY_EXPORT Message
0038 {
0039 public:
0040     // this class contains header data in deserialized form (maybe also serialized) and the payload
0041     // in serialized form
0042 
0043     Message(); // constructs an invalid message (to be filled in later, usually)
0044     ~Message();
0045 
0046     // prefer these over copy construction / assignment whenever possible, for performance reasons
0047     Message(Message &&other);
0048     Message &operator=(Message &&other);
0049 
0050     Message(const Message &other);
0051     Message &operator=(const Message &other);
0052 
0053     // error (if any) propagates to PendingReply, so it is still available later
0054     Error error() const;
0055 
0056     // convenience
0057     void setCall(const std::string &path, const std::string &interface, const std::string &method);
0058     void setCall(const std::string &path, const std::string &method); // deprecated? remove?
0059     void setReplyTo(const Message &call); // fills in all available details as appropriate for a reply
0060     void setErrorReplyTo(const Message &call, const std::string &errorName);
0061     void setSignal(const std::string &path, const std::string &interface, const std::string &method);
0062     // decadence
0063     static Message createCall(const std::string &path, const std::string &interface,
0064                               const std::string &method);
0065     static Message createCall(const std::string &path, const std::string &method);
0066     static Message createReplyTo(const Message &call);
0067     static Message createErrorReplyTo(const Message &call, const std::string &errorName);
0068     static Message createSignal(const std::string &path, const std::string &interface,
0069                                 const std::string &method);
0070 
0071     std::string prettyPrint() const;
0072 
0073     enum Type {
0074         InvalidMessage = 0,
0075         MethodCallMessage,
0076         MethodReturnMessage,
0077         ErrorMessage,
0078         SignalMessage
0079     };
0080 
0081     Type type() const;
0082     void setType(Type type);
0083     uint32 protocolVersion() const;
0084 
0085     enum VariableHeader {
0086         PathHeader = 1,
0087         InterfaceHeader,
0088         MethodHeader, // called "member" in the spec
0089         ErrorNameHeader,
0090         ReplySerialHeader,
0091         DestinationHeader,
0092         SenderHeader,
0093         SignatureHeader,
0094         UnixFdsHeader // TODO UnixFdCountHeader
0095     };
0096 
0097     // enum-based access to headers
0098     // These are validated during serialization, not now; the message cannot expected to be in a
0099     // completely valid state before that anyway. Yes, we could validate some things, but let's just
0100     // do it all at once.
0101     std::string stringHeader(VariableHeader header, bool *isPresent = nullptr) const;
0102     void setStringHeader(VariableHeader header, const std::string &value);
0103     uint32 intHeader(VariableHeader header, bool *isPresent = nullptr) const;
0104     void setIntHeader(VariableHeader header, uint32 value);
0105 
0106     // convenience access to headers, these directly call enum-based getters / setters
0107     std::string path() const;
0108     void setPath(const std::string &path);
0109     std::string interface() const;
0110     void setInterface(const std::string &interface);
0111     std::string method() const;
0112     void setMethod(const std::string &method);
0113     std::string errorName() const;
0114     void setErrorName(const std::string &errorName);
0115     uint32 replySerial() const;
0116     void setReplySerial(uint32 replySerial);
0117     std::string destination() const;
0118     void setDestination(const std::string &destination);
0119     std::string sender() const;
0120     void setSender(const std::string &sender);
0121     std::string signature() const;
0122     // no setSignature() - setArguments() also sets the signature
0123     uint32 unixFdCount() const;
0124     // no setUnixFdCount() - setArguments() also sets the Unix file descriptor count
0125 
0126     bool expectsReply() const; // default true (except for signals, I guess? TODO clarify)
0127     void setExpectsReply(bool);
0128 
0129     bool autoStartService() const; // default true
0130     void setAutoStartService(bool) const;
0131 
0132     bool interactiveAuthorizationAllowed() const; // default true
0133     void setInteractiveAuthorizationAllowed(bool) const;
0134 
0135     // setArguments also sets the signature header of the message
0136     void setArguments(Arguments arguments);
0137     const Arguments &arguments() const;
0138 
0139     std::vector<byte> save();
0140     void load(const std::vector<byte> &data);
0141 
0142     // TODO actual guarantees?
0143     // Serialize the message and return a view on the serialized data. The view points to memory that
0144     // is still owned by the Message instance. It is valid as long as no non-const methods are called
0145     // on the message. Well, that's the idea. In practice, it is best to copy out the data ASAP.
0146     // If the message could not be serialized, an empty chunk is returned.
0147     chunk serializeAndView();
0148     // Deserialize the message from chunk memOwnership and take ownership. memOwnership.ptr must
0149     // point to the beginning of a malloc() ed block of data. memOwnership.length is the length
0150     // of the serialized data, but the malloc()ed chunk may be larger.
0151     void deserializeAndTake(chunk memOwnership);
0152 
0153     // The rest of public methods is low-level API that should only be used in very special situations
0154 
0155     void setSerial(uint32 serial);
0156     uint32 serial() const;
0157 
0158 #ifndef DFERRY_SERDES_ONLY
0159     bool isReceiving() const;
0160     bool isSending() const;
0161 #endif
0162 
0163 private:
0164     friend class MessagePrivate;
0165     MessagePrivate *d;
0166 };
0167 
0168 #endif // MESSAGE_H