substdio(3) substdio(3) NNAAMMEE substdio - the Sub-Standard Input/Output Library SSYYNNTTAAXX ##iinncclluuddee <> void ssuubbssttddiioo__ffddbbuuff(&_s,_o_p,_f_d,_b_u_f,_l_e_n); int ssuubbssttddiioo__ffiilleennoo(&_s); substdio _s; int (*_o_p)(); int _f_d; char *_b_u_f; int _l_e_n; DDEESSCCRRIIPPTTIIOONN ssuubbssttddiioo is the Sub-Standard I/O Library. ssuubbssttddiioo con- tains only a few of the features of stdio; it is a fast, lightweight, low-level library, suitable for use as a com- ponent of higher-level I/O libraries. The point of ssuubbssttddiioo is to provide buffered I/O. The basic object in ssuubbssttddiioo is the ssuubbssttddiioo structure; a ssuubb-- ssttddiioo variable stores an operation, a descriptor, and a pointer into a buffer of some nonzero length. The ssuubbsstt-- ddiioo operations read data from the buffer, filling the buffer as necessary using the operation on the descriptor, or write data to the buffer, flushing the buffer as neces- sary using the operation on the descriptor. Input and output operations cannot be mixed. ssuubbssttddiioo__ffddbbuuff initializes a ssuubbssttddiioo variable. The oper- ation is _o_p. The descriptor is _f_d. The buffer is _b_u_f, an array of _l_e_n chars. _o_p will be called as _o_p(_f_d,_x,_n). Here _x is a pointer to an array of characters of length _n; _o_p must read some characters from _f_d to that array, or write some characters to _f_d from that array. The return value from _o_p must be the number of characters read or written. 0 characters read means end of input; 0 characters written means that the write operation should be tried again immediately. On error, _o_p must return -1, setting eerrrrnnoo appropriately, without reading or writing anything. Most errors are returned directly to the ssuubbssttddiioo caller, but an error of eerrrroorr__iinnttrr means that the operation should be tried again immediately. There is a SSUUBBSSTTDDIIOO__FFDDBBUUFF macro that can be used to stati- cally initialize a ssuubbssttddiioo variable: substdio s = SUBSTDIO_FDBUF(op,fd,buf,len); 1 substdio(3) substdio(3) ssuubbssttddiioo__ffiilleennoo returns the descriptor for an initialized ssuubbssttddiioo variable. SSEEEE AALLSSOO substdio_in(3), substdio_out(3), substdio_copy(3), error(3) 2 substdio_in(3) substdio_in(3) NNAAMMEE substdio_in - substdio input routines SSYYNNTTAAXX ##iinncclluuddee <> int ssuubbssttddiioo__ggeett(&_s,_t_o,_l_e_n); int ssuubbssttddiioo__bbggeett(&_s,_t_o,_l_e_n); int ssuubbssttddiioo__ffeeeedd(&_s); char *ssuubbssttddiioo__ppeeeekk(&_s); void ssuubbssttddiioo__sseeeekk(&_s,_l_e_n); substdio _s; char *_t_o; int _l_e_n; DDEESSCCRRIIPPTTIIOONN ssuubbssttddiioo__ggeett reads at most _l_e_n characters from _s into the character array _t_o. It returns the number of characters read, 0 for end of file, or -1 for error, setting eerrrrnnoo appropriately. ssuubbssttddiioo__bbggeett has the same function as ssuubbssttddiioo__ggeett. The difference is what happens when there is no buffered data and _l_e_n exceeds the buffer size: ssuubbssttddiioo__ggeett tries to read _l_e_n characters, whereas ssuubbssttddiioo__bbggeett tries to read one buffer of characters. In some cases ssuubbssttddiioo__bbggeett will be more efficient than ssuubbssttddiioo__ggeett. ssuubbssttddiioo__ffeeeedd makes sure that there is buffered data, so that the next ssuubbssttddiioo__ggeett or ssuubbssttddiioo__bbggeett will succeed. If the buffer is empty, ssuubbssttddiioo__ffeeeedd tries to fill it; it returns 0 for end of file, -1 for error, or the number of buffered characters on success. If the buffer already had data, ssuubbssttddiioo__ffeeeedd leaves it alone and returns the number of buffered characters. ssuubbssttddiioo__ppeeeekk returns a pointer to the buffered data. ssuubbssttddiioo__sseeeekk throws away _l_e_n buffered characters, as if they had been read. _l_e_n must be at least 0 and at most the amount of buffered data. The ssuubbssttddiioo__PPEEEEKK and ssuubbssttddiioo__SSEEEEKK macros behave the same way as ssuubbssttddiioo__ppeeeekk and ssuubbssttddiioo__sseeeekk but may evaluate their arguments several times. The point of ssuubbssttddiioo__ppeeeekk and ssuubbssttddiioo__sseeeekk is to read data without unnecessary copies. Sample code: 1 substdio_in(3) substdio_in(3) for (;;) { n = substdio_feed(s); if (n <= 0) return n; x = substdio_PEEK(s); handle(x,n); substdio_SEEK(s,n); } The SSUUBBSSTTDDIIOO__IINNSSIIZZEE macro is defined as a reasonably large input buffer size for ssuubbssttddiioo__ffddbbuuff. IINNTTEERRNNAALLSS When a ssuubbssttddiioo variable _s is used for input, there is free buffer space from _s..xx to _s..xx + _s..nn; data is buffered from _s..xx + _s..nn to _s..xx + _s..nn + _s..pp; the total buffer length is _s..nn + _s..pp. SSEEEE AALLSSOO substdio(3) 2 substdio_out(3) substdio_out(3) NNAAMMEE substdio_out - substdio output routines SSYYNNTTAAXX ##iinncclluuddee <> int ssuubbssttddiioo__ppuutt(&_s,_f_r_o_m,_l_e_n); int ssuubbssttddiioo__ppuuttss(&_s,_f_r_o_m); int ssuubbssttddiioo__bbppuutt(&_s,_f_r_o_m,_l_e_n); int ssuubbssttddiioo__bbppuuttss(&_s,_f_r_o_m); int ssuubbssttddiioo__fflluusshh(&_s); int ssuubbssttddiioo__ppuuttfflluusshh(&_s,_f_r_o_m,_l_e_n); int ssuubbssttddiioo__ppuuttssfflluusshh(&_s,_f_r_o_m); substdio _s; char *_f_r_o_m; int _l_e_n; DDEESSCCRRIIPPTTIIOONN ssuubbssttddiioo__ppuutt writes _l_e_n characters to _s out of the charac- ter array _f_r_o_m. It returns 0 on success, -1 on error. ssuubbssttddiioo__bbppuutt has the same function as ssuubbssttddiioo__ppuutt. The difference is how the buffer is flushed when there isn't enough room for _l_e_n characters: ssuubbssttddiioo__ppuutt flushes the buffered data before copying the new data, whereas ssuubbsstt-- ddiioo__bbppuutt fills the buffer with new data before flushing. ssuubbssttddiioo__fflluusshh forces all data to be written from the internal buffer. It returns 0 on success, -1 on error. ssuubbssttddiioo__ppuuttfflluusshh is similar to ssuubbssttddiioo__ppuutt followed by ssuubbssttddiioo__fflluusshh, but it avoids all internal copies. ssuubbssttddiioo__ppuuttss, ssuubbssttddiioo__bbppuuttss, and ssuubbssttddiioo__ppuuttssfflluusshh are the same as ssuubbssttddiioo__ppuutt, ssuubbssttddiioo__bbppuutt, and ssuubbssttddiioo__ppuutt-- fflluusshh except that _f_r_o_m must be a 0-terminated string of characters. The string, not including the 0, is written. The SSUUBBSSTTDDIIOO__OOUUTTSSIIZZEE macro is defined as a reasonably large output buffer size for ssuubbssttddiioo__ffddbbuuff. IINNTTEERRNNAALLSS When a ssuubbssttddiioo variable _s is used for output, data is buffered from _s..xx to _s..xx + _s..pp; there is free buffer space from to _s..xx + _s..pp to _s..xx + _s..nn; the total buffer length is _s..nn. SSEEEE AALLSSOO substdio(3) 1 substdio_copy(3) substdio_copy(3) NNAAMMEE substdio_copy - copy an entire input to an output SSYYNNTTAAXX ##iinncclluuddee <> int ssuubbssttddiioo__ccooppyy(&_s_o_u_t,&_s_i_n); substdio _s_o_u_t; substdio _s_i_n; DDEESSCCRRIIPPTTIIOONN ssuubbssttddiioo__ccooppyy reads characters from _s_i_n until end of file, writing each character to _s_o_u_t. It then returns 0. It does not flush _s_o_u_t. Upon a _s_i_n error, ssuubbssttddiioo__ccooppyy returns -2, leaving eerrrrnnoo set appropriately. Upon a _s_o_u_t error, ssuubbssttddiioo__ccooppyy returns -3, leaving eerrrrnnoo set appropriately. SSEEEE AALLSSOO substdio(3) 1