137da2899SCharles.Forsythimplement Bufio; 237da2899SCharles.Forsyth 337da2899SCharles.Forsythinclude "sys.m"; 437da2899SCharles.Forsyth sys: Sys; 537da2899SCharles.Forsyth 637da2899SCharles.Forsythinclude "bufio.m"; 737da2899SCharles.Forsyth 837da2899SCharles.ForsythUTFself: con 16r80; # ascii and UTF sequences are the same (<) 937da2899SCharles.ForsythMaxrune: con 8; # could probably be Sys->UTFmax 1037da2899SCharles.ForsythBufsize: con Sys->ATOMICIO; 1137da2899SCharles.Forsyth 1237da2899SCharles.ForsythFiller: adt 1337da2899SCharles.Forsyth{ 1437da2899SCharles.Forsyth iobuf: ref Iobuf; 1537da2899SCharles.Forsyth fill: BufioFill; 1637da2899SCharles.Forsyth next: cyclic ref Filler; 1737da2899SCharles.Forsyth}; 1837da2899SCharles.Forsyth 1937da2899SCharles.Forsythfillers: ref Filler; 2037da2899SCharles.Forsyth 2137da2899SCharles.Forsythcreate(filename: string, mode, perm: int): ref Iobuf 2237da2899SCharles.Forsyth{ 2337da2899SCharles.Forsyth if (sys == nil) 2437da2899SCharles.Forsyth sys = load Sys Sys->PATH; 2537da2899SCharles.Forsyth if ((fd := sys->create(filename, mode, perm)) == nil) 2637da2899SCharles.Forsyth return nil; 2737da2899SCharles.Forsyth return ref Iobuf(fd, array[Bufsize+Maxrune] of byte, 0, 0, 0, big 0, big 0, mode, mode); 2837da2899SCharles.Forsyth} 2937da2899SCharles.Forsyth 3037da2899SCharles.Forsythopen(filename: string, mode: int): ref Iobuf 3137da2899SCharles.Forsyth{ 3237da2899SCharles.Forsyth if (sys == nil) 3337da2899SCharles.Forsyth sys = load Sys Sys->PATH; 3437da2899SCharles.Forsyth if ((fd := sys->open(filename, mode)) == nil) 3537da2899SCharles.Forsyth return nil; 3637da2899SCharles.Forsyth return ref Iobuf(fd, array[Bufsize+Maxrune] of byte, 0, 0, 0, big 0, big 0, mode, mode); 3737da2899SCharles.Forsyth} 3837da2899SCharles.Forsyth 3937da2899SCharles.Forsythfopen(fd: ref Sys->FD, mode: int): ref Iobuf 4037da2899SCharles.Forsyth{ 4137da2899SCharles.Forsyth if (sys == nil) 4237da2899SCharles.Forsyth sys = load Sys Sys->PATH; 4337da2899SCharles.Forsyth if ((filpos := sys->seek(fd, big 0, 1)) < big 0) 4437da2899SCharles.Forsyth filpos = big 0; 4537da2899SCharles.Forsyth return ref Iobuf(fd, array[Bufsize+Maxrune] of byte, 0, 0, 0, filpos, filpos, mode, mode); 4637da2899SCharles.Forsyth} 4737da2899SCharles.Forsyth 4837da2899SCharles.Forsythsopen(input: string): ref Iobuf 4937da2899SCharles.Forsyth{ 5037da2899SCharles.Forsyth return aopen(array of byte input); 5137da2899SCharles.Forsyth} 5237da2899SCharles.Forsyth 5337da2899SCharles.Forsythaopen(b: array of byte): ref Iobuf 5437da2899SCharles.Forsyth{ 5537da2899SCharles.Forsyth if (sys == nil) 5637da2899SCharles.Forsyth sys = load Sys Sys->PATH; 5737da2899SCharles.Forsyth return ref Iobuf(nil, b, 0, len b, 0, big 0, big 0, OREAD, OREAD); 5837da2899SCharles.Forsyth} 5937da2899SCharles.Forsyth 6037da2899SCharles.Forsythreadchunk(b: ref Iobuf): int 6137da2899SCharles.Forsyth{ 6237da2899SCharles.Forsyth if (b.fd == nil){ 6337da2899SCharles.Forsyth if ((f := filler(b)) != nil){ 6437da2899SCharles.Forsyth if ((n := f.fill->fill(b)) == EOF) 6537da2899SCharles.Forsyth nofill(b); 6637da2899SCharles.Forsyth return n; 6737da2899SCharles.Forsyth } 6837da2899SCharles.Forsyth return EOF; 6937da2899SCharles.Forsyth } 7037da2899SCharles.Forsyth if (b.filpos != b.bufpos + big b.size) { 7137da2899SCharles.Forsyth s := b.bufpos + big b.size; 7237da2899SCharles.Forsyth if (sys->seek(b.fd, s, 0) != s) 7337da2899SCharles.Forsyth return ERROR; 7437da2899SCharles.Forsyth b.filpos = s; 7537da2899SCharles.Forsyth } 7637da2899SCharles.Forsyth i := len b.buffer - b.size - 1; 7737da2899SCharles.Forsyth if(i > Bufsize) 7837da2899SCharles.Forsyth i = Bufsize; 7937da2899SCharles.Forsyth if ((i = sys->read(b.fd, b.buffer[b.size:], i)) <= 0) { 8037da2899SCharles.Forsyth if(i < 0) 8137da2899SCharles.Forsyth return ERROR; 8237da2899SCharles.Forsyth return EOF; 8337da2899SCharles.Forsyth } 8437da2899SCharles.Forsyth b.size += i; 8537da2899SCharles.Forsyth b.filpos += big i; 8637da2899SCharles.Forsyth return i; 8737da2899SCharles.Forsyth} 8837da2899SCharles.Forsyth 8937da2899SCharles.Forsythwritechunk(b: ref Iobuf): int 9037da2899SCharles.Forsyth{ 918efcc025SCharles.Forsyth err := (b.fd == nil); 9237da2899SCharles.Forsyth if (b.filpos != b.bufpos) { 9337da2899SCharles.Forsyth if (sys->seek(b.fd, b.bufpos, 0) != b.bufpos) 948efcc025SCharles.Forsyth err = 1; 9537da2899SCharles.Forsyth b.filpos = b.bufpos; 9637da2899SCharles.Forsyth } 9737da2899SCharles.Forsyth if ((size := b.size) > Bufsize) 9837da2899SCharles.Forsyth size = Bufsize; 9937da2899SCharles.Forsyth if (sys->write(b.fd, b.buffer, size) != size) 1008efcc025SCharles.Forsyth err = 1; 10137da2899SCharles.Forsyth b.filpos += big size; 10237da2899SCharles.Forsyth b.size -= size; 10337da2899SCharles.Forsyth if (b.size) { 10437da2899SCharles.Forsyth b.dirty = 1; 10537da2899SCharles.Forsyth b.buffer[0:] = b.buffer[Bufsize:Bufsize+b.size]; 10637da2899SCharles.Forsyth } else 10737da2899SCharles.Forsyth b.dirty = 0; 10837da2899SCharles.Forsyth b.bufpos += big size; 10937da2899SCharles.Forsyth b.index -= size; 1108efcc025SCharles.Forsyth if(err) 1118efcc025SCharles.Forsyth return ERROR; 11237da2899SCharles.Forsyth return size; 11337da2899SCharles.Forsyth} 11437da2899SCharles.Forsyth 11537da2899SCharles.ForsythIobuf.close(b: self ref Iobuf) 11637da2899SCharles.Forsyth{ 11737da2899SCharles.Forsyth if (b.fd == nil) { 11837da2899SCharles.Forsyth nofill(b); 11937da2899SCharles.Forsyth return; 12037da2899SCharles.Forsyth } 12137da2899SCharles.Forsyth if (b.dirty) 12237da2899SCharles.Forsyth b.flush(); 12337da2899SCharles.Forsyth b.fd = nil; 12437da2899SCharles.Forsyth b.buffer = nil; 12537da2899SCharles.Forsyth} 12637da2899SCharles.Forsyth 12737da2899SCharles.ForsythIobuf.flush(b: self ref Iobuf): int 12837da2899SCharles.Forsyth{ 12937da2899SCharles.Forsyth if (b.fd == nil) 13037da2899SCharles.Forsyth return ERROR; 13137da2899SCharles.Forsyth if (b.lastop == OREAD){ 13237da2899SCharles.Forsyth b.bufpos = b.filpos; 13337da2899SCharles.Forsyth b.size = 0; 13437da2899SCharles.Forsyth return 0; 13537da2899SCharles.Forsyth } 13637da2899SCharles.Forsyth while (b.dirty) { 13737da2899SCharles.Forsyth if (writechunk(b) < 0) 13837da2899SCharles.Forsyth return ERROR; 13937da2899SCharles.Forsyth if (b.index < 0) { 14037da2899SCharles.Forsyth b.bufpos += big b.index; 14137da2899SCharles.Forsyth b.index = 0; 14237da2899SCharles.Forsyth } 14337da2899SCharles.Forsyth } 14437da2899SCharles.Forsyth return 0; 14537da2899SCharles.Forsyth} 14637da2899SCharles.Forsyth 14737da2899SCharles.ForsythIobuf.seek(b: self ref Iobuf, off: big, start: int): big 14837da2899SCharles.Forsyth{ 14937da2899SCharles.Forsyth npos: big; 15037da2899SCharles.Forsyth 15137da2899SCharles.Forsyth if (b.fd == nil){ 15237da2899SCharles.Forsyth if(filler(b) != nil) 15337da2899SCharles.Forsyth return big ERROR; 15437da2899SCharles.Forsyth } 15537da2899SCharles.Forsyth case (start) { 15637da2899SCharles.Forsyth 0 => # absolute address 15737da2899SCharles.Forsyth npos = off; 15837da2899SCharles.Forsyth 1 => # offset from current location 15937da2899SCharles.Forsyth npos = b.bufpos + big b.index + off; 16037da2899SCharles.Forsyth off = npos; 16137da2899SCharles.Forsyth start = Sys->SEEKSTART; 16237da2899SCharles.Forsyth 2 => # offset from EOF 16337da2899SCharles.Forsyth npos = big -1; 16437da2899SCharles.Forsyth * => return big ERROR; 16537da2899SCharles.Forsyth } 16637da2899SCharles.Forsyth if (b.bufpos <= npos && npos < b.bufpos + big b.size) { 16737da2899SCharles.Forsyth b.index = int(npos - b.bufpos); 16837da2899SCharles.Forsyth return npos; 16937da2899SCharles.Forsyth } 17037da2899SCharles.Forsyth if (b.fd == nil || b.dirty && b.flush() < 0) 17137da2899SCharles.Forsyth return big ERROR; 17237da2899SCharles.Forsyth b.size = 0; 17337da2899SCharles.Forsyth b.index = 0; 174*eddf3bddSforsyth if ((s := sys->seek(b.fd, off, start)) < big 0) { 175*eddf3bddSforsyth b.bufpos = b.filpos; 17637da2899SCharles.Forsyth return big ERROR; 177*eddf3bddSforsyth } 17837da2899SCharles.Forsyth b.bufpos = b.filpos = s; 179c25d3f6dSforsyth return s; 18037da2899SCharles.Forsyth} 18137da2899SCharles.Forsyth 18237da2899SCharles.ForsythIobuf.offset(b: self ref Iobuf): big 18337da2899SCharles.Forsyth{ 18437da2899SCharles.Forsyth return b.bufpos + big b.index; 18537da2899SCharles.Forsyth} 18637da2899SCharles.Forsyth 18737da2899SCharles.Forsythwrite2read(b: ref Iobuf): int 18837da2899SCharles.Forsyth{ 18937da2899SCharles.Forsyth while (b.dirty) 19037da2899SCharles.Forsyth if (b.flush() < 0) 19137da2899SCharles.Forsyth return ERROR; 19237da2899SCharles.Forsyth b.bufpos = b.filpos; 19337da2899SCharles.Forsyth b.size = 0; 19437da2899SCharles.Forsyth b.lastop = OREAD; 19537da2899SCharles.Forsyth if ((r := readchunk(b)) < 0) 19637da2899SCharles.Forsyth return r; 19737da2899SCharles.Forsyth if (b.index > b.size) 19837da2899SCharles.Forsyth return EOF; 19937da2899SCharles.Forsyth return 0; 20037da2899SCharles.Forsyth} 20137da2899SCharles.Forsyth 20237da2899SCharles.ForsythIobuf.read(b: self ref Iobuf, buf: array of byte, n: int): int 20337da2899SCharles.Forsyth{ 20437da2899SCharles.Forsyth if (b.mode == OWRITE) 20537da2899SCharles.Forsyth return ERROR; 20637da2899SCharles.Forsyth if (b.lastop != OREAD){ 20737da2899SCharles.Forsyth if ((r := write2read(b)) < 0) 20837da2899SCharles.Forsyth return r; 20937da2899SCharles.Forsyth } 21037da2899SCharles.Forsyth k := n; 21137da2899SCharles.Forsyth while (b.size - b.index < k) { 21237da2899SCharles.Forsyth buf[0:] = b.buffer[b.index:b.size]; 21337da2899SCharles.Forsyth buf = buf[b.size - b.index:]; 21437da2899SCharles.Forsyth k -= b.size - b.index; 21537da2899SCharles.Forsyth 21637da2899SCharles.Forsyth b.bufpos += big b.size; 21737da2899SCharles.Forsyth b.index = 0; 21837da2899SCharles.Forsyth b.size = 0; 21937da2899SCharles.Forsyth if ((r := readchunk(b)) < 0) { 22037da2899SCharles.Forsyth if(r == EOF || n != k) 22137da2899SCharles.Forsyth return n-k; 22237da2899SCharles.Forsyth return ERROR; 22337da2899SCharles.Forsyth } 22437da2899SCharles.Forsyth } 22537da2899SCharles.Forsyth buf[0:] = b.buffer[b.index:b.index+k]; 22637da2899SCharles.Forsyth b.index += k; 22737da2899SCharles.Forsyth return n; 22837da2899SCharles.Forsyth} 22937da2899SCharles.Forsyth 23037da2899SCharles.ForsythIobuf.getb(b: self ref Iobuf): int 23137da2899SCharles.Forsyth{ 23237da2899SCharles.Forsyth if(b.lastop != OREAD){ 23337da2899SCharles.Forsyth if(b.mode == OWRITE) 23437da2899SCharles.Forsyth return ERROR; 23537da2899SCharles.Forsyth if((r := write2read(b)) < 0) 23637da2899SCharles.Forsyth return r; 23737da2899SCharles.Forsyth } 23837da2899SCharles.Forsyth if (b.index == b.size) { 23937da2899SCharles.Forsyth b.bufpos += big b.index; 24037da2899SCharles.Forsyth b.index = 0; 24137da2899SCharles.Forsyth b.size = 0; 24237da2899SCharles.Forsyth if ((r := readchunk(b)) < 0) 24337da2899SCharles.Forsyth return r; 24437da2899SCharles.Forsyth } 24537da2899SCharles.Forsyth return int b.buffer[b.index++]; 24637da2899SCharles.Forsyth} 24737da2899SCharles.Forsyth 24837da2899SCharles.ForsythIobuf.ungetb(b: self ref Iobuf): int 24937da2899SCharles.Forsyth{ 25037da2899SCharles.Forsyth if(b.mode == OWRITE || b.lastop != OREAD) 25137da2899SCharles.Forsyth return ERROR; 25237da2899SCharles.Forsyth b.index--; 25337da2899SCharles.Forsyth return 1; 25437da2899SCharles.Forsyth} 25537da2899SCharles.Forsyth 25637da2899SCharles.ForsythIobuf.getc(b: self ref Iobuf): int 25737da2899SCharles.Forsyth{ 25837da2899SCharles.Forsyth r, i, s: int; 25937da2899SCharles.Forsyth 26037da2899SCharles.Forsyth if(b.lastop != OREAD){ 26137da2899SCharles.Forsyth if(b.mode == OWRITE) 26237da2899SCharles.Forsyth return ERROR; 26337da2899SCharles.Forsyth if((r = write2read(b)) < 0) 26437da2899SCharles.Forsyth return r; 26537da2899SCharles.Forsyth } 26637da2899SCharles.Forsyth for(;;) { 26737da2899SCharles.Forsyth if(b.index < b.size) { 26837da2899SCharles.Forsyth r = int b.buffer[b.index]; 26937da2899SCharles.Forsyth if(r < UTFself){ 27037da2899SCharles.Forsyth b.index++; 27137da2899SCharles.Forsyth return r; 27237da2899SCharles.Forsyth } 27337da2899SCharles.Forsyth (r, i, s) = sys->byte2char(b.buffer[0:b.size], b.index); 27437da2899SCharles.Forsyth if (i != 0) { 27537da2899SCharles.Forsyth b.index += i; 27637da2899SCharles.Forsyth return r; 27737da2899SCharles.Forsyth } 27837da2899SCharles.Forsyth b.buffer[0:] = b.buffer[b.index:b.size]; 27937da2899SCharles.Forsyth } 28037da2899SCharles.Forsyth b.bufpos += big b.index; 28137da2899SCharles.Forsyth b.size -= b.index; 28237da2899SCharles.Forsyth b.index = 0; 28337da2899SCharles.Forsyth if ((r = readchunk(b)) < 0) 28437da2899SCharles.Forsyth return r; 28537da2899SCharles.Forsyth } 28637da2899SCharles.Forsyth # Not reached: 28737da2899SCharles.Forsyth return -1; 28837da2899SCharles.Forsyth} 28937da2899SCharles.Forsyth 29037da2899SCharles.ForsythIobuf.ungetc(b: self ref Iobuf): int 29137da2899SCharles.Forsyth{ 29237da2899SCharles.Forsyth if(b.index == 0 || b.mode == OWRITE || b.lastop != OREAD) 29337da2899SCharles.Forsyth return ERROR; 29437da2899SCharles.Forsyth stop := b.index - Sys->UTFmax; 29537da2899SCharles.Forsyth if(stop < 0) 29637da2899SCharles.Forsyth stop = 0; 29737da2899SCharles.Forsyth buf := b.buffer[0:b.size]; 29837da2899SCharles.Forsyth for(i := b.index-1; i >= stop; i--){ 2998efcc025SCharles.Forsyth (nil, n, s) := sys->byte2char(buf, i); 30037da2899SCharles.Forsyth if(s && i + n == b.index){ 30137da2899SCharles.Forsyth b.index = i; 30237da2899SCharles.Forsyth return 1; 30337da2899SCharles.Forsyth } 30437da2899SCharles.Forsyth } 30537da2899SCharles.Forsyth b.index--; 30637da2899SCharles.Forsyth 30737da2899SCharles.Forsyth return 1; 30837da2899SCharles.Forsyth} 30937da2899SCharles.Forsyth 31037da2899SCharles.Forsyth# optimised when term < UTFself (common case) 31137da2899SCharles.Forsythtgets(b: ref Iobuf, t: int): string 31237da2899SCharles.Forsyth{ 31337da2899SCharles.Forsyth str: string; 31437da2899SCharles.Forsyth term := byte t; 31537da2899SCharles.Forsyth for(;;){ 31637da2899SCharles.Forsyth start := b.index; 31737da2899SCharles.Forsyth end := start + sys->utfbytes(b.buffer[start:], b.size-start); 31837da2899SCharles.Forsyth buf := b.buffer; 31937da2899SCharles.Forsyth # XXX could speed up by adding extra byte to end of buffer and 32037da2899SCharles.Forsyth # placing a sentinel there (eliminate one test, perhaps 35% speedup). 32137da2899SCharles.Forsyth # (but not when we've been given the buffer externally) 32237da2899SCharles.Forsyth for(i := start; i < end; i++){ 32337da2899SCharles.Forsyth if(buf[i] == term){ 32437da2899SCharles.Forsyth i++; 32537da2899SCharles.Forsyth str += string buf[start:i]; 32637da2899SCharles.Forsyth b.index = i; 32737da2899SCharles.Forsyth return str; 32837da2899SCharles.Forsyth } 32937da2899SCharles.Forsyth } 33037da2899SCharles.Forsyth str += string buf[start:i]; 33137da2899SCharles.Forsyth if(i < b.size) 33237da2899SCharles.Forsyth b.buffer[0:] = buf[i:b.size]; 33337da2899SCharles.Forsyth b.size -= i; 33437da2899SCharles.Forsyth b.bufpos += big i; 33537da2899SCharles.Forsyth b.index = 0; 33637da2899SCharles.Forsyth if(readchunk(b) < 0) 33737da2899SCharles.Forsyth break; 33837da2899SCharles.Forsyth } 33937da2899SCharles.Forsyth return str; 34037da2899SCharles.Forsyth} 34137da2899SCharles.Forsyth 34237da2899SCharles.ForsythIobuf.gets(b: self ref Iobuf, term: int): string 34337da2899SCharles.Forsyth{ 34437da2899SCharles.Forsyth i: int; 34537da2899SCharles.Forsyth 34637da2899SCharles.Forsyth if(b.mode == OWRITE) 34737da2899SCharles.Forsyth return nil; 34837da2899SCharles.Forsyth if(b.lastop != OREAD && write2read(b) < 0) 34937da2899SCharles.Forsyth return nil; 35037da2899SCharles.Forsyth# if(term < UTFself) 35137da2899SCharles.Forsyth# return tgets(b, term); 35237da2899SCharles.Forsyth str: string; 35337da2899SCharles.Forsyth ch := -1; 35437da2899SCharles.Forsyth for (;;) { 35537da2899SCharles.Forsyth start := b.index; 35637da2899SCharles.Forsyth n := 0; 35737da2899SCharles.Forsyth while(b.index < b.size){ 35837da2899SCharles.Forsyth (ch, i, nil) = sys->byte2char(b.buffer[0:b.size], b.index); 35937da2899SCharles.Forsyth if(i == 0) # too few bytes for full Rune 36037da2899SCharles.Forsyth break; 36137da2899SCharles.Forsyth n += i; 36237da2899SCharles.Forsyth b.index += i; 36337da2899SCharles.Forsyth if(ch == term) 36437da2899SCharles.Forsyth break; 36537da2899SCharles.Forsyth } 36637da2899SCharles.Forsyth if(n > 0) 36737da2899SCharles.Forsyth str += string b.buffer[start:start+n]; 36837da2899SCharles.Forsyth if(ch == term) 36937da2899SCharles.Forsyth return str; 37037da2899SCharles.Forsyth b.buffer[0:] = b.buffer[b.index:b.size]; 37137da2899SCharles.Forsyth b.bufpos += big b.index; 37237da2899SCharles.Forsyth b.size -= b.index; 37337da2899SCharles.Forsyth b.index = 0; 37437da2899SCharles.Forsyth if (readchunk(b) < 0) 37537da2899SCharles.Forsyth break; 37637da2899SCharles.Forsyth } 37737da2899SCharles.Forsyth return str; # nil at EOF 37837da2899SCharles.Forsyth} 37937da2899SCharles.Forsyth 38037da2899SCharles.ForsythIobuf.gett(b: self ref Iobuf, s: string): string 38137da2899SCharles.Forsyth{ 38237da2899SCharles.Forsyth r := ""; 38337da2899SCharles.Forsyth if (b.mode == OWRITE || (ch := b.getc()) < 0) 38437da2899SCharles.Forsyth return nil; 38537da2899SCharles.Forsyth do { 38637da2899SCharles.Forsyth r[len r] = ch; 38737da2899SCharles.Forsyth for (i:=0; i<len(s); i++) 38837da2899SCharles.Forsyth if (ch == s[i]) 38937da2899SCharles.Forsyth return r; 39037da2899SCharles.Forsyth } while ((ch = b.getc()) >= 0); 39137da2899SCharles.Forsyth return r; 39237da2899SCharles.Forsyth} 39337da2899SCharles.Forsyth 39437da2899SCharles.Forsythread2write(b: ref Iobuf) 39537da2899SCharles.Forsyth{ 39637da2899SCharles.Forsyth # last operation was a read 39737da2899SCharles.Forsyth b.bufpos += big b.index; 39837da2899SCharles.Forsyth b.size = 0; 39937da2899SCharles.Forsyth b.index = 0; 40037da2899SCharles.Forsyth b.lastop = OWRITE; 40137da2899SCharles.Forsyth} 40237da2899SCharles.Forsyth 40337da2899SCharles.ForsythIobuf.write(b: self ref Iobuf, buf: array of byte, n: int): int 40437da2899SCharles.Forsyth{ 40537da2899SCharles.Forsyth if(b.lastop != OWRITE) { 40637da2899SCharles.Forsyth if(b.mode == OREAD) 40737da2899SCharles.Forsyth return ERROR; 40837da2899SCharles.Forsyth read2write(b); 40937da2899SCharles.Forsyth } 41037da2899SCharles.Forsyth start := 0; 41137da2899SCharles.Forsyth k := n; 41237da2899SCharles.Forsyth while(k > 0){ 41337da2899SCharles.Forsyth nw := Bufsize - b.index; 41437da2899SCharles.Forsyth if(nw > k) 41537da2899SCharles.Forsyth nw = k; 41637da2899SCharles.Forsyth end := start + nw; 41737da2899SCharles.Forsyth b.buffer[b.index:] = buf[start:end]; 41837da2899SCharles.Forsyth start = end; 41937da2899SCharles.Forsyth b.index += nw; 42037da2899SCharles.Forsyth k -= nw; 42137da2899SCharles.Forsyth if(b.index > b.size) 42237da2899SCharles.Forsyth b.size = b.index; 42337da2899SCharles.Forsyth b.dirty = 1; 42437da2899SCharles.Forsyth if(b.size == Bufsize && writechunk(b) < 0) 42537da2899SCharles.Forsyth return ERROR; 42637da2899SCharles.Forsyth } 42737da2899SCharles.Forsyth return n; 42837da2899SCharles.Forsyth} 42937da2899SCharles.Forsyth 43037da2899SCharles.ForsythIobuf.putb(b: self ref Iobuf, c: byte): int 43137da2899SCharles.Forsyth{ 43237da2899SCharles.Forsyth if(b.lastop != OWRITE) { 43337da2899SCharles.Forsyth if(b.mode == OREAD) 43437da2899SCharles.Forsyth return ERROR; 43537da2899SCharles.Forsyth read2write(b); 43637da2899SCharles.Forsyth } 43737da2899SCharles.Forsyth b.buffer[b.index++] = c; 43837da2899SCharles.Forsyth if(b.index > b.size) 43937da2899SCharles.Forsyth b.size = b.index; 44037da2899SCharles.Forsyth b.dirty = 1; 44137da2899SCharles.Forsyth if(b.size >= Bufsize) { 44237da2899SCharles.Forsyth if (b.fd == nil) 44337da2899SCharles.Forsyth return ERROR; 44437da2899SCharles.Forsyth if (writechunk(b) < 0) 44537da2899SCharles.Forsyth return ERROR; 44637da2899SCharles.Forsyth } 44737da2899SCharles.Forsyth return 0; 44837da2899SCharles.Forsyth} 44937da2899SCharles.Forsyth 45037da2899SCharles.ForsythIobuf.putc(b: self ref Iobuf, c: int): int 45137da2899SCharles.Forsyth{ 45237da2899SCharles.Forsyth if(b.lastop != OWRITE) { 45337da2899SCharles.Forsyth if (b.mode == OREAD) 45437da2899SCharles.Forsyth return ERROR; 45537da2899SCharles.Forsyth read2write(b); 45637da2899SCharles.Forsyth } 45737da2899SCharles.Forsyth if(c < UTFself) 45837da2899SCharles.Forsyth b.buffer[b.index++] = byte c; 45937da2899SCharles.Forsyth else 46037da2899SCharles.Forsyth b.index += sys->char2byte(c, b.buffer, b.index); 46137da2899SCharles.Forsyth if (b.index > b.size) 46237da2899SCharles.Forsyth b.size = b.index; 46337da2899SCharles.Forsyth b.dirty = 1; 46437da2899SCharles.Forsyth if (b.size >= Bufsize) { 46537da2899SCharles.Forsyth if (writechunk(b) < 0) 46637da2899SCharles.Forsyth return ERROR; 46737da2899SCharles.Forsyth } 46837da2899SCharles.Forsyth return 0; 46937da2899SCharles.Forsyth} 47037da2899SCharles.Forsyth 47137da2899SCharles.ForsythIobuf.puts(b: self ref Iobuf, s: string): int 47237da2899SCharles.Forsyth{ 47337da2899SCharles.Forsyth if(b.lastop != OWRITE) { 47437da2899SCharles.Forsyth if (b.mode == OREAD) 47537da2899SCharles.Forsyth return ERROR; 47637da2899SCharles.Forsyth read2write(b); 47737da2899SCharles.Forsyth } 47837da2899SCharles.Forsyth n := len s; 47937da2899SCharles.Forsyth if (n == 0) 48037da2899SCharles.Forsyth return 0; 48137da2899SCharles.Forsyth ind := b.index; 48237da2899SCharles.Forsyth buf := b.buffer; 48337da2899SCharles.Forsyth for(i := 0; i < n; i++){ 48437da2899SCharles.Forsyth c := s[i]; 48537da2899SCharles.Forsyth if(c < UTFself) 48637da2899SCharles.Forsyth buf[ind++] = byte c; 48737da2899SCharles.Forsyth else 48837da2899SCharles.Forsyth ind += sys->char2byte(c, buf, ind); 48937da2899SCharles.Forsyth if(ind >= Bufsize){ 49037da2899SCharles.Forsyth b.index = ind; 49137da2899SCharles.Forsyth if(ind > b.size) 49237da2899SCharles.Forsyth b.size = ind; 49337da2899SCharles.Forsyth b.dirty = 1; 49437da2899SCharles.Forsyth if(writechunk(b) < 0) 49537da2899SCharles.Forsyth return ERROR; 49637da2899SCharles.Forsyth ind = b.index; 49737da2899SCharles.Forsyth } 49837da2899SCharles.Forsyth } 49937da2899SCharles.Forsyth b.dirty = b.index != ind; 50037da2899SCharles.Forsyth b.index = ind; 50137da2899SCharles.Forsyth if (ind > b.size) 50237da2899SCharles.Forsyth b.size = ind; 50337da2899SCharles.Forsyth return n; 50437da2899SCharles.Forsyth} 50537da2899SCharles.Forsyth 50637da2899SCharles.Forsythfiller(b: ref Iobuf): ref Filler 50737da2899SCharles.Forsyth{ 50837da2899SCharles.Forsyth for (f := fillers; f != nil; f = f.next) 50937da2899SCharles.Forsyth if(f.iobuf == b) 51037da2899SCharles.Forsyth return f; 51137da2899SCharles.Forsyth return nil; 51237da2899SCharles.Forsyth} 51337da2899SCharles.Forsyth 51437da2899SCharles.ForsythIobuf.setfill(b: self ref Iobuf, fill: BufioFill) 51537da2899SCharles.Forsyth{ 51637da2899SCharles.Forsyth if ((f := filler(b)) != nil) 51737da2899SCharles.Forsyth f.fill = fill; 51837da2899SCharles.Forsyth else 51937da2899SCharles.Forsyth fillers = ref Filler(b, fill, fillers); 52037da2899SCharles.Forsyth} 52137da2899SCharles.Forsyth 52237da2899SCharles.Forsythnofill(b: ref Iobuf) 52337da2899SCharles.Forsyth{ 52437da2899SCharles.Forsyth prev: ref Filler; 52537da2899SCharles.Forsyth for(f := fillers; f != nil; f = f.next) { 52637da2899SCharles.Forsyth if(f.iobuf == b) { 52737da2899SCharles.Forsyth if (prev == nil) 52837da2899SCharles.Forsyth fillers = f.next; 52937da2899SCharles.Forsyth else 53037da2899SCharles.Forsyth prev.next = f.next; 53137da2899SCharles.Forsyth } 53237da2899SCharles.Forsyth prev = f; 53337da2899SCharles.Forsyth } 53437da2899SCharles.Forsyth} 535