COMBUF.CPP 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: F:\projects\c&c\vcs\code\combuf.cpv 1.4 16 Oct 1995 16:50:16 JOE_BOSTIC $ */
  15. /***************************************************************************
  16. ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  17. ***************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : COMBUF.CPP *
  22. * *
  23. * Programmer : Bill Randolph *
  24. * *
  25. * Start Date : December 19, 1994 *
  26. * *
  27. * Last Update : May 2, 1995 [BRR] *
  28. * *
  29. *-------------------------------------------------------------------------*
  30. * Functions: *
  31. * CommBufferClass::CommBufferClass -- class constructor *
  32. * CommBufferClass::~CommBufferClass -- class destructor *
  33. * CommBufferClass::Init -- initializes this queue *
  34. * CommBufferClass::Queue_Send -- queues a message for sending *
  35. * CommBufferClass::UnQueue_Send -- removes next entry from send queue *
  36. * CommBufferClass::Get_Send -- gets ptr to queue entry *
  37. * CommBufferClass::Queue_Receive -- queues a received message *
  38. * CommBufferClass::UnQueue_Receive -- removes next entry from send queue*
  39. * CommBufferClass::Get_Receive -- gets ptr to queue entry *
  40. * CommBufferClass::Add_Delay -- adds a new delay value for response time*
  41. * CommBufferClass::Avg_Response_Time -- returns average response time *
  42. * CommBufferClass::Max_Response_Time -- returns max response time *
  43. * CommBufferClass::Reset_Response_Time -- resets computations *
  44. * Mono_Debug_Print -- Debug output routine *
  45. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  46. #include "function.h"
  47. /***************************************************************************
  48. * CommBufferClass::CommBufferClass -- class constructor *
  49. * *
  50. * INPUT: *
  51. * numsend # queue entries for sending *
  52. * numreceive # queue entries for receiving *
  53. * maxlen maximum desired packet length, in bytes *
  54. * *
  55. * OUTPUT: *
  56. * none. *
  57. * *
  58. * WARNINGS: *
  59. * none. *
  60. * *
  61. * HISTORY: *
  62. * 12/19/1994 BR : Created. *
  63. *=========================================================================*/
  64. CommBufferClass::CommBufferClass(int numsend, int numreceive, int maxlen)
  65. {
  66. int i;
  67. /*
  68. ----------------------------- Init variables -----------------------------
  69. */
  70. MaxSend = numsend;
  71. MaxReceive = numreceive;
  72. MaxPacketSize = maxlen;
  73. /*
  74. ----------------------- Allocate the queue entries -----------------------
  75. */
  76. SendQueue = new SendQueueType[numsend];
  77. ReceiveQueue = new ReceiveQueueType[numreceive];
  78. SendIndex = new int[numsend];
  79. ReceiveIndex = new int[numreceive];
  80. /*
  81. ---------------------- Allocate queue entry buffers ----------------------
  82. */
  83. for (i = 0; i < MaxSend; i++) {
  84. SendQueue[i].Buffer = new char[maxlen];
  85. }
  86. for (i = 0; i < MaxReceive; i++) {
  87. ReceiveQueue[i].Buffer = new char[maxlen];
  88. }
  89. Init();
  90. } /* end of CommBufferClass */
  91. /***************************************************************************
  92. * CommBufferClass::~CommBufferClass -- class destructor *
  93. * *
  94. * INPUT: *
  95. * none. *
  96. * *
  97. * OUTPUT: *
  98. * none. *
  99. * *
  100. * WARNINGS: *
  101. * none. *
  102. * *
  103. * HISTORY: *
  104. * 12/19/1994 BR : Created. *
  105. *=========================================================================*/
  106. CommBufferClass::~CommBufferClass()
  107. {
  108. int i;
  109. /*
  110. ------------------------ Free queue entry buffers ------------------------
  111. */
  112. for (i = 0; i < MaxSend; i++) {
  113. delete [] SendQueue[i].Buffer;
  114. }
  115. for (i = 0; i < MaxReceive; i++) {
  116. delete [] ReceiveQueue[i].Buffer;
  117. }
  118. delete [] SendQueue;
  119. delete [] ReceiveQueue;
  120. delete [] SendIndex;
  121. delete [] ReceiveIndex;
  122. } /* end of ~CommBufferClass */
  123. /***************************************************************************
  124. * CommBufferClass::Init -- initializes this queue *
  125. * *
  126. * INPUT: *
  127. * none. *
  128. * *
  129. * OUTPUT: *
  130. * none. *
  131. * *
  132. * WARNINGS: *
  133. * none. *
  134. * *
  135. * HISTORY: *
  136. * 01/20/1995 BR : Created. *
  137. *=========================================================================*/
  138. void CommBufferClass::Init(void)
  139. {
  140. int i;
  141. /*------------------------------------------------------------------------
  142. Init data members
  143. ------------------------------------------------------------------------*/
  144. SendTotal = 0L;
  145. ReceiveTotal = 0L;
  146. DelaySum = 0L;
  147. NumDelay = 0L;
  148. MeanDelay = 0L;
  149. MaxDelay = 0L;
  150. SendCount = 0;
  151. ReceiveCount = 0;
  152. /*------------------------------------------------------------------------
  153. Init the queue entries
  154. ------------------------------------------------------------------------*/
  155. for (i = 0; i < MaxSend; i++) {
  156. SendQueue[i].IsActive = 0;
  157. SendQueue[i].IsACK = 0;
  158. SendQueue[i].FirstTime = 0L;
  159. SendQueue[i].LastTime = 0L;
  160. SendQueue[i].SendCount = 0L;
  161. SendQueue[i].BufLen = 0;
  162. SendIndex[i] = 0;
  163. }
  164. for (i = 0; i < MaxReceive; i++) {
  165. ReceiveQueue[i].IsActive = 0;
  166. ReceiveQueue[i].IsRead = 0;
  167. ReceiveQueue[i].IsACK = 0;
  168. ReceiveQueue[i].BufLen = 0;
  169. ReceiveIndex[i] = 0;
  170. }
  171. /*------------------------------------------------------------------------
  172. Init debug values
  173. ------------------------------------------------------------------------*/
  174. DebugOffset = 0;
  175. DebugSize = 0;
  176. DebugNames = NULL;
  177. DebugMaxNames = 0;
  178. } /* end of Init */
  179. void CommBufferClass::Init_Send_Queue(void)
  180. {
  181. int i;
  182. /*------------------------------------------------------------------------
  183. Init data members
  184. ------------------------------------------------------------------------*/
  185. SendCount = 0;
  186. /*------------------------------------------------------------------------
  187. Init the queue entries
  188. ------------------------------------------------------------------------*/
  189. for (i = 0; i < MaxSend; i++) {
  190. SendQueue[i].IsActive = 0;
  191. SendQueue[i].IsACK = 0;
  192. SendQueue[i].FirstTime = 0L;
  193. SendQueue[i].LastTime = 0L;
  194. SendQueue[i].SendCount = 0L;
  195. SendIndex[i] = 0;
  196. }
  197. } /* end of Init_Send_Queue */
  198. /***************************************************************************
  199. * CommBufferClass::Queue_Send -- queues a message for sending *
  200. * *
  201. * INPUT: *
  202. * buf buffer containing the message *
  203. * buflen length of 'buf' *
  204. * *
  205. * OUTPUT: *
  206. * 1 = OK, 0 = no room in the queue *
  207. * *
  208. * WARNINGS: *
  209. * none. *
  210. * *
  211. * HISTORY: *
  212. * 12/20/1994 BR : Created. *
  213. *=========================================================================*/
  214. int CommBufferClass::Queue_Send(void *buf, int buflen)
  215. {
  216. int i;
  217. int index;
  218. /*
  219. --------------------- Error if no room in the queue ----------------------
  220. */
  221. if (SendCount==MaxSend)
  222. return(0);
  223. /*
  224. -------------------------- Find an empty slot ----------------------------
  225. */
  226. index = -1;
  227. for (i = 0; i < MaxSend; i++) {
  228. if (SendQueue[i].IsActive==0) {
  229. index = i;
  230. break;
  231. }
  232. }
  233. /*
  234. ---------------------------- Set entry flags -----------------------------
  235. */
  236. SendQueue[index].IsActive = 1; // entry is now active
  237. SendQueue[index].IsACK = 0; // entry hasn't been ACK'd
  238. SendQueue[index].FirstTime = 0L; // filled in by Manager when sent
  239. SendQueue[index].LastTime = 0L; // filled in by Manager when sent
  240. SendQueue[index].SendCount = 0L; // filled in by Manager when sent
  241. SendQueue[index].BufLen = buflen; // save buffer size
  242. /*
  243. ------------------------- Copy the packet data ---------------------------
  244. */
  245. memcpy(SendQueue[index].Buffer,buf,buflen);
  246. /*
  247. ----------------------- Save this entry's index --------------------------
  248. */
  249. SendIndex[SendCount] = index;
  250. /*
  251. -------------------- Increment counters & entry ptr ----------------------
  252. */
  253. SendCount++;
  254. SendTotal++;
  255. return(1);
  256. } /* end of Queue_Send */
  257. /***************************************************************************
  258. * CommBufferClass::UnQueue_Send -- removes next entry from send queue *
  259. * *
  260. * Frees the given entry; the index given by the caller is the "active" *
  261. * index value (ie the "nth" active entry), not the actual index in the *
  262. * array. *
  263. * *
  264. * INPUT: *
  265. * buf buffer to store entry's data in; if NULL, it's discarded *
  266. * buflen filled in with length of entry retrieved *
  267. * index "index" of entry to un-queue *
  268. * *
  269. * OUTPUT: *
  270. * 1 = OK, 0 = no entry to retreive *
  271. * *
  272. * WARNINGS: *
  273. * none. *
  274. * *
  275. * HISTORY: *
  276. * 12/20/1994 BR : Created. *
  277. *=========================================================================*/
  278. int CommBufferClass::UnQueue_Send(void *buf, int *buflen, int index)
  279. {
  280. int i;
  281. /*
  282. --------------------- Error if no entry to retrieve ----------------------
  283. */
  284. if (SendCount==0 || SendQueue[SendIndex[index]].IsActive==0)
  285. return(0);
  286. /*
  287. ---------------------- Copy the data from the entry ----------------------
  288. */
  289. if (buf!=NULL) {
  290. memcpy(buf,SendQueue[SendIndex[index]].Buffer,
  291. SendQueue[SendIndex[index]].BufLen);
  292. (*buflen) = SendQueue[SendIndex[index]].BufLen;
  293. }
  294. /*
  295. ---------------------------- Set entry flags -----------------------------
  296. */
  297. SendQueue[SendIndex[index]].IsActive = 0;
  298. SendQueue[SendIndex[index]].IsACK = 0;
  299. SendQueue[SendIndex[index]].FirstTime = 0L;
  300. SendQueue[SendIndex[index]].LastTime = 0L;
  301. SendQueue[SendIndex[index]].SendCount = 0L;
  302. SendQueue[SendIndex[index]].BufLen = 0;
  303. /*
  304. ------------------------- Move Indices back one --------------------------
  305. */
  306. for (i = index; i < SendCount - 1; i++) {
  307. SendIndex[i] = SendIndex[i + 1];
  308. }
  309. SendIndex[SendCount - 1] = 0;
  310. SendCount--;
  311. return(1);
  312. } /* end of UnQueue_Send */
  313. /***************************************************************************
  314. * CommBufferClass::Get_Send -- gets ptr to queue entry *
  315. * *
  316. * This routine gets a pointer to the indicated queue entry. The index *
  317. * value is relative to the next-accessable queue entry; 0 = get the *
  318. * next available queue entry, 1 = get the one behind that, etc. *
  319. * *
  320. * INPUT: *
  321. * index index of entry to get (0 = 1st available) *
  322. * *
  323. * OUTPUT: *
  324. * ptr to entry *
  325. * *
  326. * WARNINGS: *
  327. * none. *
  328. * *
  329. * HISTORY: *
  330. * 12/21/1994 BR : Created. *
  331. *=========================================================================*/
  332. SendQueueType * CommBufferClass::Get_Send(int index)
  333. {
  334. if (SendQueue[SendIndex[index]].IsActive==0) {
  335. return(NULL);
  336. } else {
  337. return(&SendQueue[SendIndex[index]]);
  338. }
  339. } /* end of Get_Send */
  340. /***************************************************************************
  341. * CommBufferClass::Queue_Receive -- queues a received message *
  342. * *
  343. * INPUT: *
  344. * buf buffer containing the message *
  345. * buflen length of 'buf' *
  346. * *
  347. * OUTPUT: *
  348. * 1 = OK, 0 = no room in the queue *
  349. * *
  350. * WARNINGS: *
  351. * none. *
  352. * *
  353. * HISTORY: *
  354. * 12/20/1994 BR : Created. *
  355. *=========================================================================*/
  356. int CommBufferClass::Queue_Receive(void *buf, int buflen)
  357. {
  358. int i;
  359. int index;
  360. //CCDebugString ("C&C95 - Queueing a receive packet\n");
  361. /*
  362. --------------------- Error if no room in the queue ----------------------
  363. */
  364. if (ReceiveCount==MaxReceive) {
  365. CCDebugString ("C&C95 - Error - Receive queue full!\n");
  366. return(0);
  367. }
  368. /*
  369. -------------------------- Find an empty slot ----------------------------
  370. */
  371. index = -1;
  372. for (i = 0; i < MaxReceive; i++) {
  373. if (ReceiveQueue[i].IsActive==0) {
  374. index = i;
  375. break;
  376. }
  377. }
  378. if (index == -1){
  379. CCDebugString ("C&C95 - Error - Receive queue full too!\n");
  380. }
  381. /*
  382. ---------------------------- Set entry flags -----------------------------
  383. */
  384. ReceiveQueue[index].IsActive = 1;
  385. ReceiveQueue[index].IsRead = 0;
  386. ReceiveQueue[index].IsACK = 0;
  387. ReceiveQueue[index].BufLen = buflen;
  388. /*
  389. ------------------------- Copy the packet data ---------------------------
  390. */
  391. memcpy(ReceiveQueue[index].Buffer,buf,buflen);
  392. /*
  393. ----------------------- Save this entry's index --------------------------
  394. */
  395. ReceiveIndex[ReceiveCount] = index;
  396. /*
  397. -------------------- Increment counters & entry ptr ----------------------
  398. */
  399. ReceiveCount++;
  400. ReceiveTotal++;
  401. return(1);
  402. } /* end of Queue_Receive */
  403. /***************************************************************************
  404. * CommBufferClass::UnQueue_Receive -- removes next entry from send queue *
  405. * *
  406. * Frees the given entry; the index given by the caller is the "active" *
  407. * index value (ie the "nth" active entry), not the actual index in the *
  408. * array. *
  409. * *
  410. * INPUT: *
  411. * buf buffer to store entry's data in; if NULL, it's discarded *
  412. * buflen filled in with length of entry retrieved *
  413. * index index of entry to un-queue *
  414. * *
  415. * OUTPUT: *
  416. * 1 = OK, 0 = no entry to retreive *
  417. * *
  418. * WARNINGS: *
  419. * none. *
  420. * *
  421. * HISTORY: *
  422. * 12/20/1994 BR : Created. *
  423. *=========================================================================*/
  424. int CommBufferClass::UnQueue_Receive(void *buf, int *buflen, int index)
  425. {
  426. int i;
  427. /*
  428. --------------------- Error if no entry to retrieve ----------------------
  429. */
  430. if (ReceiveCount==0 || ReceiveQueue[ReceiveIndex[index]].IsActive==0) {
  431. return(0);
  432. }
  433. /*
  434. ---------------------- Copy the data from the entry ----------------------
  435. */
  436. if (buf!=NULL) {
  437. memcpy(buf,ReceiveQueue[ReceiveIndex[index]].Buffer,
  438. ReceiveQueue[ReceiveIndex[index]].BufLen);
  439. (*buflen) = ReceiveQueue[ReceiveIndex[index]].BufLen;
  440. }
  441. /*
  442. ---------------------------- Set entry flags -----------------------------
  443. */
  444. ReceiveQueue[ReceiveIndex[index]].IsActive = 0;
  445. ReceiveQueue[ReceiveIndex[index]].IsRead = 0;
  446. ReceiveQueue[ReceiveIndex[index]].IsACK = 0;
  447. ReceiveQueue[ReceiveIndex[index]].BufLen = 0;
  448. /*
  449. ------------------------- Move Indices back one --------------------------
  450. */
  451. for (i = index; i < ReceiveCount - 1; i++) {
  452. ReceiveIndex[i] = ReceiveIndex[i + 1];
  453. }
  454. ReceiveIndex[ReceiveCount - 1] = 0;
  455. ReceiveCount--;
  456. return(1);
  457. } /* end of UnQueue_Receive */
  458. /***************************************************************************
  459. * CommBufferClass::Get_Receive -- gets ptr to queue entry *
  460. * *
  461. * This routine gets a pointer to the indicated queue entry. The index *
  462. * value is relative to the next-accessable queue entry; 0 = get the *
  463. * next available queue entry, 1 = get the one behind that, etc. *
  464. * *
  465. * INPUT: *
  466. * index index of entry to get (0 = 1st available) *
  467. * *
  468. * OUTPUT: *
  469. * ptr to entry *
  470. * *
  471. * WARNINGS: *
  472. * none. *
  473. * *
  474. * HISTORY: *
  475. * 12/21/1994 BR : Created. *
  476. *=========================================================================*/
  477. ReceiveQueueType * CommBufferClass::Get_Receive(int index)
  478. {
  479. if (ReceiveQueue[ReceiveIndex[index]].IsActive==0) {
  480. return(NULL);
  481. } else {
  482. return(&ReceiveQueue[ReceiveIndex[index]]);
  483. }
  484. } /* end of Get_Receive */
  485. /***************************************************************************
  486. * CommBufferClass::Add_Delay -- adds a new delay value for response time *
  487. * *
  488. * This routine updates the average response time for this queue. The *
  489. * computation is based on the average of the last 'n' delay values given, *
  490. * It computes a running total of the last n delay values, then divides *
  491. * that by n to compute the average. *
  492. * *
  493. * When the number of values given exceeds the max, the mean is subtracted *
  494. * off the total, then the new value is added in. Thus, any single delay *
  495. * value will have an effect on the total that approaches 0 over time, and *
  496. * the new delay value contributes to 1/n of the mean. *
  497. * *
  498. * INPUT: *
  499. * delay value to add into the response time computation *
  500. * *
  501. * OUTPUT: *
  502. * none. *
  503. * *
  504. * WARNINGS: *
  505. * none. *
  506. * *
  507. * HISTORY: *
  508. * 01/19/1995 BR : Created. *
  509. *=========================================================================*/
  510. void CommBufferClass::Add_Delay(unsigned long delay)
  511. {
  512. int roundoff = 0;
  513. if (NumDelay==256) {
  514. DelaySum -= MeanDelay;
  515. DelaySum += delay;
  516. if ( (DelaySum & 0x00ff) > 127)
  517. roundoff = 1;
  518. MeanDelay = (DelaySum >> 8) + roundoff;
  519. } else {
  520. NumDelay++;
  521. DelaySum += delay;
  522. MeanDelay = DelaySum / NumDelay;
  523. }
  524. if (delay > MaxDelay)
  525. MaxDelay = delay;
  526. } /* end of Add_Delay */
  527. /***************************************************************************
  528. * CommBufferClass::Avg_Response_Time -- returns average response time *
  529. * *
  530. * INPUT: *
  531. * none. *
  532. * *
  533. * OUTPUT: *
  534. * latest computed average response time *
  535. * *
  536. * WARNINGS: *
  537. * none. *
  538. * *
  539. * HISTORY: *
  540. * 01/19/1995 BR : Created. *
  541. *=========================================================================*/
  542. unsigned long CommBufferClass::Avg_Response_Time(void)
  543. {
  544. return(MeanDelay);
  545. } /* end of Avg_Response_Time */
  546. /***************************************************************************
  547. * CommBufferClass::Max_Response_Time -- returns max response time *
  548. * *
  549. * INPUT: *
  550. * none. *
  551. * *
  552. * OUTPUT: *
  553. * latest computed average response time *
  554. * *
  555. * WARNINGS: *
  556. * none. *
  557. * *
  558. * HISTORY: *
  559. * 01/19/1995 BR : Created. *
  560. *=========================================================================*/
  561. unsigned long CommBufferClass::Max_Response_Time(void)
  562. {
  563. return(MaxDelay);
  564. } /* end of Max_Response_Time */
  565. /***************************************************************************
  566. * CommBufferClass::Reset_Response_Time -- resets computations *
  567. * *
  568. * INPUT: *
  569. * none. *
  570. * *
  571. * OUTPUT: *
  572. * none. *
  573. * *
  574. * WARNINGS: *
  575. * none. *
  576. * *
  577. * HISTORY: *
  578. * 01/19/1995 BR : Created. *
  579. *=========================================================================*/
  580. void CommBufferClass::Reset_Response_Time(void)
  581. {
  582. DelaySum = 0L;
  583. NumDelay = 0L;
  584. MeanDelay = 0L;
  585. MaxDelay = 0L;
  586. } /* end of Reset_Response_Time */
  587. /***************************************************************************
  588. * CommBufferClass::Configure_Debug -- sets up special debug values *
  589. * *
  590. * Mono_Debug_Print2() can look into a packet to pull out a particular *
  591. * ID, and can print both that ID and a string corresponding to *
  592. * that ID. This routine configures these values so it can find *
  593. * and decode the ID. This ID is used in addition to the normal *
  594. * CommHeaderType values. *
  595. * *
  596. * INPUT: *
  597. * offset ID's byte offset into packet *
  598. * size size of ID, in bytes; 0 if none *
  599. * names ptr to array of names; use ID as an index into this *
  600. * maxnames max # in the names array; 0 if none. *
  601. * *
  602. * OUTPUT: *
  603. * none. *
  604. * *
  605. * WARNINGS: *
  606. * Names shouldn't be longer than 12 characters. *
  607. * *
  608. * HISTORY: *
  609. * 05/31/1995 BRR : Created. *
  610. *=========================================================================*/
  611. void CommBufferClass::Configure_Debug(int offset, int size, char **names,
  612. int maxnames)
  613. {
  614. DebugOffset = offset;
  615. DebugSize = size;
  616. DebugNames = names;
  617. DebugMaxNames = maxnames;
  618. } /* end of Configure_Debug */
  619. /***************************************************************************
  620. * Mono_Debug_Print -- Debug output routine *
  621. * *
  622. * This routine leaves 5 lines at the top for the caller's use. *
  623. * *
  624. * INPUT: *
  625. * refresh 1 = clear screen & completely refresh *
  626. * *
  627. * OUTPUT: *
  628. * none. *
  629. * *
  630. * WARNINGS: *
  631. * none. *
  632. * *
  633. * HISTORY: *
  634. * 05/02/1995 BRR : Created. *
  635. *=========================================================================*/
  636. void CommBufferClass::Mono_Debug_Print(int refresh)
  637. {
  638. #ifdef WWLIB32_H
  639. int i; // loop counter
  640. static int send_col[] = {1,14,28}; // coords of send queue columns
  641. static int receive_col[] = {40,54,68}; // coords of recv queue columns
  642. int row,col; // current row,col for printing
  643. int num; // max # items to print
  644. struct CommHdr { // this mirrors the CommHeaderType
  645. unsigned short MagicNumber;
  646. unsigned char Code;
  647. unsigned long PacketID;
  648. } *hdr;
  649. /*------------------------------------------------------------------------
  650. If few enough entries, call the verbose debug version
  651. ------------------------------------------------------------------------*/
  652. if (MaxSend <= 16) {
  653. Mono_Debug_Print2(refresh);
  654. return;
  655. }
  656. /*------------------------------------------------------------------------
  657. Refresh the screen
  658. ------------------------------------------------------------------------*/
  659. if (refresh) {
  660. Mono_Clear_Screen ();
  661. Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
  662. Mono_Printf("³ ³\n");
  663. Mono_Printf("³ ³\n");
  664. Mono_Printf("³ ³\n");
  665. Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
  666. Mono_Printf("³ Send Queue ³ Receive Queue ³\n");
  667. Mono_Printf("³ ³ ³\n");
  668. Mono_Printf("³ ID Ct ACK ID Ct ACK ID Ct ACK³ ID Rd ACK ID Rd ACK ID Rd ACK³\n");
  669. Mono_Printf("³ ³ ³\n");
  670. Mono_Printf("³ ³ ³\n");
  671. Mono_Printf("³ ³ ³\n");
  672. Mono_Printf("³ ³ ³\n");
  673. Mono_Printf("³ ³ ³\n");
  674. Mono_Printf("³ ³ ³\n");
  675. Mono_Printf("³ ³ ³\n");
  676. Mono_Printf("³ ³ ³\n");
  677. Mono_Printf("³ ³ ³\n");
  678. Mono_Printf("³ ³ ³\n");
  679. Mono_Printf("³ ³ ³\n");
  680. Mono_Printf("³ ³ ³\n");
  681. Mono_Printf("³ ³ ³\n");
  682. Mono_Printf("³ ³ ³\n");
  683. Mono_Printf("³ ³ ³\n");
  684. Mono_Printf("³ ³ ³\n");
  685. Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
  686. }
  687. /*------------------------------------------------------------------------
  688. Print Send Queue items
  689. ------------------------------------------------------------------------*/
  690. if (MaxSend <= 48) {
  691. num = MaxSend;
  692. } else {
  693. num = 48;
  694. }
  695. col = 0;
  696. row = 0;
  697. for (i = 0; i < MaxSend; i++) {
  698. Mono_Set_Cursor (send_col[col],row + 8);
  699. if (SendQueue[i].IsActive) {
  700. hdr = (CommHdr *)SendQueue[i].Buffer;
  701. hdr->MagicNumber = hdr->MagicNumber;
  702. hdr->Code = hdr->Code;
  703. Mono_Printf ("%4d %2d %d",hdr->PacketID, SendQueue[i].SendCount,
  704. SendQueue[i].IsACK);
  705. } else {
  706. Mono_Printf ("____ __ _ ");
  707. }
  708. row++;
  709. if (row > 15) {
  710. row = 0;
  711. col++;
  712. }
  713. }
  714. /*------------------------------------------------------------------------
  715. Print Receive Queue items
  716. ------------------------------------------------------------------------*/
  717. if (MaxReceive <= 48) {
  718. num = MaxSend;
  719. } else {
  720. num = 48;
  721. }
  722. col = 0;
  723. row = 0;
  724. for (i = 0; i < MaxReceive; i++) {
  725. Mono_Set_Cursor (receive_col[col],row + 8);
  726. if (ReceiveQueue[i].IsActive) {
  727. hdr = (CommHdr *)ReceiveQueue[i].Buffer;
  728. Mono_Printf ("%4d %d %d",hdr->PacketID, ReceiveQueue[i].IsRead,
  729. ReceiveQueue[i].IsACK);
  730. } else {
  731. Mono_Printf ("____ _ _ ");
  732. }
  733. row++;
  734. if (row > 15) {
  735. row = 0;
  736. col++;
  737. }
  738. }
  739. #else
  740. refresh = refresh;
  741. #endif
  742. } /* end of Mono_Debug_Print */
  743. /***************************************************************************
  744. * CommBufferClass::Mono_Debug_Print2 -- Debug output; alternate format *
  745. * *
  746. * This routine prints more information than the other version; it's *
  747. * called only if the number of queue entries is small enough to support *
  748. * this format. *
  749. * *
  750. * INPUT: *
  751. * refresh 1 = clear screen & completely refresh *
  752. * *
  753. * OUTPUT: *
  754. * none. *
  755. * *
  756. * WARNINGS: *
  757. * none. *
  758. * *
  759. * HISTORY: *
  760. * 05/31/1995 BRR : Created. *
  761. *=========================================================================*/
  762. void CommBufferClass::Mono_Debug_Print2(int refresh)
  763. {
  764. #ifdef WWLIB32_H
  765. int i; // loop counter
  766. char txt[80];
  767. int val;
  768. struct CommHdr { // this mirrors the CommHeaderType
  769. unsigned short MagicNumber;
  770. unsigned char Code;
  771. unsigned long PacketID;
  772. } *hdr;
  773. /*------------------------------------------------------------------------
  774. Refresh the screen
  775. ------------------------------------------------------------------------*/
  776. if (refresh) {
  777. Mono_Clear_Screen ();
  778. Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
  779. Mono_Printf("³ ³\n");
  780. Mono_Printf("³ ³\n");
  781. Mono_Printf("³ ³\n");
  782. Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
  783. Mono_Printf("³ Send Queue ³ Receive Queue ³\n");
  784. Mono_Printf("³ ³ ³\n");
  785. Mono_Printf("³ ID Ct Type Data Name ACK ³ ID Rd Type Data Name ACK ³\n");
  786. Mono_Printf("³ ³ ³\n");
  787. Mono_Printf("³ ³ ³\n");
  788. Mono_Printf("³ ³ ³\n");
  789. Mono_Printf("³ ³ ³\n");
  790. Mono_Printf("³ ³ ³\n");
  791. Mono_Printf("³ ³ ³\n");
  792. Mono_Printf("³ ³ ³\n");
  793. Mono_Printf("³ ³ ³\n");
  794. Mono_Printf("³ ³ ³\n");
  795. Mono_Printf("³ ³ ³\n");
  796. Mono_Printf("³ ³ ³\n");
  797. Mono_Printf("³ ³ ³\n");
  798. Mono_Printf("³ ³ ³\n");
  799. Mono_Printf("³ ³ ³\n");
  800. Mono_Printf("³ ³ ³\n");
  801. Mono_Printf("³ ³ ³\n");
  802. Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
  803. }
  804. /*------------------------------------------------------------------------
  805. Print Send Queue items
  806. ------------------------------------------------------------------------*/
  807. for (i = 0; i < MaxSend; i++) {
  808. Mono_Set_Cursor (1,8 + i);
  809. /*.....................................................................
  810. Print an active entry
  811. .....................................................................*/
  812. if (SendQueue[i].IsActive) {
  813. /*..................................................................
  814. Get header info
  815. ..................................................................*/
  816. hdr = (CommHdr *)SendQueue[i].Buffer;
  817. hdr->MagicNumber = hdr->MagicNumber;
  818. hdr->Code = hdr->Code;
  819. sprintf(txt,"%4d %2d %-5s ",
  820. hdr->PacketID,
  821. SendQueue[i].SendCount,
  822. ConnectionClass::Command_Name(hdr->Code));
  823. /*..................................................................
  824. Decode app's ID & its name
  825. ..................................................................*/
  826. if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) {
  827. if (DebugSize==1) {
  828. val = *(SendQueue[i].Buffer + DebugOffset);
  829. } else {
  830. if (DebugSize==2) {
  831. val = *((short *)(SendQueue[i].Buffer + DebugOffset));
  832. } else {
  833. if (DebugSize==4) {
  834. val = *((int *)(SendQueue[i].Buffer + DebugOffset));
  835. }
  836. }
  837. }
  838. sprintf(txt + strlen(txt),"%4d ",val);
  839. if (DebugMaxNames > 0 && val >= 0 && val < DebugMaxNames) {
  840. sprintf(txt + strlen(txt),"%-12s %x", DebugNames[val], SendQueue[i].IsACK);
  841. } else {
  842. sprintf(txt + strlen(txt)," %x",SendQueue[i].IsACK);
  843. }
  844. } else {
  845. sprintf(txt + strlen(txt)," %x",SendQueue[i].IsACK);
  846. }
  847. Mono_Printf("%s",txt);
  848. } else {
  849. /*.....................................................................
  850. Entry isn't active; print blanks
  851. .....................................................................*/
  852. Mono_Printf("____ __ _");
  853. }
  854. }
  855. /*------------------------------------------------------------------------
  856. Print Receive Queue items
  857. ------------------------------------------------------------------------*/
  858. for (i = 0; i < MaxReceive; i++) {
  859. Mono_Set_Cursor (40,8 + i);
  860. /*.....................................................................
  861. Print an active entry
  862. .....................................................................*/
  863. if (ReceiveQueue[i].IsActive) {
  864. /*..................................................................
  865. Get header info
  866. ..................................................................*/
  867. hdr = (CommHdr *)ReceiveQueue[i].Buffer;
  868. hdr->MagicNumber = hdr->MagicNumber;
  869. hdr->Code = hdr->Code;
  870. sprintf(txt,"%4d %2d %-5s ",
  871. hdr->PacketID,
  872. ReceiveQueue[i].IsRead,
  873. ConnectionClass::Command_Name(hdr->Code));
  874. /*..................................................................
  875. Decode app's ID & its name
  876. ..................................................................*/
  877. if (DebugSize && (DebugOffset + DebugSize) <= ReceiveQueue[i].BufLen) {
  878. if (DebugSize==1) {
  879. val = *(ReceiveQueue[i].Buffer + DebugOffset);
  880. } else {
  881. if (DebugSize==2) {
  882. val = *((short *)(ReceiveQueue[i].Buffer + DebugOffset));
  883. } else {
  884. if (DebugSize==4) {
  885. val = *((int *)(ReceiveQueue[i].Buffer + DebugOffset));
  886. }
  887. }
  888. }
  889. sprintf(txt + strlen(txt),"%4d ",val);
  890. if (DebugMaxNames > 0 && val >= 0 && val < DebugMaxNames) {
  891. sprintf(txt + strlen(txt),"%-12s %x",
  892. DebugNames[val],
  893. ReceiveQueue[i].IsACK);
  894. } else {
  895. sprintf(txt + strlen(txt)," %x",ReceiveQueue[i].IsACK);
  896. }
  897. } else {
  898. sprintf(txt + strlen(txt)," %x",ReceiveQueue[i].IsACK);
  899. }
  900. Mono_Printf("%s",txt);
  901. } else {
  902. /*.....................................................................
  903. Entry isn't active; print blanks
  904. .....................................................................*/
  905. Mono_Printf("____ __ _");
  906. }
  907. }
  908. #else
  909. refresh = refresh;
  910. #endif
  911. } /* end of Mono_Debug_Print2 */