ref: a411870ee4640241e3c494367d922847da84f972
dir: /man/2/iobuf/
.TH IOBUF 2 .SH NAME iobuf: ReadBuf, WriteBuf \- read/write buffers .SH SYNOPSIS .EX include "iobuf.m"; iobuf: IOBuf; ReadBuf, WriteBuf: import iobuf; iobuf = load IOBuf IOBuf->PATH; init: fn(); ReadBuf: adt{ new: fn(fd: ref Sys->FD, bufsize: int): ref ReadBuf; newc: fn(queuesize, bufsize: int): ref ReadBuf; setsep: fn(r: self ref ReadBuf, sep: string, strip: int); reads: fn(r: self ref ReadBuf): array of byte; readn: fn(r: self ref ReadBuf, n: int): array of byte; fill: fn(r: self ref ReadBuf, data: array of byte, wc: Sys->Rwrite); } WriteBuf: adt{ new: fn(fd: ref Sys->FD, bufsize: int): ref WriteBuf; newc: fn(bufsize: int): ref WriteBuf; write: fn(w: self ref WriteBuf, buf: array of byte); flush: fn(w: self ref WriteBuf); eof: fn(w: self ref WriteBuf); request: fn(w: self ref WriteBuf, n: int, rc: Sys->Rread); } .EE .SH DESCRIPTION .PP This module provide simpler and faster alternative to .IR bufio (2). On reading text file it's about 30-40 times faster than bufio, on writing text file it's about 3-4 times faster than bufio. .PP .B init must be called before invoking any other operation of the module. .SS ReadBuf .PP ReadBuf is used when we receive stream of bytes (from fd or file2chan for ex.) while we need to read by full records (either separated by some delimiter or having known size). .PP Reading from ReadBuf is blocking operation. .PP .B setsep convert .I sep from string to array of byte, and .B reads will use that array to search for separator. If separator will be Unicode char which may be encoded with different sequences of bytes, .B reads may fail to find it. .PP .B reads return record separated by .IR sep , optionally with separator stripped from end of record. Last record may not end with separator, so ReadBuf can't distinguish between incomplete record because of unexpected EOF and full last record without separator. Will return nil on EOF. Will raise on I/O error. Will raise if neither .I sep nor EOF will be found in .I bufsize bytes. .PP .B readn return record with .I n bytes size, or less on EOF. It's possible to have .I n greater than .IR bufsize . Will return array with less than .I n bytes on EOF. Will return nil on EOF. Will raise on I/O error. .PP Arrays returned by .B reads and .B readn usually will be slices of ReadBuf's internal buffer, which may be overwritten on next .B reads or .B readn calls, so these calls may change contents of previously returned arrays. .PP When ReadBuf used with chan instead of fd, .I queuesize define maximum amount of packets (not bytes!) received from chan, which wasn't fetched yet by .B reads or .BR readn . This is needed to optimize latency. .PP When ReadBuf used with chan, while one process may block in .B reads or .BR readn , another may receive data from chan, and should call .B fill to put this data into ReadBuf. .PP .B fill will either immediately send reply to .I wc if it was able to add data to ReadBuf, or save pending .I data and .I wc in ReadBuf (reply to .I wc will be sent later from process calling .B reads or .BR readn ). Call to .B fill never blocks. Will send error "concurrent writes not supported" to .I wc and drop .I data if will be called again before reply to previous .I wc will be sent (i.e. when previous .I wc is in pending state because of full incoming queue). .PP Resume: .RS .IP • Process reading from ReadBuf doesn't need to know about data source (fd or chan). .IP • Process reading from ReadBuf may intermix reads() and readn(), may change record separator at any time. .IP • Process reading from ReadBuf receive nil on EOF or got exception on I/O error. .IP • Process receiving data from chan (usually, file2chan) for ReadBuf just call fill() and don't bother about errors or replying to .IR wc . .RE .PP Limitations: .RS .IP • Unicode separator may not be detected in some cases. .IP • Offset/seek doesn't supported (so offset received with file2chan request will be ignored). .IP • No getb(), getc(), ungetb(), ungetc() - but they can be added later. .IP • Only one process may call reads() or readn() and only one (another) process may call fill(). .RE .SS WriteBuf .PP WriteBuf is used when we sending stream of bytes (to fd or file2chan for ex.) while we want to write data by (possibly small) records. .PP Writing to WriteBuf is blocking operation. .PP .B write is adding data from .I buf to WriteBuf. Size of .I buf may be greater than .IR bufsize . It may call .BR flush . Will raise on I/O error. .PP .B flush ensure all buffered data in WriteBuf is actually written. Will raise on I/O error. .PP When WriteBuf used with chan, while one process may block in .B write or .BR flush , another may receive read request from chan, and should call .B request to let .B write or .B flush send data from WriteBuf to chan when they'll be ready. .PP .B eof calls .BR flush , but what it does next depends on WriteBuf type. When WriteBuf used with fd, it do nothing more and just returns. When WriteBuf used with chan, it'll wait for next .B request and will reply on all with EOF .BI ( "" nil "" , "" nil "" ) , and will returns only after got .B request with .B nil .IR rc . .PP .B request notified WriteBuf about data requested by chan, to let .B write or .B flush to send data from .I buf to chan. Call to .B request never blocks. Will send error "concurrent reads not supported" to .I rc if will be called again before reply to previous .I rc will be sent. .PP Resume: .RS .IP • Process writing to WriteBuf doesn't need to know about data destination (fd or chan). .IP • Process writing to WriteBuf got exception on I/O error. .IP • Process receiving read requests from chan (usually, file2chan) from WriteBuf just call request() and don't bother about errors or replying to .IR rc . .RE .PP Limitations: .RS .IP • Offset/seek doesn't supported (so offset received with file2chan request will be ignored). .IP • Only one process may call write() or flush() and only one (another) process may call request(). .RE .SH EXAMPLES .EX .EE .SH SOURCE .PP .B /appl/lib/iobuf.b .br .SH SEE ALSO .PP .IR bufio (2) .SH BUGS