Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include        <u.h>
#include        <libc.h>
#include        <fcall.h>

static
uchar*
pstring(uchar *p, char *s)
{
        uint n;

        if(s == nil){
                PBIT16(p, 0);
                p += BIT16SZ;
                return p;
        }

        n = strlen(s);
        /*
         * We are moving the string before the length,
         * so you can S2M a struct into an existing message
         */
        memmove(p + BIT16SZ, s, n);
        PBIT16(p, n);
        p += n + BIT16SZ;
        return p;
}

static
uchar*
pqid(uchar *p, Qid *q)
{
        PBIT8(p, q->type);
        p += BIT8SZ;
        PBIT32(p, q->vers);
        p += BIT32SZ;
        PBIT64(p, q->path);
        p += BIT64SZ;
        return p;
}

static
uint
stringsz(char *s)
{
        if(s == nil)
                return BIT16SZ;

        return BIT16SZ+strlen(s);
}

uint
sizeS2M(Fcall *f)
{
        uint n;
        int i;

        n = 0;
        n += BIT32SZ;   /* size */
        n += BIT8SZ;    /* type */
        n += BIT16SZ;   /* tag */

        switch(f->type)
        {
        default:
                return 0;

        case Tversion:
                n += BIT32SZ;
                n += stringsz(f->version);
                break;

        case Tflush:
                n += BIT16SZ;
                break;

        case Tauth:
                n += BIT32SZ;
                n += stringsz(f->uname);
                n += stringsz(f->aname);
                break;

        case Tattach:
                n += BIT32SZ;
                n += BIT32SZ;
                n += stringsz(f->uname);
                n += stringsz(f->aname);
                break;

        case Twalk:
                n += BIT32SZ;
                n += BIT32SZ;
                n += BIT16SZ;
                for(i=0; i<f->nwname; i++)
                        n += stringsz(f->wname[i]);
                break;

        case Topen:
                n += BIT32SZ;
                n += BIT8SZ;
                break;

        case Tcreate:
                n += BIT32SZ;
                n += stringsz(f->name);
                n += BIT32SZ;
                n += BIT8SZ;
                break;

        case Tread:
                n += BIT32SZ;
                n += BIT64SZ;
                n += BIT32SZ;
                break;

        case Twrite:
                n += BIT32SZ;
                n += BIT64SZ;
                n += BIT32SZ;
                n += f->count;
                break;

        case Tclunk:
        case Tremove:
                n += BIT32SZ;
                break;

        case Tstat:
                n += BIT32SZ;
                break;

        case Twstat:
                n += BIT32SZ;
                n += BIT16SZ;
                n += f->nstat;
                break;
/*
 */

        case Rversion:
                n += BIT32SZ;
                n += stringsz(f->version);
                break;

        case Rerror:
                n += stringsz(f->ename);
                break;

        case Rflush:
                break;

        case Rauth:
                n += QIDSZ;
                break;

        case Rattach:
                n += QIDSZ;
                break;

        case Rwalk:
                n += BIT16SZ;
                n += f->nwqid*QIDSZ;
                break;

        case Ropen:
        case Rcreate:
                n += QIDSZ;
                n += BIT32SZ;
                break;

        case Rread:
                n += BIT32SZ;
                n += f->count;
                break;

        case Rwrite:
                n += BIT32SZ;
                break;

        case Rclunk:
                break;

        case Rremove:
                break;

        case Rstat:
                n += BIT16SZ;
                n += f->nstat;
                break;

        case Rwstat:
                break;
        }
        return n;
}

uint
convS2M(Fcall *f, uchar *ap, uint nap)
{
        uchar *p;
        uint i, size;

        size = sizeS2M(f);
        if(size == 0)
                return 0;
        if(size > nap)
                return 0;

        p = (uchar*)ap;

        PBIT32(p, size);
        p += BIT32SZ;
        PBIT8(p, f->type);
        p += BIT8SZ;
        PBIT16(p, f->tag);
        p += BIT16SZ;

        switch(f->type)
        {
        default:
                return 0;

        case Tversion:
                PBIT32(p, f->msize);
                p += BIT32SZ;
                p = pstring(p, f->version);
                break;

        case Tflush:
                PBIT16(p, f->oldtag);
                p += BIT16SZ;
                break;

        case Tauth:
                PBIT32(p, f->afid);
                p += BIT32SZ;
                p  = pstring(p, f->uname);
                p  = pstring(p, f->aname);
                break;

        case Tattach:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT32(p, f->afid);
                p += BIT32SZ;
                p  = pstring(p, f->uname);
                p  = pstring(p, f->aname);
                break;

        case Twalk:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT32(p, f->newfid);
                p += BIT32SZ;
                PBIT16(p, f->nwname);
                p += BIT16SZ;
                if(f->nwname > MAXWELEM)
                        return 0;
                for(i=0; i<f->nwname; i++)
                        p = pstring(p, f->wname[i]);
                break;

        case Topen:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT8(p, f->mode);
                p += BIT8SZ;
                break;

        case Tcreate:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                p = pstring(p, f->name);
                PBIT32(p, f->perm);
                p += BIT32SZ;
                PBIT8(p, f->mode);
                p += BIT8SZ;
                break;

        case Tread:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT64(p, f->offset);
                p += BIT64SZ;
                PBIT32(p, f->count);
                p += BIT32SZ;
                break;

        case Twrite:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT64(p, f->offset);
                p += BIT64SZ;
                PBIT32(p, f->count);
                p += BIT32SZ;
                memmove(p, f->data, f->count);
                p += f->count;
                break;

        case Tclunk:
        case Tremove:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                break;

        case Tstat:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                break;

        case Twstat:
                PBIT32(p, f->fid);
                p += BIT32SZ;
                PBIT16(p, f->nstat);
                p += BIT16SZ;
                memmove(p, f->stat, f->nstat);
                p += f->nstat;
                break;
/*
 */

        case Rversion:
                PBIT32(p, f->msize);
                p += BIT32SZ;
                p = pstring(p, f->version);
                break;

        case Rerror:
                p = pstring(p, f->ename);
                break;

        case Rflush:
                break;

        case Rauth:
                p = pqid(p, &f->aqid);
                break;

        case Rattach:
                p = pqid(p, &f->qid);
                break;

        case Rwalk:
                PBIT16(p, f->nwqid);
                p += BIT16SZ;
                if(f->nwqid > MAXWELEM)
                        return 0;
                for(i=0; i<f->nwqid; i++)
                        p = pqid(p, &f->wqid[i]);
                break;

        case Ropen:
        case Rcreate:
                p = pqid(p, &f->qid);
                PBIT32(p, f->iounit);
                p += BIT32SZ;
                break;

        case Rread:
                PBIT32(p, f->count);
                p += BIT32SZ;
                memmove(p, f->data, f->count);
                p += f->count;
                break;

        case Rwrite:
                PBIT32(p, f->count);
                p += BIT32SZ;
                break;

        case Rclunk:
                break;

        case Rremove:
                break;

        case Rstat:
                PBIT16(p, f->nstat);
                p += BIT16SZ;
                memmove(p, f->stat, f->nstat);
                p += f->nstat;
                break;

        case Rwstat:
                break;
        }
        if(size != p-ap)
                return 0;
        return size;
}