示例#1
0
/*
  read len bytes without advancing the read pointer
 */
uint32_t ByteBuffer::peekbytes(uint8_t *data, uint32_t len)
{
    if (len > available()) {
        len = available();
    }
    if (len == 0) {
        return 0;
    }
    uint32_t n;
    const uint8_t *b = readptr(n);
    if (n > len) {
        n = len;
    }

    // perform first memcpy
    memcpy(data, b, n);
    data += n;

    if (len > n) {
        // possible second memcpy, must be from front of buffer
        memcpy(data, buf, len-n);
    }
    return len;
}
示例#2
0
static long
segmentread(Chan *c, void *a, long n, vlong voff)
{
	Globalseg *g;
	Zseg *zs;
	uintptr va;
	char *p, *s;
	long tot;
	char buf[64];

	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, (Dirtab *)0, 0L, segmentgen);

	g = c->aux;
	switch(TYPE(c)){
	case Qfree:
		if(g->s == nil)
			error("segment not yet allocated");
		if(n < PTRSIZE)
			error("read buffer too small");
		zs = &g->s->zseg;
		qlock(&g->s->lk);
		if(waserror()){
			qunlock(&g->s->lk);
			nexterror();
		}
		while((va = zgetaddr(g->s)) == 0ULL){
			qunlock(&g->s->lk);
			sleep(&zs->rr, znotempty, zs);
			qlock(&g->s->lk);
		}
		p = a;
		for(tot = 0; n-tot > PTRSIZE; tot += PTRSIZE){
			p += readptr(p, n, va);
			if((va = zgetaddr(g->s)) == 0ULL)
				break;
		}
		poperror();
		qunlock(&g->s->lk);
		return tot;
	case Qctl:
		if(g->s == nil)
			error("segment not yet allocated");
		if(g->s->type&SG_KZIO)
			s = "kmsg";
		else if(g->s->type&SG_ZIO)
			s = "umsg";
		else
			s = "addr";
		snprint(buf, sizeof(buf), "%s %#p %#p\n",
			s, g->s->base, (uintptr)(g->s->top-g->s->base));
		return readstr(voff, a, n, buf);
	case Qdata:
		if(voff < 0)
			error(Enegoff);
		if(voff + n > g->s->top - g->s->base){
			n = g->s->top - voff;
			if(n <= 0)
				break;
		}
		qlock(&g->l);
		if(waserror()){
			qunlock(&g->l);
			nexterror();
		}

		g->off = voff + g->s->base;
		g->data = smalloc(n);
		if(waserror()){
			free(g->data);
			nexterror();
		}
		g->dlen = n;
		docmd(g, Cread);
		memmove(a, g->data, g->dlen);
		poperror();
		free(g->data);

		poperror();
		qunlock(&g->l);
		return g->dlen;
	default:
		panic("segmentread");
	}
	return 0;	/* not reached */
}