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