#include "../sccshead/sfile.h"
char outbuf_[] "~|^`outbuf.c:	3.1";
/*
	Bottom level write routines for SCCS files.

	Usage:
		struct Obufr ob;
		...
		crtr(&ob,"filename",0666);
		...
		putr(&ob,recaddr,reclen);
		...
		flshr(&ob);

	Recaddr need not be even, but it will be written to an even address
	in the file anyhow.  Putr automatically computes a hash count for
	the written file and stores it in address HASHADDR.

	Second (non-zero) argument to flshr if present suppresses
	storing of the hash count.  This argument must be used for
	compatibility with Release 1 of SCCS.
*/

crtr(buf,file,mode)
register struct Obufr *buf;
char file[];
int mode;

{
	buf->Ofildes = xcreat(file,mode);
	buf->Obuff1[0] = '\0';
	buf->Orecptr = buf->Obuff1 + 1;
	buf->Oend = buf->Orecptr + 510;
	buf->Ohcnt = buf->Ohflag = 0;
}


struct {int *ip;};

putr(buf,rec,len)
struct Obufr *buf;
char *rec;
int len;
{
	register int l;
	register char *p, *r;
	int lsave;
	char *rsave;

	l = len;
	p = buf->Orecptr;
	r = rec;

	if(l > 255) fatal("record too big (202)");

	*p++ = l - 128;
	if(!(l&1)) l++;

	while(1) {
		while(p <= buf->Oend) {
			if(l-- == 0) {
				buf->Orecptr = p;
				return;
			}
			*p++ = *r++;
		}

		xwrite(buf->Ofildes,p=buf->Obuff1,512);

		lsave = l;
		rsave = r;
		if(buf->Ohflag == 0) {
			buf->Ohflag = 1;
			p.ip[HASHADDR>>1] = 0;
		}

		r.ip = p.ip + 256;
		for(l=0; p.ip<r.ip; p.ip++) l =+ *p.ip;
		buf->Ohcnt =+ l;
		l = lsave;
		r = rsave;
		p = buf->Obuff1;
	}
}


flshr(buf,nohash)
struct Obufr *buf;
int nohash;
{
	register int n, *p, *q;

	n = buf->Orecptr - buf->Obuff1;
	if(n < 512) buf->Obuff1[n] = 0;

	xwrite(buf->Ofildes,buf->Orecptr=buf->Obuff1,n);

	p = buf->Obuff1;
	q = &p[(n&1?n-1:n-2)>>1];
	for(n=0; p<=q; p++) n =+ *p;
	buf->Ohcnt =+ n;

	if(nohash) return;
	seek(buf->Ofildes,HASHADDR,0);
	write(buf->Ofildes,&buf->Ohcnt,2);
}
