os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

bufio.om (2996B)


      1 struct file {
      2 	a: *alloc;
      3 	fd: int;
      4 	buf: *byte;
      5 	r: int;
      6 	w: int;
      7 	cap: int;
      8 	eof: int;
      9 	noflush: int;
     10 }
     11 
     12 func fopen(fd: int, a: *alloc): *file {
     13 	var f: *file;
     14 
     15 	f = alloc(a, sizeof(*f)) as *file;
     16 
     17 	f.fd = fd;
     18 	f.a = a;
     19 	f.r = 0;
     20 	f.w = 0;
     21 	f.cap = 4096 * 16;
     22 	f.eof = 0;
     23 
     24 	f.buf = alloc(a, f.cap);
     25 
     26 	return f;
     27 }
     28 
     29 func fclose(f: *file): void {
     30 	fflush(f);
     31 
     32 	if (close(f.fd) != 0) {
     33 		die("write failed");
     34 	}
     35 
     36 	free(f.a, f.buf);
     37 
     38 	free(f.a, f as *byte);
     39 }
     40 
     41 func fflush(f: *file): void {
     42 	var ret: int;
     43 
     44 	loop {
     45 		if (f.r == f.w) {
     46 			f.r = 0;
     47 			f.w = 0;
     48 			return;
     49 		}
     50 
     51 		ret = write(f.fd, &f.buf[f.r], f.w - f.r);
     52 
     53 		if (ret < 0) {
     54 			die("write failed");
     55 		}
     56 
     57 		f.r = f.r + ret;
     58 	}
     59 }
     60 
     61 func ffill(f: *file): void {
     62 	var ret: int;
     63 
     64 	if (f.eof) {
     65 		return;
     66 	}
     67 
     68 	if (f.r == f.w) {
     69 		f.r = 0;
     70 		f.w = 0;
     71 	}
     72 
     73 	if (f.w == f.cap) {
     74 		die("out of space");
     75 	}
     76 
     77 	ret = read(f.fd, &f.buf[f.w], f.cap - f.w);
     78 
     79 	if (ret < 0) {
     80 		die("read failed");
     81 	}
     82 
     83 	if (ret == 0) {
     84 		f.eof = 1;
     85 	}
     86 
     87 	f.w = f.w + ret;
     88 }
     89 
     90 func fputc(f: *file, ch: int): void {
     91 	var b: byte;
     92 
     93 	if !f {
     94 		b = ch as byte;
     95 		if write(1, &b, 1) != 1 {
     96 			exit(3);
     97 		}
     98 		return;
     99 	}
    100 
    101 	if (f.w == f.cap) {
    102 		fflush(f);
    103 	}
    104 
    105 	f.buf[f.w] = ch as byte;
    106 	f.w = f.w + 1;
    107 
    108 	if (ch == '\n' && !f.noflush) {
    109 		fflush(f);
    110 	}
    111 }
    112 
    113 func fgetc(f: *file): int {
    114 	var ch: int;
    115 
    116 	if (f.r == f.w) {
    117 		ffill(f);
    118 	}
    119 
    120 	if (f.eof) {
    121 		return -1;
    122 	}
    123 
    124 	ch = f.buf[f.r] as int;
    125 
    126 	f.r = f.r + 1;
    127 
    128 	return ch;
    129 }
    130 
    131 func fgets(f: *file, buf: *byte, len: int): int {
    132 	var i: int;
    133 	var c: int;
    134 
    135 	if len == 1 {
    136 		buf[0] = 0 as byte;
    137 		return 0;
    138 	}
    139 
    140 	i = 0;
    141 	loop {
    142 		if i + 1 == len {
    143 			buf[i] = 0 as byte;
    144 			return i;
    145 		}
    146 
    147 		c = fgetc(f);
    148 		if c == -1 || c == '\n' {
    149 			buf[i] = 0 as byte;
    150 			return i;
    151 		}
    152 
    153 		buf[i] = c as byte;
    154 		i = i + 1;
    155 	}
    156 }
    157 
    158 func fputs(f: *file, s: *byte) {
    159 	var i: int;
    160 	i = 0;
    161 	loop {
    162 		if !s[i] {
    163 			break;
    164 		}
    165 		fputc(f, s[i] as int);
    166 		i = i + 1;
    167 	}
    168 }
    169 
    170 func fputb(f: *file, s: *byte, n: int) {
    171 	var i: int;
    172 	i = 0;
    173 	loop {
    174 		if i >= n {
    175 			break;
    176 		}
    177 		fputc(f, s[i] as int);
    178 		i = i + 1;
    179 	}
    180 }
    181 
    182 func fputd(out: *file, n: int) {
    183 	var a: int;
    184 
    185 	if (n < 0) {
    186 		fputc(out, '-');
    187 		a = -(n % 10);
    188 		n = n / -10;
    189 	} else {
    190 		a = n % 10;
    191 		n = n / 10;
    192 	}
    193 
    194 	if (n != 0) {
    195 		fputd(out, n);
    196 	}
    197 
    198 	fputc(out, '0' + a);
    199 }
    200 
    201 func fputh(out: *file, n: int) {
    202 	var d: int;
    203 
    204 	d = n & 15;
    205 
    206 	n = n >> 4;
    207 
    208 	if n {
    209 		fputh(out, n);
    210 	}
    211 
    212 	fputc(out, "0123456789abcdef"[d] as int);
    213 }
    214 
    215 func fseek(f: *file, off: int) {
    216 	f.r = 0;
    217 	f.w = 0;
    218 	f.eof = 0;
    219 	if lseek(f.fd, off, 0) != off {
    220 		die("invalid seek");
    221 	}
    222 }
    223 
    224 func freadall(f: *file, size: *int): *byte {
    225 	var i: int;
    226 	var cap: int;
    227 	var ret: *byte;
    228 	var tmp: *byte;
    229 	var ch: int;
    230 
    231 	i = 0;
    232 	cap = 0;
    233 	loop {
    234 		ch = fgetc(f);
    235 		if ch == -1 {
    236 			*size = i;
    237 			return ret;
    238 		}
    239 
    240 		if i == cap {
    241 			if cap == 0 {
    242 				cap = 4096;
    243 				ret = alloc(f.a, cap);
    244 			} else {
    245 				cap = cap * 2;
    246 				tmp = alloc(f.a, cap);
    247 				memcpy(tmp, ret, i);
    248 				free(f.a, ret);
    249 				ret = tmp;
    250 			}
    251 		}
    252 
    253 		ret[i] = ch as byte;
    254 		i = i + 1;
    255 	}
    256 }