This is Unofficial EPICS BASE Doxygen Site
comQueRecv.cpp
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 /*
10  *
11  *
12  * L O S A L A M O S
13  * Los Alamos National Laboratory
14  * Los Alamos, New Mexico 87545
15  *
16  * Copyright, 1986, The Regents of the University of California.
17  *
18  *
19  * Author Jeffrey O. Hill
20  * johill@lanl.gov
21  */
22 
23 #define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
24 
25 #include "iocinf.h"
26 #include "virtualCircuit.h"
27 
28 comQueRecv::comQueRecv ( comBufMemoryManager & comBufMemoryManagerIn ):
29  comBufMemMgr ( comBufMemoryManagerIn ), nBytesPending ( 0u )
30 {
31 }
32 
34 {
35  this->clear ();
36 }
37 
39 {
40  comBuf *pBuf;
41  while ( ( pBuf = this->bufs.get () ) ) {
42  pBuf->~comBuf ();
43  this->comBufMemMgr.release ( pBuf );
44  }
45  this->nBytesPending = 0u;
46 }
47 
48 unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes )
49 {
50  unsigned totalBytes = 0u;
51  do {
52  comBuf * pComBuf = this->bufs.first ();
53  if ( ! pComBuf ) {
54  this->nBytesPending -= totalBytes;
55  return totalBytes;
56  }
57  totalBytes += pComBuf->copyOutBytes ( &pBuf[totalBytes], nBytes - totalBytes );
58  if ( pComBuf->occupiedBytes () == 0u ) {
59  this->bufs.remove ( *pComBuf );
60  pComBuf->~comBuf ();
61  this->comBufMemMgr.release ( pComBuf );
62  }
63  }
64  while ( totalBytes < nBytes );
65  this->nBytesPending -= totalBytes;
66  return totalBytes;
67 }
68 
69 unsigned comQueRecv::removeBytes ( unsigned nBytes )
70 {
71  unsigned totalBytes = 0u;
72  unsigned bytesLeft = nBytes;
73  while ( bytesLeft ) {
74  comBuf * pComBuf = this->bufs.first ();
75  if ( ! pComBuf ) {
76  this->nBytesPending -= totalBytes;
77  return totalBytes;
78  }
79  unsigned nBytesThisTime = pComBuf->removeBytes ( bytesLeft );
80  if ( pComBuf->occupiedBytes () == 0u ) {
81  this->bufs.remove ( *pComBuf );
82  pComBuf->~comBuf ();
83  this->comBufMemMgr.release ( pComBuf );
84  }
85  if ( nBytesThisTime == 0u) {
86  break;
87  }
88  totalBytes += nBytesThisTime;
89  bytesLeft = nBytes - totalBytes;
90  }
91  this->nBytesPending -= totalBytes;
92  return totalBytes;
93 }
94 
96 {
97  for ( unsigned i = 0u; i < sizeof ( *pStr ); i++ ) {
98  pStr[0][i] = this->popInt8 ();
99  }
100 }
101 
103 
104 {
105  bufIn.commitIncomming ();
106  comBuf * pComBuf = this->bufs.last ();
107  if ( pComBuf ) {
108  if ( pComBuf->unoccupiedBytes() ) {
109  this->nBytesPending += pComBuf->push ( bufIn );
110  pComBuf->commitIncomming ();
111  }
112  }
113  unsigned bufBytes = bufIn.occupiedBytes();
114  if ( bufBytes ) {
115  this->nBytesPending += bufBytes;
116  this->bufs.add ( bufIn );
117  }
118  else {
119  bufIn.~comBuf ();
120  this->comBufMemMgr.release ( & bufIn );
121  }
122 }
123 
124 // 1) split between buffers expected to run slower
125 // 2) using canonical unsigned tmp avoids ANSI C conversions to int
126 // 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32)
127 epicsUInt16 comQueRecv::multiBufferPopUInt16 ()
128 {
129  epicsUInt16 tmp;
130  if ( this->occupiedBytes() >= sizeof (tmp) ) {
131  unsigned byte1 = this->popUInt8 ();
132  unsigned byte2 = this->popUInt8 ();
133  tmp = static_cast <epicsUInt16> ( ( byte1 << 8u ) | byte2 );
134  }
135  else {
137  tmp = 0u;
138  }
139  return tmp;
140 }
141 
142 // 1) split between buffers expected to run slower
143 // 2) using canonical unsigned temporary avoids ANSI C conversions to int
144 // 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32)
145 epicsUInt32 comQueRecv::multiBufferPopUInt32 ()
146 {
147  epicsUInt32 tmp;
148  if ( this->occupiedBytes() >= sizeof (tmp) ) {
149  // 1) split between buffers expected to run slower
150  // 2) using canonical unsigned temporary avoids ANSI C conversions to int
151  // 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32)
152  unsigned byte1 = this->popUInt8();
153  unsigned byte2 = this->popUInt8();
154  unsigned byte3 = this->popUInt8();
155  unsigned byte4 = this->popUInt8();
156  tmp = static_cast <epicsUInt32>
157  ( ( byte1 << 24u ) | ( byte2 << 16u ) |
158  ( byte3 << 8u ) | byte4 );
159  }
160  else {
162  tmp = 0u; // avoid compiler warnings
163  }
164  return tmp;
165 }
166 
167 void comQueRecv::removeAndDestroyBuf ( comBuf & buf )
168 {
169  this->bufs.remove ( buf );
170  buf.~comBuf ();
171  this->comBufMemMgr.release ( & buf );
172 }
173 
175 {
176  comBuf * pComBuf = this->bufs.first ();
177  if ( ! pComBuf ) {
179  }
180  epicsUInt8 tmp = '\0';
181  comBuf::popStatus status = pComBuf->pop ( tmp );
182  if ( ! status.success ) {
184  }
185  if ( status.nowEmpty ) {
186  this->removeAndDestroyBuf ( *pComBuf );
187  }
188  this->nBytesPending--;
189  return tmp;
190 }
191 
193 {
194  comBuf * pComBuf = this->bufs.first ();
195  if ( ! pComBuf ) {
197  }
198  // try first for all in one buffer efficent version
199  epicsUInt16 tmp = 0;
200  comBuf::popStatus status = pComBuf->pop ( tmp );
201  if ( status.success ) {
202  this->nBytesPending -= sizeof ( epicsUInt16 );
203  if ( status.nowEmpty ) {
204  this->removeAndDestroyBuf ( *pComBuf );
205  }
206  return tmp;
207  }
208  return this->multiBufferPopUInt16 ();
209 }
210 
212 {
213  comBuf *pComBuf = this->bufs.first ();
214  if ( ! pComBuf ) {
216  }
217  // try first for all in one buffer efficent version
218  epicsUInt32 tmp = 0;
219  comBuf::popStatus status = pComBuf->pop ( tmp );
220  if ( status.success ) {
221  this->nBytesPending -= sizeof ( epicsUInt32 );
222  if ( status.nowEmpty ) {
223  this->removeAndDestroyBuf ( *pComBuf );
224  }
225  return tmp;
226  }
227  return this->multiBufferPopUInt32 ();
228 }
229 
231 {
232  // try first for all in one buffer efficent version
233  comBuf * pComBuf = this->bufs.first ();
234  if ( ! pComBuf ) {
235  return false;
236  }
237  unsigned avail = pComBuf->occupiedBytes ();
238  if ( avail >= sizeof ( caHdr ) ) {
239  pComBuf->pop ( msg.m_cmmd );
240  ca_uint16_t smallPostsize = 0;
241  pComBuf->pop ( smallPostsize );
242  msg.m_postsize = smallPostsize;
243  pComBuf->pop ( msg.m_dataType );
244  ca_uint16_t smallCount = 0;
245  pComBuf->pop ( smallCount );
246  msg.m_count = smallCount;
247  pComBuf->pop ( msg.m_cid );
248  pComBuf->pop ( msg.m_available );
249  this->nBytesPending -= sizeof ( caHdr );
250  if ( avail == sizeof ( caHdr ) ) {
251  this->removeAndDestroyBuf ( *pComBuf );
252  }
253  return true;
254  }
255  else if ( this->occupiedBytes () >= sizeof ( caHdr ) ) {
256  msg.m_cmmd = this->popUInt16 ();
257  msg.m_postsize = this->popUInt16 ();
258  msg.m_dataType = this->popUInt16 ();
259  msg.m_count = this->popUInt16 ();
260  msg.m_cid = this->popUInt32 ();
261  msg.m_available = this->popUInt32 ();
262  return true;
263  }
264  else {
265  return false;
266  }
267 }
268 
unsigned push(comBuf &)
Definition: comBuf.h:162
epicsUInt8 popUInt8()
Definition: comQueRecv.cpp:174
void clear()
Definition: comQueRecv.cpp:38
void commitIncomming()
Definition: comBuf.h:242
void add(T &item)
Definition: tsDLList.h:313
char epicsOldString[MAX_STRING_SIZE]
Definition: epicsTypes.h:66
pvd::Status status
int i
Definition: scan.c:967
ca_uint32_t m_postsize
unsigned short epicsUInt16
Definition: epicsTypes.h:41
bool popOldMsgHeader(struct caHdrLargeArray &)
Definition: comQueRecv.cpp:230
unsigned char epicsUInt8
Definition: epicsTypes.h:39
ca_uint16_t m_dataType
epicsInt8 popInt8()
Definition: comQueRecv.h:65
unsigned int epicsUInt32
Definition: epicsTypes.h:43
unsigned short ca_uint16_t
Definition: caProto.h:75
epicsUInt16 popUInt16()
Definition: comQueRecv.cpp:192
comQueRecv(comBufMemoryManager &)
Definition: comQueRecv.cpp:28
T * last(void) const
Definition: tsDLList.h:199
ca_uint32_t m_count
unsigned removeBytes(unsigned nBytes)
Definition: comQueRecv.cpp:69
unsigned occupiedBytes() const
Definition: comBuf.h:152
unsigned occupiedBytes() const
Definition: comQueRecv.h:60
unsigned copyOutBytes(void *pBuf, unsigned nBytes)
Definition: comBuf.h:288
char epicsInt8
Definition: epicsTypes.h:38
unsigned removeBytes(unsigned nBytes)
Definition: comBuf.h:300
static void throwInsufficentBytesException()
Definition: comBuf.cpp:49
void popString(epicsOldString *)
Definition: comQueRecv.cpp:95
struct ca_hdr caHdr
ca_uint32_t m_cid
T * get()
Definition: tsDLList.h:261
popStatus pop(T &)
Definition: comBuf.h:312
Definition: comBuf.h:75
unsigned copyOutBytes(epicsInt8 *pBuf, unsigned nBytes)
Definition: comQueRecv.cpp:48
unsigned unoccupiedBytes() const
Definition: comBuf.h:147
ca_uint16_t m_cmmd
void remove(T &item)
Definition: tsDLList.h:219
ca_uint32_t m_available
void pushLastComBufReceived(comBuf &)
Definition: comQueRecv.cpp:102
epicsUInt32 popUInt32()
Definition: comQueRecv.cpp:211
T * first(void) const
Definition: tsDLList.h:190
virtual void release(void *)=0