ngc 1.5.0
 
Loading...
Searching...
No Matches
ngcbSTREAM.hpp
Go to the documentation of this file.
1
8#ifndef ngcbSTREAM_H
9#define ngcbSTREAM_H
10
11
12#ifndef __cplusplus
13#error This is a C++ include file and cannot be used from plain C
14#endif
15
16/*
17 * System Headers
18 */
19
20/*
21 * Local Headers
22 */
24
28struct ngcb_fb_t {
30 FILE *chan;
31
34
36 ngcb_fb_t() {chan = NULL; automatic = 0;}
37};
38
43{
44public:
46 explicit ngcbSTREAM(FILE *fd) {
47 /*
48 * Initialize data members
49 */
50 Init_(fd);
51
52 /*
53 * Create streaming process
54 */
55 stream_ = NewThread(this, (ngcbPROCESS_T)&ngcbSTREAM::Process_, NULL);
56 if (stream_ == NULL)
57 {
58 sprintf(ErrMsg(), "unable to start streaming thread");
59 return;
60 }
61 else if (!stream_->Initialized())
62 {
63 delete stream_;
64 stream_ = NULL;
65 sprintf(ErrMsg(), "unable to initialize streaming thread");
66 return;
67 }
68
69 /*
70 * Initialized
71 */
72 initialized_ = 1;
73 }
74
76 ngcbSTREAM(FILE *fd, ssize_t bufferSize) {
77 /*
78 * Initialize data members
79 */
80 Init_(fd);
81
82 if (bufferSize <= 0)
83 {
84 if (bufferSize == 0)
85 {
86 /*
87 * Disable streaming buffer
88 */
89 setbuf(fd, NULL);
90 }
91 }
92 else
93 {
94 /*
95 * Allocate buffer
96 */
97 buffer_ = (char *)malloc(bufferSize);
98 if (buffer_ == NULL)
99 {
100 bufferSize_ = 0;
101 sprintf(ErrMsg(), "unable to allocate streaming buffer");
102 return;
103 }
104 bufferSize_ = bufferSize;
105
106 /*
107 * Create streaming process
108 */
109 stream_ = NewThread(this, (ngcbPROCESS_T)&ngcbSTREAM::Process_, NULL);
110 if (stream_ == NULL)
111 {
112 free(buffer_);
113 buffer_ = NULL;
114 bufferSize_ = 0;
115 sprintf(ErrMsg(), "unable to start streaming thread");
116 return;
117 }
118 else if (!stream_->Initialized())
119 {
120 delete stream_;
121 stream_ = NULL;
122 free(buffer_);
123 buffer_ = NULL;
124 bufferSize_ = 0;
125 sprintf(ErrMsg(), "unable to initialize streaming thread");
126 return;
127 }
128 }
129
130 /*
131 * Initialized
132 */
133 initialized_ = 1;
134 }
135
137 virtual ~ngcbSTREAM() {
138 /*
139 * Wait for transfer
140 */
141 if (transfer_ && (semAck_ != NULL)) semAck_->Wait();
142
143 /*
144 * Enforce streaming process termination
145 */
146 if (semSig_ != NULL) semSig_->Post();
147
148 /*
149 * Free resources
150 */
151 if (stream_ != NULL) delete stream_;
152 if (semSig_ != NULL) delete semSig_;
153 if (semAck_ != NULL) delete semAck_;
154 if (buffer_ != NULL) free(buffer_);
155 }
156
158 size_t Write(const char *buffer, size_t size) {
159 size_t tx;
160 size_t b2w = size;
161 size_t offset = 0;
162
163 if (bufferSize_ == 0)
164 {
165 /*
166 * System write
167 */
168 if (fwrite(buffer, 1, size, fd_) != size)
169 {
170 strcpy(ErrMsg(), strerror(errno));
171 return (0);
172 }
173
174 return (size);
175 }
176
177 if (stream_ == NULL)
178 {
179 strcpy(ErrMsg(), "invalid stream");
180 return (0);
181 }
182
183 while (b2w > 0)
184 {
185 if (b2w <= bufferSize_) tx = b2w;
186 else tx = bufferSize_;
187
188 /*
189 * Wait until stream is free
190 */
191 semAck_->Wait();
192 transfer_ = 0;
193
194 /*
195 * Check if an error has occurred
196 */
197 if (error_)
198 {
199 /*
200 * Delete the stream
201 */
202 delete stream_; stream_ = NULL;
203 return (0);
204 }
205
206 /*
207 * Copy next chunk to streaming buffer
208 */
209 memcpy(buffer_, buffer + offset, tx);
210
211 /*
212 * Initiate transfer
213 */
214 size_ = tx;
215 source_ = (const char *)buffer_;
216 transfer_ = 1;
217 semSig_->Post();
218
219 b2w -= tx;
220 offset += tx;
221 }
222
223 return (size);
224 }
225
227 int Send(const char *buffer, size_t size) {
228
229 if (stream_ == NULL)
230 {
231 strcpy(ErrMsg(), "invalid stream");
232 return (-1);
233 }
234
235 /*
236 * Wait until stream is free
237 */
238 semAck_->Wait();
239 transfer_ = 0;
240
241 /*
242 * Check if an error has occurred
243 */
244 if (error_)
245 {
246 /*
247 * Delete the stream
248 */
249 delete stream_; stream_ = NULL;
250 return (-1);
251 }
252
253 /*
254 * Pass the buffer address to streaming process
255 */
256 source_ = buffer;
257
258 /*
259 * Initiate transfer
260 */
261 size_ = size;
262 transfer_ = 1;
263 semSig_->Post();
264
265 return (0);
266 }
267
269 char *ErrMsg() {return (erms_);}
270
272 int Initialized() {return (initialized_);}
273
274protected:
275
276private:
278 char erms_[256];
279
281 int error_;
282
284 int initialized_;
285
287 int transfer_;
288
290 ngcbTHREAD *stream_;
291
293 ngcbSEM *semSig_;
294
296 ngcbSEM *semAck_;
297
299 char *buffer_;
300
302 const char *source_;
303
305 size_t bufferSize_;
306
308 size_t size_;
309
311 FILE *fd_;
312
314 void Init_(FILE *fd) {
315 initialized_ = 0;
316 error_ = 0;
317 transfer_ = 0;
318 erms_[0] = '\0';
319 fd_ = fd;
320 stream_ = NULL;
321 buffer_ = NULL;
322 source_ = NULL;
323 bufferSize_ = 0;
324 size_ = 0;
325 semSig_ = new ngcbSEM(0);
326 semAck_ = new ngcbSEM(0);
327 }
328
330 void Process_(ngcbTHREAD *thr, void *arg) {
331
332 /*
333 * Process initialized
334 */
335 semAck_->Post();
336
337 while (!error_)
338 {
339 /*
340 * Wait for next transfer signal
341 */
342 semSig_->Wait();
343
344 if (size_ == 0)
345 {
346 /*
347 * Terminate
348 */
349 semAck_->Post();
350 break;
351 }
352
353 if (source_ != NULL)
354 {
355 /*
356 * Write buffer to stream
357 */
358 if (fwrite(source_, 1, size_, fd_) != size_)
359 {
360 strcpy(ErrMsg(), strerror(errno));
361 error_ = 1;
362 }
363 }
364 else
365 {
366 strcpy(ErrMsg(), "invalid buffer source (NULL)");
367 error_ = 1;
368 }
369
370 /*
371 * Acknowledge transfer
372 */
373 semAck_->Post();
374 }
375
376 ThrExit();
377 }
378
379};
380
381#endif
Definition ngcbTHREAD.hpp:68
int Initialized()
Check class initialization.
Definition ngcbSTREAM.hpp:272
size_t Write(const char *buffer, size_t size)
Write size bytes of buffer to the stream.
Definition ngcbSTREAM.hpp:158
ngcbSTREAM(FILE *fd, ssize_t bufferSize)
Constructor defining a streaming buffer size.
Definition ngcbSTREAM.hpp:76
char * ErrMsg()
Return error message.
Definition ngcbSTREAM.hpp:269
ngcbSTREAM(FILE *fd)
Constructor for parallel stram.
Definition ngcbSTREAM.hpp:46
virtual ~ngcbSTREAM()
Destructor.
Definition ngcbSTREAM.hpp:137
int Send(const char *buffer, size_t size)
Send size bytes of buffer to the stream.
Definition ngcbSTREAM.hpp:227
Definition ngcbTHREAD.hpp:186
ngcbTHREAD()
Normal constructor.
Definition ngcbTHREAD.cpp:53
void ThrExit()
Thread exit.
Definition ngcbTHREAD.cpp:213
virtual ngcbTHREAD * NewThread(ngcbTHREAD *app, ngcbPROCESS_T process, void *arg, size_t stack=0)
Process to be overloaded.
Definition ngcbTHREAD.cpp:169
void(ngcbTHREAD::* ngcbPROCESS_T)(ngcbTHREAD *thread, void *arg)
Definition ngcbTHREAD.hpp:181
ngcb_fb_t()
Constructor.
Definition ngcbSTREAM.hpp:36
int automatic
Automatic open/close.
Definition ngcbSTREAM.hpp:33
FILE * chan
Stream channel.
Definition ngcbSTREAM.hpp:30