COMBUF.CPP 50 KB

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