Plan 9 from Bell Labs’s /sys/src/games/agui/io.c

Copyright © 2021 Plan 9 Foundation
Distributed under the MIT License.
Download the Plan 9 distribution.


#include "audio.h"

enum
{
	Ilog	= 6,
	Isiz	= 1<<Ilog,
	Nbuf	= 5209*3,	// approx 1 meg
};

typedef	struct	Jbuf	Jbuf;
struct	Jbuf
{
	long	base;
	uchar	buf[Isiz];
	Jbuf*	next;
};

typedef	struct	Ibuf	Ibuf;
struct	Ibuf
{
	int	fd;
	long	base;
	Jbuf*	buf[Nbuf/3];
};

Ibuf*
Iopen(char *f, int)
{
	int i;
	Ibuf *b;
	Jbuf *c1, *c2, *c3;

	b = malloc(sizeof(*b));
	if(b == 0)
		return 0;
	memset(b, 0, sizeof(*b));
	b->fd = open(f, OREAD);
	if(b->fd < 0)
		return 0;
	for(i=0; i<nelem(b->buf); i++) {
		c1 = malloc(sizeof(*c1));
		c2 = malloc(sizeof(*c2));
		c3 = malloc(sizeof(*c3));
		if(c1 == 0 || c2 == 0 || c3 == 0)
			return 0;
		c1->base = -1;
		c2->base = -1;
		c3->base = -1;

		b->buf[i] = c1;
		c1->next = c2;
		c2->next = c3;
		c3->next = c1;
	}
	b->base = 0;
	return b;
}

long
Iseek(Ibuf *b, long o, int p)
{
	long base;

	switch(p) {
	default:
		fprint(2, "bad seek pointed: %d\n", p);
		exits(0);
	case 0:
		base = 0;
		break;
	case 1:
		base = b->base;
		break;
	case 2:
		base = seek(b->fd, 0, 2);
	}
	base += o;
	b->base = base;
	return base;
}

Jbuf*
getbuf(Ibuf *b, long base)
{
	int h, n;
	Jbuf *c1, *c2, *c3;

	h = base % nelem(b->buf);
	if(h < 0)
		h = 0;

	/* 1st recently matched buf */
	c1 = b->buf[h];
	if(c1->base == base)
		return c1;

	/* 3rd recently matched buf */
	c3 = c1->next;
	if(c3->base == base) {
		b->buf[h] = c3;
		return c3;
	}

	/* 2nd recently matched buf */
	c2 = c3->next;
	if(c2->base == base) {
		b->buf[h] = c2;
		c2->next = c3;
		c3->next = c1;
		c1->next = c2;
		return c2;
	}

	/* overwrite 3rd recently matched buf */
	if(seek(b->fd, base, 0) != base) {
		fprint(2, "seek error: %r\n");
		exits(0);
	}
	n = read(b->fd, c3->buf, Isiz);
	if(n < Isiz) {
		if(n <= 0) {
			fprint(2, "read error: o=%ld, n=%d %r\n", base, n);
			exits(0);
		}
		memset(c3->buf+n, 0, Isiz-n);
	}
	c3->base = base;
	b->buf[h] = c3;
	return c3;
}

int
Igetc1(Ibuf *b, long base)
{
	int off;
	Jbuf *c;

	b->base = base+1;
	off = base & (Isiz-1);
	base = base & ~(Isiz-1);

	c = getbuf(b, base);
	return c->buf[off];
}

int
Igetc(Ibuf *b)
{

	return Igetc1(b, b->base);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@plan9.bell-labs.com.