Files
BPI-M2C/source_sync_rls_25c/source/unisoc/perflink/libudbus/Message.cpp
T
2026-09-22 09:38:26 +08:00

705 lines
15 KiB
C++

/*
* SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0
* Copyright 2016-2023 Unisoc (Shanghai) Technologies Co., Ltd
* Licensed under the Unisoc General Software License, version 1.0 (the License);
* you may not use this file except in compliance with the License. You may obtain a copy of the License at
* https://www.unisoc.com/en_us/license/UNISOC_GENERAL_LICENSE_V1.0-EN_US
* Software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, either express or implied.
* See the Unisoc General Software License, version 1.0 for more details.
*/
#include <Message.h>
#include <dbus/dbus.h>
#include <cstdlib>
#include "InternalError.h"
#include "MessageInternal.h"
#include "Debug.h"
using namespace UDBus;
static bool isBasicType(int typeCode)
{
switch (typeCode) {
case DBUS_TYPE_DOUBLE:
case DBUS_TYPE_UINT64:
case DBUS_TYPE_INT64:
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT16:
case DBUS_TYPE_INT16:
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_UNIX_FD:
case DBUS_TYPE_BYTE:
case DBUS_TYPE_SIGNATURE:
case DBUS_TYPE_BOOLEAN:
return true;
default:
return false;
}
}
MessageIter::MessageIter()
: mPrivate(new UDBusPrivate), mMsg(nullptr) {}
MessageIter::MessageIter(Message &msg)
: mPrivate(new UDBusPrivate), mMsg(&msg) {}
MessageIter::MessageIter(const MessageIter &iter)
: mPrivate(new UDBusPrivate(*iter.mPrivate)), mMsg(iter.mMsg) {}
MessageIter::~MessageIter()
{
delete mPrivate;
mPrivate = nullptr;
mMsg = nullptr;
}
MessageIter &MessageIter::operator =(const MessageIter &iter)
{
if (this != &iter) {
*mPrivate = *iter.mPrivate;
mMsg = iter.mMsg;
}
return *this;
}
bool MessageIter::AppendBasic(int type_id, void *value)
{
return dbus_message_iter_append_basic(&mPrivate->iter, type_id, value);
}
bool MessageIter::AppendFd(int fd)
{
return AppendBasic(DBUS_TYPE_UNIX_FD, &fd);
}
bool MessageIter::AppendSignature(const char *chars)
{
return AppendBasic(DBUS_TYPE_SIGNATURE, &chars);
}
bool MessageIter::AppendPath(const char *chars)
{
return AppendBasic(DBUS_TYPE_OBJECT_PATH, &chars);
}
bool MessageIter::AppendArray(char type, const void *ptr, size_t length)
{
return dbus_message_iter_append_fixed_array(&mPrivate->iter, type, &ptr, length);
}
bool MessageIter::AppendByte(unsigned char b)
{
return AppendBasic(DBUS_TYPE_BYTE, &b);
}
bool MessageIter::AppendDouble(double d)
{
return AppendBasic(DBUS_TYPE_DOUBLE, &d);
}
bool MessageIter::AppendUint64(unsigned long long u)
{
return AppendBasic(DBUS_TYPE_UINT64, &u);
}
bool MessageIter::AppendInt64(signed long long i)
{
return AppendBasic(DBUS_TYPE_INT64, &i);
}
bool MessageIter::AppendUint32(unsigned int u)
{
return AppendBasic(DBUS_TYPE_UINT32, &u);
}
bool MessageIter::AppendInt32(signed int i)
{
return AppendBasic(DBUS_TYPE_INT32, &i);
}
bool MessageIter::AppendUint16(unsigned short u)
{
return AppendBasic(DBUS_TYPE_UINT16, &u);
}
bool MessageIter::AppendInt16(signed short i)
{
return AppendBasic(DBUS_TYPE_INT16, &i);
}
bool MessageIter::AppendString(const char *chars)
{
return AppendBasic(DBUS_TYPE_STRING, &chars);
}
bool MessageIter::AppendBool(bool b)
{
dbus_bool_t db = b ? TRUE : FALSE;
return AppendBasic(DBUS_TYPE_BOOLEAN, &db);
}
signed short MessageIter::GetInt16()
{
signed short i;
GetBasic(DBUS_TYPE_INT16, &i);
return i;
}
unsigned short MessageIter::GetUint16()
{
unsigned short u;
GetBasic(DBUS_TYPE_UINT16, &u);
return u;
}
signed int MessageIter::GetInt32()
{
signed int i;
GetBasic(DBUS_TYPE_INT32, &i);
return i;
}
unsigned int MessageIter::GetUint32()
{
unsigned int u;
GetBasic(DBUS_TYPE_UINT32, &u);
return u;
}
unsigned long long MessageIter::GetUint64()
{
unsigned long long u;
GetBasic(DBUS_TYPE_UINT64, &u);
return u;
}
signed long long MessageIter::GetInt64()
{
signed long long i;
GetBasic(DBUS_TYPE_INT64, &i);
return i;
}
double MessageIter::GetDouble()
{
double d;
GetBasic(DBUS_TYPE_DOUBLE, &d);
return d;
}
void MessageIter::GetBasic(int type_id, void *ptr)
{
if (Type() != type_id)
throw ErrorInvalidArgs("type mismatch");
dbus_message_iter_get_basic(&mPrivate->iter, ptr);
}
unsigned char MessageIter::GetByte()
{
unsigned char b;
GetBasic(DBUS_TYPE_BYTE, &b);
return b;
}
bool MessageIter::GetBool()
{
dbus_bool_t db;
GetBasic(DBUS_TYPE_BOOLEAN, &db);
return db ? true : false;
}
const char *MessageIter::GetString()
{
char *chars;
GetBasic(DBUS_TYPE_STRING, &chars);
return chars;
}
const char *MessageIter::GetPath()
{
char *path;
GetBasic(DBUS_TYPE_OBJECT_PATH, &path);
return path;
}
const char *MessageIter::GetSignature()
{
char *signature;
GetBasic(DBUS_TYPE_SIGNATURE, &signature);
return signature;
}
int MessageIter::GetFd()
{
int fd;
GetBasic(DBUS_TYPE_UNIX_FD, &fd);
return fd;
}
int MessageIter::GetArray(void *ptr)
{
int length = 0;
dbus_message_iter_get_fixed_array(&mPrivate->iter, ptr, &length);
return length;
}
bool MessageIter::AtEnd()
{
return Type() == DBUS_TYPE_INVALID;
}
bool MessageIter::HasNext()
{
return dbus_message_iter_has_next(&mPrivate->iter);
}
char *MessageIter::Signature() const
{
return dbus_message_iter_get_signature(&mPrivate->iter);
}
int MessageIter::ArrayType()
{
return dbus_message_iter_get_element_type(&mPrivate->iter);
}
bool MessageIter::IsDict()
{
return IsArray() && dbus_message_iter_get_element_type(&mPrivate->iter) == DBUS_TYPE_DICT_ENTRY;
}
bool MessageIter::IsArray()
{
return dbus_message_iter_get_arg_type(&mPrivate->iter) == DBUS_TYPE_ARRAY;
}
int MessageIter::Type()
{
return dbus_message_iter_get_arg_type(&mPrivate->iter);
}
MessageIter MessageIter::CreateVariant(const char *sig)
{
MessageIter var(Msg());
dbus_message_iter_open_container(
&mPrivate->iter, DBUS_TYPE_VARIANT, sig, &var.mPrivate->iter
);
return var;
}
MessageIter MessageIter::CreateArray(const char *sig)
{
MessageIter arr(Msg());
dbus_message_iter_open_container(
&mPrivate->iter, DBUS_TYPE_ARRAY, sig, &arr.mPrivate->iter
);
return arr;
}
MessageIter MessageIter::CreateDictEntry()
{
MessageIter ent(Msg());
dbus_message_iter_open_container(
&mPrivate->iter, DBUS_TYPE_DICT_ENTRY, nullptr, &ent.mPrivate->iter
);
return ent;
}
MessageIter MessageIter::CreateStruct()
{
MessageIter stu(Msg());
dbus_message_iter_open_container(
&mPrivate->iter, DBUS_TYPE_STRUCT, nullptr, &stu.mPrivate->iter
);
return stu;
}
MessageIter MessageIter::Recurse()
{
MessageIter iter(Msg());
dbus_message_iter_recurse(&mPrivate->iter, &iter.mPrivate->iter);
return iter;
}
void MessageIter::CloseContainer(MessageIter &container)
{
dbus_message_iter_close_container(&mPrivate->iter, &container.mPrivate->iter);
}
void MessageIter::CopyData(MessageIter &dest)
{
for (MessageIter &orig = *this; !orig.AtEnd(); ++orig) {
if (isBasicType(orig.Type())) {
unsigned char variant[8];
orig.GetBasic(orig.Type(), &variant);
dest.AppendBasic(orig.Type(), &variant);
} else {
MessageIter dest_container (dest.Msg());
MessageIter orig_container = orig.Recurse();
char *signature = orig_container.Signature();
dbus_message_iter_open_container(
&dest.mPrivate->iter, orig.Type(),
orig.Type() == DBUS_TYPE_DICT_ENTRY ||
orig.Type() == DBUS_TYPE_STRUCT
? nullptr: signature,
&dest_container.mPrivate->iter);
orig_container.CopyData(dest_container);
dest.CloseContainer(dest_container);
free(signature);
}
}
}
MessageIter MessageIter::operator ++(int)
{
MessageIter copy(*this);
++(*this);
return copy;
}
MessageIter &MessageIter::operator ++()
{
dbus_message_iter_next(&mPrivate->iter);
return (*this);
}
/*
*/
Message::Message()
: mPrivate(new UDBusPrivate)
{
isSync = true;
}
Message::Message(Message::UDBusPrivate *p, bool incref)
: mPrivate(p)
{
if (mPrivate->msg && incref) dbus_message_ref(mPrivate->msg);
isSync = true;
}
Message::Message(const Message &m)
: mPrivate(m.mPrivate)
{
if (mPrivate->msg)
dbus_message_ref(mPrivate->msg);
isSync = true;
}
Message::~Message()
{
if (mPrivate->msg)
dbus_message_unref(mPrivate->msg);
}
Message &Message::operator = (const Message &m)
{
if (&m != this) {
if (mPrivate->msg)
dbus_message_unref(mPrivate->msg);
mPrivate = m.mPrivate;
if (mPrivate->msg)
dbus_message_ref(mPrivate->msg);
}
isSync = m.isSync;
return *this;
}
bool Message::GetSync()
{
return isSync;
}
UDBus::Tag *Message::GetTag() const
{
return mPrivate->tag;
}
const char* Message::GetErrorName() const
{
return dbus_message_get_error_name(mPrivate->msg);
}
const char *Message::Destination() const
{
return dbus_message_get_destination(mPrivate->msg);
}
const char *Message::Sender() const
{
return dbus_message_get_sender(mPrivate->msg);
}
int Message::ReplySerial() const
{
return dbus_message_get_reply_serial(mPrivate->msg);
}
int Message::Serial() const
{
return dbus_message_get_serial(mPrivate->msg);
}
bool Message::SetReplySerial(int s)
{
return dbus_message_set_reply_serial(mPrivate->msg, s);
}
bool Message::SetSender(const char *s)
{
return dbus_message_set_sender(mPrivate->msg, s);
}
bool Message::SetDestination(const char *s)
{
return dbus_message_set_destination(mPrivate->msg, s);
}
void Message::SetSync(bool sync)
{
isSync = sync;
}
bool Message::IsError() const
{
return Type() == DBUS_MESSAGE_TYPE_ERROR;
}
bool Message::IsSignal(const char *interface, const char* member) const
{
return dbus_message_is_signal(mPrivate->msg, interface, member);
}
void Message::Terminate()
{
dbus_message_append_args(mPrivate->msg, DBUS_TYPE_INVALID);
}
int Message::Type() const
{
return dbus_message_get_type(mPrivate->msg);
}
Message Message::Copy()
{
UDBusPrivate *pvt = new UDBusPrivate(mPrivate->msg ? dbus_message_copy(mPrivate->msg) : nullptr);
return Message(pvt);
}
MessageIter Message::Writer()
{
MessageIter iter(*this);
dbus_message_iter_init_append(mPrivate->msg, &iter.mPrivate->iter);
return iter;
}
bool Message::Append(int orig, ...)
{
va_list val_list;
va_start(val_list, orig);
bool ret = dbus_message_append_args_valist(mPrivate->msg, orig, val_list);
va_end(val_list);
return ret;
}
MessageIter Message::Reader() const
{
MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(mPrivate->msg, &iter.mPrivate->iter);
return iter;
}
void CallMessage::Ref(void)
{
if (mPrivate->msg)
dbus_message_ref(mPrivate->msg);
}
void CallMessage::Unref(void)
{
if (mPrivate->msg)
dbus_message_unref(mPrivate->msg);
}
UDbusErrorMessage::UDbusErrorMessage()
{
mPrivate->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
}
UDbusErrorMessage::UDbusErrorMessage(const Message &to_reply, const char *name, const char *message)
{
mPrivate->msg = dbus_message_new_error(to_reply.mPrivate->msg, name, message);
}
bool UDbusErrorMessage::operator == (const UDbusErrorMessage &m) const
{
return dbus_message_is_error(mPrivate->msg, m.GetName());
}
const char *UDbusErrorMessage::GetName() const
{
return dbus_message_get_error_name(mPrivate->msg);
}
bool UDbusErrorMessage::SetName(const char *n)
{
return dbus_message_set_error_name(mPrivate->msg, n);
}
/*
*/
SignalMessage::SignalMessage(const char *name)
{
mPrivate->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
SetMember(name);
}
SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
{
mPrivate->msg = dbus_message_new_signal(path, interface, name);
}
bool SignalMessage::operator == (const SignalMessage &m) const
{
return dbus_message_is_signal(mPrivate->msg, m.GetInterface(), m.GetMember());
}
const char *SignalMessage::GetInterface() const
{
return dbus_message_get_interface(mPrivate->msg);
}
bool SignalMessage::SetInterface(const char *i)
{
return dbus_message_set_interface(mPrivate->msg, i);
}
const char *SignalMessage::GetMember() const
{
return dbus_message_get_member(mPrivate->msg);
}
bool SignalMessage::SetMember(const char *m)
{
return dbus_message_set_member(mPrivate->msg, m);
}
const char *SignalMessage::GetPath() const
{
return dbus_message_get_path(mPrivate->msg);
}
char **SignalMessage::GetPathSplit() const
{
char **p = nullptr;
dbus_message_get_path_decomposed(mPrivate->msg, &p); //todo: return as a std::vector ?
return p;
}
bool SignalMessage::SetPath(const char *p)
{
return dbus_message_set_path(mPrivate->msg, p);
}
/*
*/
CallMessage::CallMessage()
{
mPrivate->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
}
CallMessage &CallMessage::operator = (const CallMessage &m)
{
if (&m != this) {
if (mPrivate->msg)
dbus_message_unref(mPrivate->msg);
mPrivate = m.mPrivate;
if (mPrivate->msg)
dbus_message_ref(mPrivate->msg);
}
return *this;
}
CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
{
mPrivate->msg = dbus_message_new_method_call(dest, path, iface, method);
}
bool CallMessage::operator == (const CallMessage &m) const
{
return dbus_message_is_method_call(mPrivate->msg, m.GetInterface(), m.GetMember());
}
const char *CallMessage::GetInterface() const
{
return dbus_message_get_interface(mPrivate->msg);
}
bool CallMessage::SetInterface(const char *i)
{
return dbus_message_set_interface(mPrivate->msg, i);
}
const char *CallMessage::GetMember() const
{
return dbus_message_get_member(mPrivate->msg);
}
bool CallMessage::SetMember(const char *m)
{
return dbus_message_set_member(mPrivate->msg, m);
}
const char *CallMessage::GetPath() const
{
return dbus_message_get_path(mPrivate->msg);
}
char **CallMessage::GetPathSplit() const
{
char **p = nullptr;
dbus_message_get_path_decomposed(mPrivate->msg, &p);
return p;
}
bool CallMessage::SetPath(const char *p)
{
return dbus_message_set_path(mPrivate->msg, p);
}
const char *CallMessage::GetSignature() const
{
return dbus_message_get_signature(mPrivate->msg);
}
TagMessage::TagMessage(UDBus::Tag *tag)
{
mPrivate->tag = tag;
}
ReturnMessage::ReturnMessage(const CallMessage &callee)
{
mPrivate = new UDBusPrivate(dbus_message_new_method_return(callee.mPrivate->msg));
}
ReturnMessage::ReturnMessage()
{
mPrivate = nullptr;
}
const char *ReturnMessage::GetSignature() const
{
return dbus_message_get_signature(mPrivate->msg);
}