/genplugouts/html/cpp/UmlCom.cpp

http://github.com/gregsmirnov/bouml · C++ · 690 lines · 596 code · 89 blank · 5 comment · 20 complexity · 94d4b5b9b3389e420520bb2964f2ab30 MD5 · raw file

  1. #include "UmlCom.h"
  2. #include <qsocketdevice.h>
  3. #include "UmlCom.h"
  4. #include "UmlItem.h"
  5. #include "UmlTypeSpec.h"
  6. #include "UmlClass.h"
  7. #include "UmlSettings.h"
  8. #include "MiscGlobalCmd.h"
  9. bool UmlCom::connect(unsigned int port)
  10. {
  11. sock = new QSocketDevice(QSocketDevice::Stream);
  12. sock->setAddressReusable(TRUE);
  13. buffer_in_size = 1024;
  14. buffer_in = new char[buffer_in_size];
  15. buffer_in_end = p_buffer_in = 0;
  16. buffer_out_size = 1024;
  17. buffer_out = new char[buffer_out_size];
  18. p_buffer_out = buffer_out + 4/*bytes for length*/;
  19. QHostAddress ha;
  20. ha.setAddress("127.0.0.1");
  21. if (sock->connect(ha, port)) {
  22. // send API version
  23. write_unsigned(55);
  24. flush();
  25. return TRUE;
  26. }
  27. else
  28. return FALSE;
  29. }
  30. UmlItem * UmlCom::targetItem()
  31. {
  32. send_cmd(miscGlobalCmd, targetCmd);
  33. return UmlBaseItem::read_();
  34. }
  35. void UmlCom::trace(const char * s)
  36. {
  37. send_cmd(miscGlobalCmd, traceCmd, s);
  38. }
  39. void UmlCom::showTrace()
  40. {
  41. send_cmd(miscGlobalCmd, showTraceCmd);
  42. }
  43. void UmlCom::traceAutoRaise(bool y)
  44. {
  45. send_cmd(miscGlobalCmd, traceAutoRaiseCmd, (y == 0) ? 0 : 1);
  46. }
  47. void UmlCom::message(const char * s)
  48. {
  49. send_cmd(miscGlobalCmd, messageCmd, s);
  50. }
  51. void UmlCom::bye(int v)
  52. {
  53. send_cmd(miscGlobalCmd, byeCmd, v, "");
  54. }
  55. void UmlCom::close()
  56. {
  57. delete sock;
  58. sock = 0;
  59. }
  60. QSocketDevice * UmlCom::sock;
  61. char * UmlCom::buffer_in;
  62. unsigned int UmlCom::buffer_in_size;
  63. char * UmlCom::p_buffer_in;
  64. char * UmlCom::buffer_in_end;
  65. char * UmlCom::buffer_out;
  66. char * UmlCom::p_buffer_out;
  67. unsigned int UmlCom::buffer_out_size;
  68. void UmlCom::check_size_out(unsigned int len)
  69. {
  70. unsigned used = p_buffer_out - buffer_out;
  71. if ((used + len) >= buffer_out_size) {
  72. buffer_out_size = used + len + 1024;
  73. char * newbuff = new char[buffer_out_size];
  74. memcpy(newbuff, buffer_out, used);
  75. delete [] buffer_out;
  76. p_buffer_out = (buffer_out = newbuff) + used;
  77. }
  78. }
  79. void UmlCom::read_if_needed()
  80. {
  81. #ifdef TRACE
  82. //cout << "UmlCom::read_if_needed " << buffer_in_end - p_buffer_in << '\n';
  83. #endif
  84. if (p_buffer_in == buffer_in_end) {
  85. read_buffer(4);
  86. #ifdef TRACE
  87. cout << "UmlCom::read " << ((((unsigned char *) buffer_in)[0] << 24) + (((unsigned char *) buffer_in)[1] << 16) +(((unsigned char *) buffer_in)[2] << 8) +((unsigned char *) buffer_in)[3]) << " bytes\n";
  88. #endif
  89. read_buffer((((unsigned char *) buffer_in)[0] << 24) +
  90. (((unsigned char *) buffer_in)[1] << 16) +
  91. (((unsigned char *) buffer_in)[2] << 8) +
  92. ((unsigned char *) buffer_in)[3]);
  93. }
  94. }
  95. void UmlCom::read_buffer(unsigned int len)
  96. {
  97. #ifdef TRACE
  98. //cout << "enter UmlCom::read_buffer(" << len << ")\n";
  99. #endif
  100. if (buffer_in_size < len) {
  101. delete [] buffer_in;
  102. buffer_in_size = len + 256;
  103. buffer_in = new char[buffer_in_size];
  104. }
  105. int remainder = (int) len;
  106. int nread;
  107. char * p = buffer_in;
  108. for (;;) {
  109. if ((nread = sock->readBlock(p, remainder)) == -1) {
  110. if (sock->error() != 0) {
  111. #ifdef TRACE
  112. cout << "UmlCom::read_buffer ERROR, already " << p - buffer_in
  113. << " remainder " << remainder << '\n';
  114. #endif
  115. fatal_error("UmlCom read error");
  116. }
  117. else
  118. nread = 0;
  119. }
  120. #ifdef TRACE
  121. //cout << "UmlCom a lu " << nread << '\n';
  122. #endif
  123. if ((remainder -= nread) == 0)
  124. break;
  125. p += nread;
  126. sock->waitForMore(100);
  127. }
  128. #ifdef TRACE
  129. //cout << "exit UmlCom::read_buffer()\n";
  130. #endif
  131. p_buffer_in = buffer_in;
  132. buffer_in_end = buffer_in + len;
  133. }
  134. void UmlCom::write_bool(bool b)
  135. {
  136. check_size_out(1);
  137. *p_buffer_out++ = (b == 0) ? 0 : 1;
  138. }
  139. void UmlCom::write_char(char c)
  140. {
  141. check_size_out(1);
  142. *p_buffer_out++ = c;
  143. }
  144. void UmlCom::write_unsigned(unsigned int u)
  145. {
  146. check_size_out(4);
  147. p_buffer_out[0] = u >> 24;
  148. p_buffer_out[1] = u >> 16;
  149. p_buffer_out[2] = u >> 8;
  150. p_buffer_out[3] = u;
  151. p_buffer_out += 4;
  152. }
  153. void UmlCom::write_id(const void * id)
  154. {
  155. check_size_out(sizeof(void *));
  156. memcpy(p_buffer_out, &id, sizeof(void *));
  157. p_buffer_out += sizeof(void *);
  158. }
  159. void UmlCom::write_string(const char * p)
  160. {
  161. if (p == 0)
  162. p = "";
  163. unsigned len = strlen(p) + 1;
  164. check_size_out(len);
  165. memcpy(p_buffer_out, p, len);
  166. p_buffer_out += len;
  167. }
  168. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd)
  169. {
  170. #ifdef TRACE
  171. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ")\n";
  172. #endif
  173. write_char(f);
  174. write_char(cmd);
  175. flush();
  176. }
  177. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, const char * s, bool b)
  178. {
  179. #ifdef TRACE
  180. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << ((s) ? s : "") << b << ")\n";
  181. #endif
  182. write_char(f);
  183. write_char(cmd);
  184. write_string(s);
  185. write_bool(b);
  186. flush();
  187. }
  188. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, char arg)
  189. {
  190. #ifdef TRACE
  191. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << arg << ")\n";
  192. #endif
  193. write_char(f);
  194. write_char(cmd);
  195. write_char(arg);
  196. flush();
  197. }
  198. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, int arg, const char *)
  199. {
  200. #ifdef TRACE
  201. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << arg << ", dummy)\n";
  202. #endif
  203. write_char(f);
  204. write_char(cmd);
  205. write_unsigned(arg);
  206. flush();
  207. }
  208. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, void * id)
  209. {
  210. #ifdef TRACE
  211. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << id << ")\n";
  212. #endif
  213. write_char(f);
  214. write_char(cmd);
  215. write_id(id);
  216. flush();
  217. }
  218. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, const char * s)
  219. {
  220. #ifdef TRACE
  221. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << s << ")\n";
  222. #endif
  223. write_char(f);
  224. write_char(cmd);
  225. write_string(s);
  226. flush();
  227. }
  228. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, void * id, const char * n)
  229. {
  230. #ifdef TRACE
  231. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << id << ")\n";
  232. #endif
  233. write_char(f);
  234. write_char(cmd);
  235. write_id(id);
  236. write_string(n);
  237. flush();
  238. }
  239. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, const char * s, const char * v)
  240. {
  241. #ifdef TRACE
  242. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << s << ", " << v << ")\n";
  243. #endif
  244. write_char(f);
  245. write_char(cmd);
  246. write_string(s);
  247. write_string(v);
  248. flush();
  249. }
  250. void UmlCom::send_cmd(CmdFamily f, unsigned int cmd, bool b, const char * s, const char * v)
  251. {
  252. #ifdef TRACE
  253. cout << "UmlCom::send_cmd((CmdFamily) " << f << ", " << cmd << ", " << b << ", " << s << ", " << v << ")\n";
  254. #endif
  255. write_char(f);
  256. write_char(cmd);
  257. write_bool(b);
  258. write_string(s);
  259. write_string(v);
  260. flush();
  261. }
  262. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd)
  263. {
  264. #ifdef TRACE
  265. cout << "UmlCom::send_cmd(id, " << cmd << ")\n";
  266. #endif
  267. write_char(onInstanceCmd);
  268. write_id(id);
  269. write_char(cmd);
  270. flush();
  271. }
  272. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const char * arg)
  273. {
  274. #ifdef TRACE
  275. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg << ")\n";
  276. #endif
  277. write_char(onInstanceCmd);
  278. write_id(id);
  279. write_char(cmd);
  280. write_string(arg);
  281. flush();
  282. }
  283. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, char arg)
  284. {
  285. #ifdef TRACE
  286. cout << "UmlCom::send_cmd(id, " << cmd << ", " << ((int) arg) << '\n';
  287. #endif
  288. write_char(onInstanceCmd);
  289. write_id(id);
  290. write_char(cmd);
  291. write_char(arg);
  292. flush();
  293. }
  294. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, unsigned int arg)
  295. {
  296. #ifdef TRACE
  297. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg << '\n';
  298. #endif
  299. write_char(onInstanceCmd);
  300. write_id(id);
  301. write_char(cmd);
  302. write_unsigned(arg);
  303. flush();
  304. }
  305. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const UmlTypeSpec & arg)
  306. {
  307. #ifdef TRACE
  308. cout << "UmlCom::send_cmd(id, " << cmd << ", UmlTypeSpec)\n";
  309. #endif
  310. write_char(onInstanceCmd);
  311. write_id(id);
  312. write_char(cmd);
  313. if (arg.type) {
  314. write_id(arg.type->_identifier);
  315. write_string("");
  316. }
  317. else {
  318. write_id(0);
  319. write_string(arg.explicit_type);
  320. }
  321. flush();
  322. }
  323. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const char * arg1, const char * arg2)
  324. {
  325. #ifdef TRACE
  326. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << ", " << arg2 << ")\n";
  327. #endif
  328. write_char(onInstanceCmd);
  329. write_id(id);
  330. write_char(cmd);
  331. write_string(arg1);
  332. write_string(arg2);
  333. flush();
  334. }
  335. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, anItemKind arg1, const char * arg2)
  336. {
  337. #ifdef TRACE
  338. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << ", " << arg2 << ")\n";
  339. #endif
  340. write_char(onInstanceCmd);
  341. write_id(id);
  342. write_char(cmd);
  343. write_char(arg1);
  344. write_string(arg2);
  345. flush();
  346. }
  347. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, anItemKind arg1, aRelationKind arg2, const void * id2)
  348. {
  349. #ifdef TRACE
  350. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << ", " << arg2 << ", " << id2 << ")\n";
  351. #endif
  352. write_char(onInstanceCmd);
  353. write_id(id);
  354. write_char(cmd);
  355. write_char(arg1);
  356. write_char(arg2);
  357. write_id(id2);
  358. flush();
  359. }
  360. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const void * id1)
  361. {
  362. #ifdef TRACE
  363. cout << "UmlCom::send_cmd(id, " << cmd << ", id1)\n";
  364. #endif
  365. write_char(onInstanceCmd);
  366. write_id(id);
  367. write_char(cmd);
  368. write_id(id1);
  369. flush();
  370. }
  371. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const void * id1, const char * arg2)
  372. {
  373. #ifdef TRACE
  374. cout << "UmlCom::send_cmd(id, " << cmd << ", id1, " << arg2 << ")\n";
  375. #endif
  376. write_char(onInstanceCmd);
  377. write_id(id);
  378. write_char(cmd);
  379. write_id(id1);
  380. write_string(arg2);
  381. flush();
  382. }
  383. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, unsigned int arg1, const UmlTypeSpec & arg2)
  384. {
  385. #ifdef TRACE
  386. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << ", UmlTypeSpec)\n";
  387. #endif
  388. write_char(onInstanceCmd);
  389. write_id(id);
  390. write_char(cmd);
  391. write_unsigned(arg1);
  392. if (arg2.type) {
  393. write_id(arg2.type->_identifier);
  394. write_string("");
  395. }
  396. else {
  397. write_id(0);
  398. write_string(arg2.explicit_type);
  399. }
  400. flush();
  401. }
  402. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, unsigned int arg1, const char * arg2, const char * arg3, const UmlTypeSpec & arg4, const UmlTypeSpec & arg5)
  403. {
  404. #ifdef DEBUGBOUML
  405. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << \", \"" << arg2 << "\", \"" << arg3 << "\", " << ", UmlTypeSpec, UmlTypeSpec)\n";
  406. #endif
  407. write_char(onInstanceCmd);
  408. write_id(id);
  409. write_char(cmd);
  410. write_unsigned(arg1);
  411. write_string(arg2);
  412. write_string(arg3);
  413. if (arg4.type) {
  414. write_id(arg4.type->_identifier);
  415. write_string("");
  416. }
  417. else {
  418. write_id(0);
  419. write_string(arg4.explicit_type);
  420. }
  421. if (arg5.type) {
  422. write_id(arg5.type->_identifier);
  423. write_string("");
  424. }
  425. else {
  426. write_id(0);
  427. write_string(arg5.explicit_type);
  428. }
  429. flush();
  430. }
  431. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, unsigned int arg1, char arg2, const char * arg3, const char * arg4, const UmlTypeSpec & arg5)
  432. {
  433. #ifdef TRACE
  434. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg1 << ", " << arg2 << ", " << arg3 << ", " << arg4 << ", UmlTypeSpec)\n";
  435. #endif
  436. write_char(onInstanceCmd);
  437. write_id(id);
  438. write_char(cmd);
  439. write_unsigned(arg1);
  440. write_char(arg2);
  441. write_string(arg3);
  442. write_string(arg4);
  443. if (arg5.type) {
  444. write_id(arg5.type->_identifier);
  445. write_string("");
  446. }
  447. else {
  448. write_id(0);
  449. write_string(arg5.explicit_type);
  450. }
  451. flush();
  452. }
  453. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, const QVector<UmlItem> & l)
  454. {
  455. #ifdef TRACE
  456. cout << "UmlCom::send_cmd(id, " << cmd << ", const QVector<UmlItem> & l)\n";
  457. #endif
  458. write_char(onInstanceCmd);
  459. write_id(id);
  460. write_char(cmd);
  461. unsigned n = l.count();
  462. write_unsigned(n);
  463. for (unsigned i = 0; i != n; i += 1)
  464. write_id(((UmlBaseItem *) l[i])->_identifier);
  465. flush();
  466. }
  467. void UmlCom::send_cmd(const void * id, OnInstanceCmd cmd, anItemKind arg, const void * id2)
  468. {
  469. #ifdef TRACE
  470. cout << "UmlCom::send_cmd(id, " << cmd << ", " << arg << ", " << id2 << ")\n";
  471. #endif
  472. write_char(onInstanceCmd);
  473. write_id(id);
  474. write_char(cmd);
  475. write_char(arg);
  476. write_id(id2);
  477. flush();
  478. }
  479. void * UmlCom::read_id()
  480. {
  481. read_if_needed();
  482. void * a;
  483. // sizeof(void *) must be the same for bouml and
  484. // the plug-out, bypass it
  485. memcpy((char *) &a, p_buffer_in + 1, sizeof(void *));
  486. p_buffer_in += sizeof(void *) + 1;
  487. return a;
  488. }
  489. const char * UmlCom::read_string()
  490. {
  491. read_if_needed();
  492. unsigned len = strlen(p_buffer_in) + 1;
  493. p_buffer_in += len;
  494. #ifdef TRACE
  495. //cout << "UmlCom::read_string : \"" << p_buffer_in - len << "\"\n";
  496. #endif
  497. return p_buffer_in - len;
  498. }
  499. bool UmlCom::read_bool()
  500. {
  501. read_if_needed();
  502. return *p_buffer_in++ != 0;
  503. }
  504. char UmlCom::read_char()
  505. {
  506. read_if_needed();
  507. return *p_buffer_in++;
  508. }
  509. unsigned int UmlCom::read_unsigned()
  510. {
  511. read_if_needed();
  512. p_buffer_in += 4;
  513. return (((unsigned char *) p_buffer_in)[-4] << 24) +
  514. (((unsigned char *) p_buffer_in)[-3] << 16) +
  515. (((unsigned char *) p_buffer_in)[-2] << 8) +
  516. ((unsigned char *) p_buffer_in)[-1];
  517. }
  518. void UmlCom::read_item_list(QVector<UmlItem> & v)
  519. {
  520. unsigned n = read_unsigned();
  521. v.resize(n);
  522. #ifdef TRACE
  523. //cout << "UmlCom::read_item_list " << n << " items\n";
  524. #endif
  525. for (unsigned index = 0; index != n; index += 1)
  526. v.insert(index, UmlBaseItem::read_());
  527. }
  528. void UmlCom::fatal_error(const QCString &
  529. #ifdef DEBUG_BOUML
  530. msg
  531. #endif
  532. )
  533. {
  534. #ifdef DEBUG_BOUML
  535. cout << msg << '\n';
  536. #endif
  537. throw 0;
  538. }
  539. void UmlCom::flush()
  540. {
  541. if (sock != 0) {
  542. int len = p_buffer_out - buffer_out - 4;
  543. /* the four first bytes of buffer_out are free to contains the length */
  544. buffer_out[0] = len >> 24;
  545. buffer_out[1] = len >> 16;
  546. buffer_out[2] = len >> 8;
  547. buffer_out[3] = len;
  548. len += 4;
  549. p_buffer_out = buffer_out;
  550. for (;;) {
  551. int sent = sock->writeBlock(p_buffer_out, len);
  552. if (sent == -1) {
  553. close(); // to not try to send "bye" !
  554. fatal_error("send error");
  555. }
  556. else if ((len -= sent) == 0) {
  557. sock->flush();
  558. p_buffer_out = buffer_out + 4/*bytes for length*/;
  559. return;
  560. }
  561. else
  562. p_buffer_out += sent;
  563. }
  564. }
  565. }