Original DBUS bindings for TQt
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

572 lines
12KB

  1. /* -*- mode: C++; c-file-style: "gnu" -*- */
  2. /* message.cpp: TQt wrapper for DBusMessage
  3. *
  4. * Copyright (C) 2003 Zack Rusin <zack@kde.org>
  5. *
  6. * Licensed under the Academic Free License version 2.0
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. */
  23. #include "message.h"
  24. #include <tqmap.h>
  25. #include <cstdlib>
  26. namespace DBusQt {
  27. struct Message::iterator::IteratorData {
  28. DBusMessageIter *iter;
  29. TQVariant var;
  30. bool end;
  31. DBusMessage *mesg;
  32. };
  33. /**
  34. * Iterator.
  35. */
  36. Message::iterator::iterator()
  37. {
  38. d = new IteratorData;
  39. d->iter = 0; d->end = true;
  40. }
  41. /**
  42. * Constructs iterator for the message.
  43. * @param msg message whose fields we want to iterate
  44. */
  45. Message::iterator::iterator( DBusMessage* msg )
  46. {
  47. d = new IteratorData;
  48. d->mesg = msg;
  49. d->iter = static_cast<DBusMessageIter *>( malloc( sizeof(DBusMessageIter) ) );
  50. dbus_message_iter_init( d->mesg, d->iter );
  51. if ( !d->iter ) {
  52. tqDebug("No iterator??");
  53. }
  54. fillVar();
  55. d->end = false;
  56. }
  57. /**
  58. * Copy constructor for the iterator.
  59. * @param itr iterator
  60. */
  61. Message::iterator::iterator( const iterator& itr )
  62. {
  63. d = new IteratorData;
  64. d->iter = itr.d->iter;
  65. d->var = itr.d->var;
  66. d->end = itr.d->end;
  67. }
  68. /**
  69. * Destructor.
  70. */
  71. Message::iterator::~iterator()
  72. {
  73. free( d->iter );
  74. delete d; d=0;
  75. }
  76. /**
  77. * Creates an iterator equal to the @p itr iterator
  78. * @param itr other iterator
  79. * @return
  80. */
  81. Message::iterator&
  82. Message::iterator::operator=( const iterator& itr )
  83. {
  84. IteratorData *tmp = new IteratorData;
  85. tmp->iter = itr.d->iter;
  86. tmp->var = itr.d->var;
  87. tmp->end = itr.d->end;
  88. delete d; d=tmp;
  89. return *this;
  90. }
  91. /**
  92. * Returns the constant TQVariant held by the iterator.
  93. * @return the constant reference to TQVariant held by this iterator
  94. */
  95. const TQVariant&
  96. Message::iterator::operator*() const
  97. {
  98. return d->var;
  99. }
  100. /**
  101. * Returns the TQVariant held by the iterator.
  102. * @return reference to TQVariant held by this iterator
  103. */
  104. TQVariant&
  105. Message::iterator::operator*()
  106. {
  107. return d->var;
  108. }
  109. /**
  110. * Moves to the next field and return a reference to itself after
  111. * incrementing.
  112. * @return reference to self after incrementing
  113. */
  114. Message::iterator&
  115. Message::iterator::operator++()
  116. {
  117. if ( d->end )
  118. return *this;
  119. if ( dbus_message_iter_next( d->iter ) ) {
  120. fillVar();
  121. } else {
  122. d->end = true;
  123. d->var = TQVariant();
  124. }
  125. return *this;
  126. }
  127. /**
  128. * Moves to the next field and returns self before incrementing.
  129. * @return self before incrementing
  130. */
  131. Message::iterator
  132. Message::iterator::operator++(int)
  133. {
  134. iterator itr( *this );
  135. operator++();
  136. return itr;
  137. }
  138. /**
  139. * Compares this iterator to @p it iterator.
  140. * @param it the iterator to which we're comparing this one to
  141. * @return true if they're equal, false otherwise
  142. */
  143. bool
  144. Message::iterator::operator==( const iterator& it )
  145. {
  146. if ( d->end == it.d->end ) {
  147. if ( d->end == true ) {
  148. return true;
  149. } else {
  150. return d->var == it.d->var;
  151. }
  152. } else
  153. return false;
  154. }
  155. /**
  156. * Compares two iterators.
  157. * @param it The other iterator.
  158. * @return true if two iterators are not equal, false
  159. * otherwise
  160. */
  161. bool
  162. Message::iterator::operator!=( const iterator& it )
  163. {
  164. return !operator==( it );
  165. }
  166. TQVariant Message::iterator::marshallBaseType( DBusMessageIter* i )
  167. {
  168. TQVariant ret;
  169. switch (dbus_message_iter_get_arg_type(i)) {
  170. case DBUS_TYPE_INT32:
  171. {
  172. dbus_int32_t v;
  173. dbus_message_iter_get_basic (i, &v);
  174. ret = TQVariant( v );
  175. }
  176. break;
  177. case DBUS_TYPE_UINT32:
  178. {
  179. dbus_uint32_t v;
  180. dbus_message_iter_get_basic (i, &v);
  181. ret = TQVariant( v );
  182. }
  183. break;
  184. case DBUS_TYPE_DOUBLE:
  185. {
  186. double v;
  187. dbus_message_iter_get_basic (i, &v);
  188. ret = TQVariant( v );
  189. }
  190. break;
  191. case DBUS_TYPE_STRING:
  192. {
  193. const char *v;
  194. dbus_message_iter_get_basic (i, &v);
  195. ret = TQVariant( v );
  196. }
  197. break;
  198. default:
  199. ret = TQVariant();
  200. break;
  201. }
  202. return ret;
  203. }
  204. /**
  205. * Fills TQVariant based on what current DBusMessageIter helds.
  206. */
  207. void
  208. Message::iterator::fillVar()
  209. {
  210. switch ( dbus_message_iter_get_arg_type( d->iter ) ) {
  211. case DBUS_TYPE_INT32:
  212. case DBUS_TYPE_UINT32:
  213. case DBUS_TYPE_DOUBLE:
  214. case DBUS_TYPE_STRING:
  215. d->var = marshallBaseType( d->iter );
  216. break;
  217. case DBUS_TYPE_ARRAY: {
  218. switch ( dbus_message_iter_get_element_type( d->iter ) ) {
  219. case DBUS_TYPE_STRING: {
  220. TQStringList tempList;
  221. DBusMessageIter sub;
  222. dbus_message_iter_recurse (d->iter, &sub);
  223. while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
  224. {
  225. const char *v;
  226. dbus_message_iter_get_basic (&sub, &v);
  227. tempList.append( TQString( v ) );
  228. dbus_message_iter_next (&sub);
  229. }
  230. d->var = TQVariant( tempList );
  231. break;
  232. }
  233. default:
  234. tqDebug( "Array of type not implemented" );
  235. d->var = TQVariant();
  236. break;
  237. }
  238. break;
  239. }
  240. #if 0
  241. /* DICT is gone for now, but expected to be reintroduced, or else
  242. * reintroduced as a flag on the introspection data that can
  243. * apply to array of struct of two fields
  244. */
  245. case DBUS_TYPE_DICT: {
  246. tqDebug( "Got a hash!" );
  247. TQMap<TQString, TQVariant> tempMap;
  248. DBusMessageIter dictIter;
  249. dbus_message_iter_init_dict_iterator( d->iter, &dictIter );
  250. do {
  251. char *key = dbus_message_iter_get_dict_key( &dictIter );
  252. tempMap[key] = marshallBaseType( &dictIter );
  253. dbus_free( key );
  254. dbus_message_iter_next( &dictIter );
  255. } while( dbus_message_iter_has_next( &dictIter ) );
  256. d->var = TQVariant( tempMap );
  257. break;
  258. tqDebug( "Hash/Dict type not implemented" );
  259. d->var = TQVariant();
  260. break;
  261. }
  262. #endif
  263. default:
  264. tqDebug( "not implemented" );
  265. d->var = TQVariant();
  266. break;
  267. }
  268. }
  269. /**
  270. * Returns a TQVariant help by this iterator.
  271. * @return TQVariant held by this iterator
  272. */
  273. TQVariant
  274. Message::iterator::var() const
  275. {
  276. return d->var;
  277. }
  278. struct Message::Private {
  279. DBusMessage *msg;
  280. };
  281. Message::Message( DBusMessage *m )
  282. {
  283. d = new Private;
  284. d->msg = m;
  285. }
  286. /**
  287. *
  288. */
  289. Message::Message( int messageType )
  290. {
  291. d = new Private;
  292. d->msg = dbus_message_new( messageType );
  293. }
  294. /**
  295. * Constructs a new Message with the given service and name.
  296. * @param service service service that the message should be sent to
  297. * @param name name of the message
  298. */
  299. Message::Message( const TQString& service, const TQString& path,
  300. const TQString& interface, const TQString& method )
  301. {
  302. d = new Private;
  303. d->msg = dbus_message_new_method_call( service.latin1(), path.latin1(),
  304. interface.latin1(), method.latin1() );
  305. }
  306. /**
  307. * Constructs a message that is a reply to some other
  308. * message.
  309. * @param name the name of the message
  310. * @param replayingTo original_message the message which the created
  311. * message is a reply to.
  312. */
  313. Message::Message( const Message& replayingTo )
  314. {
  315. d = new Private;
  316. d->msg = dbus_message_new_method_return( replayingTo.d->msg );
  317. }
  318. Message:: Message( const TQString& path, const TQString& interface,
  319. const TQString& name )
  320. {
  321. d = new Private;
  322. d->msg = dbus_message_new_signal( path.ascii(), interface.ascii(),
  323. name.ascii() );
  324. }
  325. Message::Message( const Message& replayingTo, const TQString& errorName,
  326. const TQString& errorMessage )
  327. {
  328. d = new Private;
  329. d->msg = dbus_message_new_error( replayingTo.d->msg, errorName.utf8(),
  330. errorMessage.utf8() );
  331. }
  332. Message Message::operator=( const Message& other )
  333. {
  334. //FIXME: ref the other.d->msg instead of copying it?
  335. return *this;
  336. }
  337. /**
  338. * Destructs message.
  339. */
  340. Message::~Message()
  341. {
  342. if ( d->msg ) {
  343. dbus_message_unref( d->msg );
  344. }
  345. delete d; d=0;
  346. }
  347. int Message::type() const
  348. {
  349. return dbus_message_get_type( d->msg );
  350. }
  351. void Message::setPath( const TQString& path )
  352. {
  353. dbus_message_set_path( d->msg, path.ascii() );
  354. }
  355. TQString Message::path() const
  356. {
  357. return dbus_message_get_path( d->msg );
  358. }
  359. void Message::setInterface( const TQString& iface )
  360. {
  361. dbus_message_set_interface( d->msg, iface.ascii() );
  362. }
  363. TQString Message::interface() const
  364. {
  365. return dbus_message_get_interface( d->msg );
  366. }
  367. void Message::setMember( const TQString& member )
  368. {
  369. dbus_message_set_member( d->msg, member.ascii() );
  370. }
  371. TQString Message::member() const
  372. {
  373. return dbus_message_get_member( d->msg );
  374. }
  375. void Message::setErrorName( const TQString& err )
  376. {
  377. dbus_message_set_error_name( d->msg, err.ascii() );
  378. }
  379. TQString Message::errorName() const
  380. {
  381. return dbus_message_get_error_name( d->msg );
  382. }
  383. void Message::setDestination( const TQString& dest )
  384. {
  385. dbus_message_set_destination( d->msg, dest.ascii() );
  386. }
  387. TQString Message::destination() const
  388. {
  389. return dbus_message_get_destination( d->msg );
  390. }
  391. /**
  392. * Sets the message sender.
  393. * @param sender the sender
  394. * @return false if unsuccessful
  395. */
  396. bool
  397. Message::setSender( const TQString& sender )
  398. {
  399. return dbus_message_set_sender( d->msg, sender.latin1() );
  400. }
  401. /**
  402. * Returns sender of this message.
  403. * @return sender
  404. */
  405. TQString
  406. Message::sender() const
  407. {
  408. return dbus_message_get_sender( d->msg );
  409. }
  410. TQString Message::signature() const
  411. {
  412. return dbus_message_get_signature( d->msg );
  413. }
  414. /**
  415. * Returns the starting iterator for the fields of this
  416. * message.
  417. * @return starting iterator
  418. */
  419. Message::iterator
  420. Message::begin() const
  421. {
  422. return iterator( d->msg );
  423. }
  424. /**
  425. * Returns the ending iterator for the fields of this
  426. * message.
  427. * @return ending iterator
  428. */
  429. Message::iterator
  430. Message::end() const
  431. {
  432. return iterator();
  433. }
  434. /**
  435. * Returns the field at position @p i
  436. * @param i position of the wanted field
  437. * @return TQVariant at position @p i or an empty TQVariant
  438. */
  439. TQVariant
  440. Message::at( int i )
  441. {
  442. iterator itr( d->msg );
  443. while ( i-- ) {
  444. if ( itr == end() )
  445. return TQVariant();//nothing there
  446. ++itr;
  447. }
  448. return *itr;
  449. }
  450. /**
  451. * The underlying DBusMessage of this class.
  452. * @return DBusMessage pointer.
  453. */
  454. DBusMessage*
  455. Message::message() const
  456. {
  457. return d->msg;
  458. }
  459. Message& Message::operator<<( bool b )
  460. {
  461. const dbus_bool_t right_size_bool = b;
  462. dbus_message_append_args( d->msg, DBUS_TYPE_BOOLEAN, &right_size_bool,
  463. DBUS_TYPE_INVALID );
  464. return *this;
  465. }
  466. Message& Message::operator<<( TQ_INT8 byte )
  467. {
  468. dbus_message_append_args( d->msg, DBUS_TYPE_BYTE, &byte,
  469. DBUS_TYPE_INVALID );
  470. return *this;
  471. }
  472. Message& Message::operator<<( TQ_INT32 num )
  473. {
  474. dbus_message_append_args( d->msg, DBUS_TYPE_INT32, &num,
  475. DBUS_TYPE_INVALID );
  476. return *this;
  477. }
  478. Message& Message::operator<<( TQ_UINT32 num )
  479. {
  480. dbus_message_append_args( d->msg, DBUS_TYPE_UINT32, &num,
  481. DBUS_TYPE_INVALID );
  482. return *this;
  483. }
  484. Message& Message::operator<<( TQ_INT64 num )
  485. {
  486. dbus_message_append_args( d->msg, DBUS_TYPE_INT64, &num,
  487. DBUS_TYPE_INVALID );
  488. return *this;
  489. }
  490. Message& Message::operator<<( TQ_UINT64 num )
  491. {
  492. dbus_message_append_args( d->msg, DBUS_TYPE_UINT64, &num,
  493. DBUS_TYPE_INVALID );
  494. return *this;
  495. }
  496. Message& Message::operator<<( double num )
  497. {
  498. dbus_message_append_args( d->msg, DBUS_TYPE_DOUBLE, &num,
  499. DBUS_TYPE_INVALID );
  500. return *this;
  501. }
  502. Message& Message::operator<<( const TQString& str )
  503. {
  504. const char *u = str.utf8();
  505. dbus_message_append_args( d->msg, DBUS_TYPE_STRING, &u,
  506. DBUS_TYPE_INVALID );
  507. return *this;
  508. }
  509. Message& Message::operator<<( const TQVariant& custom )
  510. {
  511. //FIXME: imeplement
  512. return *this;
  513. }
  514. }