This is Unofficial EPICS BASE Doxygen Site
comBuf.h
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 #ifndef INC_comBuf_H
24 #define INC_comBuf_H
25 
26 #include <new>
27 #include <cstring>
28 
29 #include "epicsAssert.h"
30 #include "epicsTypes.h"
31 #include "tsFreeList.h"
32 #include "tsDLList.h"
33 #include "osiWireFormat.h"
34 #include "compilerDependencies.h"
35 
36 static const unsigned comBufSize = 0x4000;
37 
38 // this wrapper avoids Tornado 2.0.1 compiler bugs
40 public:
41  virtual ~comBufMemoryManager ();
42  virtual void * allocate ( size_t ) = 0;
43  virtual void release ( void * ) = 0;
44 };
45 
47 public:
48  virtual unsigned sendBytes ( const void * pBuf,
49  unsigned nBytesInBuf,
50  const class epicsTime & currentTime ) = 0;
51 protected:
52  virtual ~wireSendAdapter() {}
53 };
54 
61 };
62 struct statusWireIO {
63  unsigned bytesCopied;
65 };
66 
68 public:
69  virtual void recvBytes ( void * pBuf,
70  unsigned nBytesInBuf, statusWireIO & ) = 0;
71 protected:
72  virtual ~wireRecvAdapter() {}
73 };
74 
75 class comBuf : public tsDLNode < comBuf > {
76 public:
78  comBuf ();
79  unsigned unoccupiedBytes () const;
80  unsigned occupiedBytes () const;
81  unsigned uncommittedBytes () const;
82  static unsigned capacityBytes ();
83  void clear ();
84  unsigned copyInBytes ( const void *pBuf, unsigned nBytes );
85  unsigned push ( comBuf & );
86  template < class T >
87  bool push ( const T & value );
88  template < class T >
89  unsigned push ( const T * pValue, unsigned nElem );
90  unsigned push ( const epicsInt8 * pValue, unsigned nElem );
91  unsigned push ( const epicsUInt8 * pValue, unsigned nElem );
92  unsigned push ( const epicsOldString * pValue, unsigned nElem );
93  void commitIncomming ();
94  void clearUncommittedIncomming ();
95  bool copyInAllBytes ( const void *pBuf, unsigned nBytes );
96  unsigned copyOutBytes ( void *pBuf, unsigned nBytes );
97  bool copyOutAllBytes ( void *pBuf, unsigned nBytes );
98  unsigned removeBytes ( unsigned nBytes );
99  bool flushToWire ( wireSendAdapter &, const epicsTime & currentTime );
100  void fillFromWire ( wireRecvAdapter &, statusWireIO & );
101  struct popStatus {
102  bool success;
103  bool nowEmpty;
104  };
105  template < class T >
106  popStatus pop ( T & );
107  static void throwInsufficentBytesException ();
108  void * operator new ( size_t size,
110  epicsPlacementDeleteOperator (( void *, comBufMemoryManager & ))
111 private:
112  unsigned commitIndex;
113  unsigned nextWriteIndex;
114  unsigned nextReadIndex;
115  epicsUInt8 buf [ comBufSize ];
116  void operator delete ( void * );
117  template < class T >
118  bool push ( const T * ); // disabled
119 };
120 
121 inline void * comBuf::operator new ( size_t size,
122  comBufMemoryManager & mgr )
123 {
124  return mgr.allocate ( size );
125 }
126 
127 #ifdef CXX_PLACEMENT_DELETE
128 inline void comBuf::operator delete ( void * pCadaver,
129  comBufMemoryManager & mgr )
130 {
131  mgr.release ( pCadaver );
132 }
133 #endif
134 
135 inline comBuf::comBuf () : commitIndex ( 0u ),
136  nextWriteIndex ( 0u ), nextReadIndex ( 0u )
137 {
138 }
139 
140 inline void comBuf :: clear ()
141 {
142  this->commitIndex = 0u;
143  this->nextWriteIndex = 0u;
144  this->nextReadIndex = 0u;
145 }
146 
147 inline unsigned comBuf :: unoccupiedBytes () const
148 {
149  return sizeof ( this->buf ) - this->nextWriteIndex;
150 }
151 
152 inline unsigned comBuf :: occupiedBytes () const
153 {
154  return this->commitIndex - this->nextReadIndex;
155 }
156 
157 inline unsigned comBuf :: uncommittedBytes () const
158 {
159  return this->nextWriteIndex - this->commitIndex;
160 }
161 
162 inline unsigned comBuf :: push ( comBuf & bufIn )
163 {
164  unsigned nBytes = this->copyInBytes (
165  & bufIn.buf[ bufIn.nextReadIndex ],
166  bufIn.commitIndex - bufIn.nextReadIndex );
167  bufIn.nextReadIndex += nBytes;
168  return nBytes;
169 }
170 
171 inline unsigned comBuf :: capacityBytes ()
172 {
173  return comBufSize;
174 }
175 
177  wireRecvAdapter & wire, statusWireIO & stat )
178 {
179  wire.recvBytes (
180  & this->buf[this->nextWriteIndex],
181  sizeof ( this->buf ) - this->nextWriteIndex, stat );
182  if ( stat.circuitState == swioConnected ) {
183  this->nextWriteIndex += stat.bytesCopied;
184  }
185 }
186 
187 template < class T >
188 inline bool comBuf :: push ( const T & value )
189 {
190  unsigned index = this->nextWriteIndex;
191  unsigned available = sizeof ( this->buf ) - index;
192  if ( sizeof ( value ) > available ) {
193  return false;
194  }
195  WireSet ( value, & this->buf[index] );
196  this->nextWriteIndex = index + sizeof ( value );
197  return true;
198 }
199 
200 inline unsigned comBuf :: push ( const epicsInt8 *pValue, unsigned nElem )
201 {
202  return copyInBytes ( pValue, nElem );
203 }
204 
205 inline unsigned comBuf :: push ( const epicsUInt8 *pValue, unsigned nElem )
206 {
207  return copyInBytes ( pValue, nElem );
208 }
209 
210 inline unsigned comBuf :: push ( const epicsOldString * pValue, unsigned nElem )
211 {
212  unsigned index = this->nextWriteIndex;
213  unsigned available = sizeof ( this->buf ) - index;
214  unsigned nBytes = sizeof ( *pValue ) * nElem;
215  if ( nBytes > available ) {
216  nElem = available / sizeof ( *pValue );
217  nBytes = nElem * sizeof ( *pValue );
218  }
219  memcpy ( &this->buf[ index ], pValue, nBytes );
220  this->nextWriteIndex = index + nBytes;
221  return nElem;
222 }
223 
224 template < class T >
225 unsigned comBuf :: push ( const T * pValue, unsigned nElem )
226 {
227  unsigned index = this->nextWriteIndex;
228  unsigned available = sizeof ( this->buf ) - index;
229  unsigned nBytes = sizeof ( *pValue ) * nElem;
230  if ( nBytes > available ) {
231  nElem = available / sizeof ( *pValue );
232  }
233  for ( unsigned i = 0u; i < nElem; i++ ) {
234  // allow native floating point formats to be converted to IEEE
235  WireSet( pValue[i], &this->buf[index] );
236  index += sizeof ( *pValue );
237  }
238  this->nextWriteIndex = index;
239  return nElem;
240 }
241 
243 {
244  this->commitIndex = this->nextWriteIndex;
245 }
246 
248 {
249  this->nextWriteIndex = this->commitIndex;
250 }
251 
252 inline bool comBuf :: copyInAllBytes ( const void *pBuf, unsigned nBytes )
253 {
254  unsigned index = this->nextWriteIndex;
255  unsigned available = sizeof ( this->buf ) - index;
256  if ( nBytes <= available ) {
257  memcpy ( & this->buf[index], pBuf, nBytes );
258  this->nextWriteIndex = index + nBytes;
259  return true;
260  }
261  return false;
262 }
263 
264 inline unsigned comBuf :: copyInBytes ( const void * pBuf, unsigned nBytes )
265 {
266  unsigned index = this->nextWriteIndex;
267  unsigned available = sizeof ( this->buf ) - index;
268  if ( nBytes > available ) {
269  nBytes = available;
270  }
271  memcpy ( & this->buf[index], pBuf, nBytes );
272  this->nextWriteIndex = index + nBytes;
273  return nBytes;
274 }
275 
276 inline bool comBuf :: copyOutAllBytes ( void * pBuf, unsigned nBytes )
277 {
278  unsigned index = this->nextReadIndex;
279  unsigned occupied = this->commitIndex - index;
280  if ( nBytes <= occupied ) {
281  memcpy ( pBuf, &this->buf[index], nBytes);
282  this->nextReadIndex = index + nBytes;
283  return true;
284  }
285  return false;
286 }
287 
288 inline unsigned comBuf :: copyOutBytes ( void *pBuf, unsigned nBytes )
289 {
290  unsigned index = this->nextReadIndex;
291  unsigned occupied = this->commitIndex - index;
292  if ( nBytes > occupied ) {
293  nBytes = occupied;
294  }
295  memcpy ( pBuf, &this->buf[index], nBytes);
296  this->nextReadIndex = index + nBytes;
297  return nBytes;
298 }
299 
300 inline unsigned comBuf :: removeBytes ( unsigned nBytes )
301 {
302  unsigned index = this->nextReadIndex;
303  unsigned occupied = this->commitIndex - index;
304  if ( nBytes > occupied ) {
305  nBytes = occupied;
306  }
307  this->nextReadIndex = index + nBytes;
308  return nBytes;
309 }
310 
311 template < class T >
313 {
314  unsigned nrIndex = this->nextReadIndex;
315  unsigned popIndex = nrIndex + sizeof ( returnVal );
316  unsigned cIndex = this->commitIndex;
318  status.success = true;
319  status.nowEmpty = false;
320  if ( popIndex >= cIndex ) {
321  if ( popIndex == cIndex ) {
322  status.nowEmpty = true;
323  }
324  else {
325  status.success = false;
326  return status;
327  }
328  }
329  WireGet ( & this->buf[ nrIndex ], returnVal );
330  this->nextReadIndex = popIndex;
331  return status;
332 }
333 
334 #endif // ifndef INC_comBuf_H
bool copyOutAllBytes(void *pBuf, unsigned nBytes)
Definition: comBuf.h:276
unsigned push(comBuf &)
Definition: comBuf.h:162
Definition: link.h:174
void commitIncomming()
Definition: comBuf.h:242
char epicsOldString[MAX_STRING_SIZE]
Definition: epicsTypes.h:66
pvd::Status status
virtual ~wireSendAdapter()
Definition: comBuf.h:52
An EPICS-specific replacement for ANSI C&#39;s assert.
int i
Definition: scan.c:967
unsigned copyInBytes(const void *pBuf, unsigned nBytes)
Definition: comBuf.h:264
bool copyInAllBytes(const void *pBuf, unsigned nBytes)
Definition: comBuf.h:252
void clear()
Definition: comBuf.h:140
void fillFromWire(wireRecvAdapter &, statusWireIO &)
Definition: comBuf.h:176
comBuf()
Definition: comBuf.h:135
unsigned uncommittedBytes() const
Definition: comBuf.h:157
unsigned char epicsUInt8
Definition: epicsTypes.h:39
swioCircuitState circuitState
Definition: comBuf.h:64
void clearUncommittedIncomming()
Definition: comBuf.h:247
unsigned bytesCopied
Definition: comBuf.h:63
epicsUInt8 buf[comBufSize]
Definition: comBuf.h:115
unsigned occupiedBytes() const
Definition: comBuf.h:152
unsigned copyOutBytes(void *pBuf, unsigned nBytes)
Definition: comBuf.h:288
char epicsInt8
Definition: epicsTypes.h:38
virtual ~wireRecvAdapter()
Definition: comBuf.h:72
unsigned removeBytes(unsigned nBytes)
Definition: comBuf.h:300
void WireGet(const epicsUInt8 *pWireSrc, epicsOldString &dst)
Definition: osdWireFormat.h:83
virtual void recvBytes(void *pBuf, unsigned nBytesInBuf, statusWireIO &)=0
virtual void * allocate(size_t)=0
popStatus pop(T &)
Definition: comBuf.h:312
Definition: comBuf.h:75
virtual ~comBufMemoryManager()
Definition: comBuf.cpp:65
unsigned unoccupiedBytes() const
Definition: comBuf.h:147
static unsigned capacityBytes()
Definition: comBuf.h:171
swioCircuitState
Definition: comBuf.h:55
Compiler specific declarations.
void WireSet(const epicsOldString &src, epicsUInt8 *pWireDst)
unsigned nextReadIndex
Definition: comBuf.h:114
epicsPlacementDeleteOperator((void *, comBufMemoryManager &)) private unsigne nextWriteIndex)
Definition: comBuf.h:110
virtual void release(void *)=0