13 #include <sys/types.h>
\r
21 static const bool UseDebug = false;
\r
22 static const bool UseCR = false;
\r
24 static const int StringSize = 4096;
\r
26 static const char LF = '\n';
\r
27 static const char CR = '\r';
\r
31 static int my_read (int fd, char string[], int size);
\r
32 static void my_write (int fd, const char string[], int size);
\r
38 bool io_is_ok(const io_t * io) {
\r
40 if (io == NULL) return false;
\r
42 if (io->name == NULL) return false;
\r
44 if (io->in_eof != true && io->in_eof != false) return false;
\r
46 if (io->in_size < 0 || io->in_size > BufferSize) return false;
\r
47 if (io->out_size < 0 || io->out_size > BufferSize) return false;
\r
54 void io_init(io_t * io) {
\r
63 ASSERT(io_is_ok(io));
\r
68 void io_close(io_t * io) {
\r
70 ASSERT(io_is_ok(io));
\r
72 ASSERT(io->out_fd>=0);
\r
74 my_log("> %s EOF\n",io->name);
\r
76 if (close(io->out_fd) == -1) {
\r
77 my_fatal("io_close(): close(): %s\n",strerror(errno));
\r
85 void io_get_update(io_t * io) {
\r
90 ASSERT(io_is_ok(io));
\r
92 ASSERT(io->in_fd>=0);
\r
93 ASSERT(!io->in_eof);
\r
99 size = BufferSize - pos;
\r
100 if (size <= 0) my_fatal("io_get_update(): buffer overflow\n");
\r
102 // read as many data as possible
\r
104 n = my_read(io->in_fd,&io->in_buffer[pos],size);
\r
105 if (UseDebug) my_log("POLYGLOT read %d byte%s from %s\n",n,(n>1)?"s":"",io->name);
\r
107 if (n > 0) { // at least one character was read
\r
109 // update buffer size
\r
111 ASSERT(n>=1&&n<=size);
\r
114 ASSERT(io->in_size>=0&&io->in_size<=BufferSize);
\r
126 bool io_line_ready(const io_t * io) {
\r
128 ASSERT(io_is_ok(io));
\r
130 if (io->in_eof) return true;
\r
132 if (memchr(io->in_buffer,LF,io->in_size) != NULL) return true; // buffer contains LF
\r
139 bool io_get_line(io_t * io, char string[], int size) {
\r
144 ASSERT(io_is_ok(io));
\r
145 ASSERT(string!=NULL);
\r
153 // test for end of buffer
\r
155 if (src >= io->in_size) {
\r
157 my_log("%s->Adapter: EOF\n",io->name);
\r
160 my_fatal("io_get_line(): no EOL in buffer\n");
\r
164 // test for end of string
\r
166 if (dst >= size) my_fatal("io_get_line(): buffer overflow\n");
\r
168 // copy the next character
\r
170 c = io->in_buffer[src++];
\r
172 if (c == LF) { // LF => line complete
\r
173 string[dst] = '\0';
\r
175 } else if (c != CR) { // skip CRs
\r
180 // shift the buffer
\r
184 io->in_size -= src;
\r
185 ASSERT(io->in_size>=0);
\r
187 if (io->in_size > 0) memmove(&io->in_buffer[0],&io->in_buffer[src],io->in_size);
\r
191 my_log("%s->Adapter: %s\n",io->name,string);
\r
198 void io_send(io_t * io, const char format[], ...) {
\r
201 char string[StringSize];
\r
204 ASSERT(io_is_ok(io));
\r
205 ASSERT(format!=NULL);
\r
207 ASSERT(io->out_fd>=0);
\r
211 va_start(arg_list,format);
\r
212 vsprintf(string,format,arg_list);
\r
215 // append string to buffer
\r
217 len = strlen(string);
\r
218 if (io->out_size + len > BufferSize-2) my_fatal("io_send(): buffer overflow\n");
\r
220 memcpy(&io->out_buffer[io->out_size],string,len);
\r
221 io->out_size += len;
\r
223 ASSERT(io->out_size>=0&&io->out_size<=BufferSize-2);
\r
227 io->out_buffer[io->out_size] = '\0';
\r
228 my_log("Adapter->%s: %s\n",io->name,io->out_buffer);
\r
229 // my_log("> %f %s %s\n",now_real(),io->name,io->out_buffer);
\r
230 // append EOL to buffer
\r
232 if (UseCR) io->out_buffer[io->out_size++] = CR;
\r
233 io->out_buffer[io->out_size++] = LF;
\r
235 ASSERT(io->out_size>=0&&io->out_size<=BufferSize);
\r
239 if (UseDebug) my_log("POLYGLOT writing %d byte%s to %s\n",io->out_size,(io->out_size>1)?"s":"",io->name);
\r
240 my_write(io->out_fd,io->out_buffer,io->out_size);
\r
247 void io_send_queue(io_t * io, const char format[], ...) {
\r
250 char string[StringSize];
\r
253 ASSERT(io_is_ok(io));
\r
254 ASSERT(format!=NULL);
\r
256 ASSERT(io->out_fd>=0);
\r
260 va_start(arg_list,format);
\r
261 vsprintf(string,format,arg_list);
\r
264 // append string to buffer
\r
266 len = strlen(string);
\r
267 if (io->out_size + len > BufferSize-2) my_fatal("io_send_queue(): buffer overflow\n");
\r
269 memcpy(&io->out_buffer[io->out_size],string,len);
\r
270 io->out_size += len;
\r
272 ASSERT(io->out_size>=0&&io->out_size<=BufferSize-2);
\r
277 static int my_read(int fd, char string[], int size) {
\r
282 ASSERT(string!=NULL);
\r
286 n = read(fd,string,size);
\r
287 } while (n == -1 && errno == EINTR);
\r
289 if (n == -1) my_fatal("my_read(): read(): %s\n",strerror(errno));
\r
298 static void my_write(int fd, const char string[], int size) {
\r
303 ASSERT(string!=NULL);
\r
308 n = write(fd,string,size);
\r
310 // if (n == -1 && errno != EINTR && errno != EPIPE) my_fatal("my_write(): write(): %s\n",strerror(errno));
\r
314 } else if (errno == EINTR) {
\r
315 n = 0; // nothing has been written
\r
316 } else if (errno == EPIPE) {
\r
317 n = size; // pretend everything has been written
\r
319 my_fatal("my_write(): write(): %s\n",strerror(errno));
\r
328 } while (size > 0);
\r