shithub: riscv

Download patch

ref: 169db43ad91d6873a3ba3cd1396aaaf96e9d4dc5
parent: 00334c0407e27921754d6ccd77d08045c2fa7254
parent: aac81cf0701330fff4ff83fc72e9200dc4b1a60c
author: cinap_lenrek <[email protected]>
date: Fri Dec 12 16:07:44 EST 2014

merge

--- a/acme/bin/source/win/fs.c
+++ b/acme/bin/source/win/fs.c
@@ -46,10 +46,9 @@
 {
 	static Event *e[4];
 	Event *ep;
-	int i, j, ei, nb, wid, pid;
+	int nb, wid, pid;
 	Rune rune;
-	char *s;
-	char tmp[UTFmax], *t;
+	char *s, *se, *d, *p;
 	static int n, partial;
 
 	if(r->fid->file == devnew){
@@ -60,13 +59,13 @@
 		s = emalloc(r->ifcall.count+1);
 		memmove(s, r->ifcall.data, r->ifcall.count);
 		s[r->ifcall.count] = 0;
-		pid = strtol(s, &t, 0);
-		if(*t==' ')
-			t++;
-		i = newpipewin(pid, t);
+		pid = strtol(s, &p, 0);
+		if(*p==' ')
+			p++;
+		nb = newpipewin(pid, p);
 		free(s);
 		s = emalloc(32);
-		sprint(s, "%lud", (ulong)i);
+		sprint(s, "%lud", (ulong)nb);
 		r->fid->aux = s;
 		r->ofcall.count = r->ifcall.count;
 		respond(r, nil);
@@ -73,45 +72,67 @@
 		return;
 	}
 
-	assert(r->fid->file == devcons);
+	if(r->fid->file != devcons){
+		respond(r, "bug in fswrite");
+		return;
+	}
 
+	/* init buffer rings */
 	if(e[0] == nil){
-		for(i=0; i<nelem(e); i++){
-			e[i] = emalloc(sizeof(Event));
-			e[i]->c1 = 'S';
+		for(n=0; n<nelem(e); n++){
+			e[n] = emalloc(sizeof(Event));
+			e[n]->c1 = 'S';
 		}
 	}
 
-	ep = e[n];
-	n = (n+1)%nelem(e);
-	assert(r->ifcall.count <= 8192);	/* is this guaranteed by lib9p? */
-	nb = r->ifcall.count;
-	memmove(ep->b+partial, r->ifcall.data, nb);
-	nb += partial;
-	ep->b[nb] = '\0';
-	if(strlen(ep->b) < nb){	/* nulls in data */
-		t = ep->b;
-		for(i=j=0; i<nb; i++)
-			if(ep->b[i] != '\0')
-				t[j++] = ep->b[i];
-		nb = j;
-		t[j] = '\0';
+	s = r->ifcall.data;
+	se = s + r->ifcall.count;
+
+	while((nb = (se - s)) > 0){
+		assert(partial >= 0);
+		if((partial+nb) > EVENTSIZE)
+			nb = EVENTSIZE - partial;
+
+		/* fill buffer */
+		ep = e[n % nelem(e)];
+		memmove(ep->b+partial, s, nb);
+		partial += nb;
+		s += nb;
+
+		/* check full runes, remove null bytes */
+		ep->nr = ep->nb = 0;
+		for(d = p = ep->b; partial > 0; partial -= wid, p += wid){
+			if(*p == '\0'){
+				wid = 1;
+				continue;
+			}
+
+			if(!fullrune(p, partial))
+				break;
+
+			wid = chartorune(&rune, p);
+			runetochar(d, &rune);
+			d += wid;
+
+			ep->nr++;
+			ep->nb += wid;
+		}
+
+		/* send buffer when not empty */
+		if(ep->nb > 0){
+			ep->b[ep->nb] = '\0';
+			sendp(win->cevent, ep);
+			recvp(writechan);
+		}
+		n++;
+
+		/* put partial reminder onto next buffer */
+		if(partial > 0){
+			ep = e[n % nelem(e)];
+			memmove(ep->b, p, partial);
+		}
 	}
-	ei = nb>8192? 8192 : nb;
-	/* process bytes into runes, transferring terminal partial runes into next buffer */
-	for(i=j=0; i<ei && fullrune(ep->b+i, ei-i); i+=wid,j++)
-		wid = chartorune(&rune, ep->b+i);
-	memmove(tmp, ep->b+i, nb-i);
-	partial = nb-i;
-	ep->nb = i;
-	ep->nr = j;
-	ep->b[i] = '\0';
-	if(i != 0){
-		sendp(win->cevent, ep);
-		recvp(writechan);
-	}
-	partial = nb-i;
-	memmove(e[n]->b, tmp, partial);
+
 	r->ofcall.count = r->ifcall.count;
 	respond(r, nil);
 }