Exemplo n.º 1
0
static size_t
maxindexfor(OCnode* node, OCmode srcmode)
{
    switch (srcmode) {
    case Dimmode:
	if(node->octype == OC_Sequence) return 0;
	if(node->octype == OC_Primitive) return 1;
	return oclistlength(node->subnodes);

    case Recordmode:
	if(node->array.rank > 0) return totaldimsize(node);
	if(node->octype == OC_Primitive) return 1;
	return oclistlength(node->subnodes);

    case Datamode:
	return 1;

    case Nullmode:
    case Fieldmode:
	if(node->array.rank > 0) return totaldimsize(node);
	if(node->octype == OC_Primitive) return 1;
	if(node->octype == OC_Sequence) return 0;
	return oclistlength(node->subnodes);

    case Emptymode:
    default:
        OCPANIC1("No defined mode transition: %d",(int)srcmode);
	break;
    }
    return oclistlength(node->subnodes);
}
Exemplo n.º 2
0
static OCmode
modetransition(OCnode* node, OCmode srcmode)
{
    switch (srcmode) {
    case Dimmode:
	if(node->octype == OC_Sequence) return Recordmode;
	if(node->octype == OC_Primitive) return Datamode;
	return Fieldmode;

    case Recordmode:
	if(node->array.rank > 0) return Dimmode;
	if(node->octype == OC_Primitive) return Datamode;
	return Fieldmode;

    case Datamode:
	return Datamode;

    case Nullmode:
    case Fieldmode:
	if(node->array.rank > 0) return Dimmode;
	if(node->octype == OC_Primitive) return Datamode;
	if(node->octype == OC_Sequence) return Recordmode;
	return Fieldmode;

    case Emptymode:
    default:
        OCPANIC1("No defined mode transition: %d",(int)srcmode);
	break;
    }
    return Fieldmode;
}
Exemplo n.º 3
0
static OCerror
occorrelater(OCnode* dds, OCnode* dxd)
{
    int i,j;
    OCerror ocstat = OC_NOERR;

    if(dds->octype != dxd->octype) {
	THROWCHK((ocstat = OC_EINVAL)); goto fail;
    }
    if(dxd->name != NULL && dxd->name != NULL
       && strcmp(dxd->name,dds->name) != 0) {
	THROWCHK((ocstat = OC_EINVAL)); goto fail;
    } else if(dxd->name != dxd->name) { /* test NULL==NULL */
	THROWCHK((ocstat = OC_EINVAL)); goto fail;
    }

    if(dxd->array.rank != dds->array.rank) {
	THROWCHK((ocstat = OC_EINVAL)); goto fail;
    }

    dds->datadds = dxd;

    switch (dds->octype) {
    case OC_Dataset:
    case OC_Structure:
    case OC_Grid:
    case OC_Sequence:
	/* Remember: there may be fewer datadds fields than dds fields */
	for(i=0;i<oclistlength(dxd->subnodes);i++) {
	    OCnode* dxd1 = (OCnode*)oclistget(dxd->subnodes,i);
	    for(j=0;j<oclistlength(dds->subnodes);j++) {
		OCnode* dds1 = (OCnode*)oclistget(dds->subnodes,j);
		if(strcmp(dxd1->name,dds1->name) == 0) {
		    ocstat = occorrelater(dds1,dxd1);
		    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
		    break;
		}
	    }
	}
	break;
    case OC_Dimension:
    case OC_Primitive:
	break;
    default: OCPANIC1("unexpected node type: %d",dds->octype);
    }
    /* Correlate the dimensions */
    if(dds->array.rank > 0) {
	for(i=0;i<oclistlength(dxd->subnodes);i++) {
	    OCnode* ddsdim = (OCnode*)oclistget(dds->array.dimensions,i);
	    OCnode* dxddim = (OCnode*)oclistget(dxd->array.dimensions,i);
	    ocstat = occorrelater(ddsdim,dxddim);
	    if(!ocstat) goto fail;	    
	}	
    }

fail:
    return THROW(ocstat);

}
Exemplo n.º 4
0
static int
ocgetmemdata(OCstate* state, OCcontent* content, void* memory, size_t memsize,
             size_t start, size_t count)
{
    OCmemdata* md = content->memdata;
    unsigned short* d16;
    unsigned int* d32;
#ifdef HAVE_LONG_LONG_INT
    unsigned long long* d64;
#endif
    char* dchar;
    char** dstring;
    size_t totalsize;
    size_t elemsize;
    OCtype etype;

    /* Validate the etypes */
    etype = content->node->etype;
    if(etype != md->etype) return OCTHROW(OC_EINVAL);

    elemsize = octypesize(etype);
    totalsize = elemsize*count;

    switch (etype) {
    case OC_Char: case OC_Byte: case OC_UByte:
	dchar = (char*)md->data.data;
	memcpy((void*)memory,(void*)(dchar+start),totalsize);
	break;
    case OC_Int16: case OC_UInt16:
	d16 = (unsigned short*)md->data.data;
	memcpy((void*)memory,(void*)(d16+start),totalsize);	    
	break;
    case OC_Int32: case OC_UInt32: case OC_Float32:
	d32 = (unsigned int*)md->data.data;
	memcpy((void*)memory,(void*)(d32+start),totalsize);
	break;
#ifdef HAVE_LONG_LONG_INT
    case OC_Int64: case OC_UInt64: case OC_Float64:
	d64 = (unsigned long long*)md->data.data;
	memcpy((void*)memory,(void*)(d64+start),totalsize);	    
	break;
#endif
    case OC_String: case OC_URL: {
	unsigned int i;
	char** memstrings = (char**)memory;
	dstring = (char**)md->data.data;
	for(i=0;i<count;i++) {
	    memstrings[i] = nulldup(dstring[start+i]);
	}
	} break;
    default: OCPANIC1("unexpected etype: %d",content->node->etype);
    }
    return OCTHROW(OC_NOERR);
}
static int
occompile1(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs)
{
    unsigned int i,j,xdrcount;
    int stat = OC_NOERR;
    size_t nelements;
    OCmemdata* memdata = NULL;
    OCmemdata* structdata = NULL;
    OClist* records = NULL;
    OCerror ocstat = OC_NOERR;
    OCmemdata** pmem = NULL;


    /* Allocate the space for this memdata chunk */
    switch (xnode->octype) {

    case OC_Dataset:
    case OC_Grid:
    case OC_Structure: {
	if(xnode->array.rank == 0) {
	    ocstat = occompilefields(state,xnode,&memdata,xdrs);
	    if(ocstat != OC_NOERR) goto fail;
	} else { /* rank > 0 */
	    /* Compute the actual index count after projections */
	    nelements = totaldimsize(xnode);
	    if(nelements == 0) return THROW(OC_ENODATA);
	    memdata = makememdata(xnode->octype,OC_NAT,nelements);
	    MEMCHECK(memdata,OC_ENOMEM);
	    memdata->mode = Dimmode;
	    pmem = (OCmemdata**)&memdata->data;
	    /* Consume the leading count field */
	    if(!xdr_u_int(xdrs,&xdrcount)) {stat = OC_EXDR; goto fail;}
	    /* validate the datadds dimensions */
	    if(xdrcount != nelements) {stat=OC_EINVALCOORDS; goto fail;}
            for(i=0;i<nelements;i++) {
		ocstat = occompilefields(state,xnode,&structdata,xdrs);
		if(ocstat != OC_NOERR) {
		    if(ocstat != OC_ENODATA) goto fail;
		    structdata = NULL; /* Leave a hole for this element */
		}
	        pmem[i] = structdata;
	        structdata = NULL;
	    }
	}
    } break;

    case OC_Sequence:{
	/* Since we do not know the # records beforehand,
           use a oclist to collect the record instances.
           Query: this stores by recor (where e.g. original ocapi
           stores by column). How hard would it be to make the
           storage choice conditional on some user defined flag?
        */
	records = oclistnew();
	for(;;) {
            /* pick up the sequence record begin marker*/
            char tmp[sizeof(unsigned int)];
            /* extract the tag byte*/
	    if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) {stat = OC_EXDR; goto fail;}
            if(tmp[0] == StartOfoclist) { /* Walk each member field*/
		ocstat = occompilefields(state,xnode,&structdata,xdrs);
		if(ocstat != OC_NOERR) goto fail;
		oclistpush(records,(ocelem)structdata);
		structdata = NULL;
            } else if(tmp[0] == EndOfoclist) {
                break; /* we are done with the this sequence instance*/
            } else {
		oc_log(LOGERR,"missing/invalid begin/end record marker\n");
                stat = OC_EINVALCOORDS;
		goto fail;
            }
	}
	/* Convert the list to a proper OCmemdata */
	nelements = oclistlength(records);
	memdata = makememdata(xnode->octype,OC_NAT,nelements);
	MEMCHECK(memdata,OC_ENOMEM);
	memdata->mode = Recordmode;
	pmem = (OCmemdata**)&memdata->data;
	for(j=0;j<nelements;j++) {
	    OCmemdata* record = (OCmemdata*)oclistget(records,j);
	    pmem[j] = record;
	}
	oclistfree(records);	    
	records = NULL;
    } break;

    case OC_Primitive:
	ocstat = occompileprim(state,xnode,&memdata,xdrs);
	if(ocstat != OC_NOERR) goto fail;
	break;

    default: OCPANIC1("ocmap: encountered unexpected node type: %x",xnode->octype);
        break;
    }

/*ok:*/
    if(memdatap) *memdatap = memdata;
    return THROW(ocstat);    

fail:
    if(records != NULL) for(i=0;i<oclistlength(records);i++)
	freeocmemdata((OCmemdata*)oclistget(records,i));
    freeocmemdata(memdata);
    freeocmemdata(structdata);
    return THROW(ocstat);
}
static int
occompileprim(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs)
{
    unsigned int xdrcount,i;
    size_t nelements = 0;
    OCerror ocstat = OC_NOERR;
    OCmemdata* memdata = NULL;
    
    OCASSERT((xnode->octype == OC_Primitive));

    /* Use the count from the datadds */
    nelements = totaldimsize(xnode);

    if(xnode->array.rank > 0) {
        /* Get first copy of the dimension count */
        if(!xdr_u_int(xdrs,&xdrcount)) {ocstat = OC_EXDR; goto fail;}
        if(xdrcount != nelements) {ocstat=OC_EINVALCOORDS; goto fail;}
        if(xnode->etype != OC_String && xnode->etype != OC_URL) {
            /* Get second copy of the dimension count */
            if(!xdr_u_int(xdrs,&xdrcount)) {ocstat = OC_EXDR; goto fail;}
            if(xdrcount != nelements) {ocstat=OC_EINVALCOORDS; goto fail;}
        }
    } else {
	nelements = 1;
	xdrcount = 1;
    }

    memdata = makememdata(xnode->octype,xnode->etype,nelements);
    MEMCHECK(memdata,OC_ENOMEM);
    memdata->mode = (xnode->array.rank > 0?Dimmode:Datamode);

    switch (xnode->etype) {

    case OC_String: case OC_URL: {/* Get the array of strings and store pointers in buf */
	char** dst = (char**)memdata->data.data;
        for(i=0;i<xdrcount;i++) {
            char* s = NULL;
            if(!xdr_string(xdrs,(void*)&s,OC_INT32_MAX)) {ocstat = OC_EXDR; goto fail;}
	    dst[i] = s;
        }
    } break;

    case OC_Byte:
    case OC_UByte:
    case OC_Char: {
        if(xnode->array.rank == 0) { /* Single unpacked character/byte */
            union {unsigned int i; char c[BYTES_PER_XDR_UNIT];} u;
            if(!xdr_opaque(xdrs,u.c,BYTES_PER_XDR_UNIT)) {ocstat = OC_EXDR; goto fail;}
            u.i = ocntoh(u.i);
	    memdata->data.data[0] = (char)u.i;
        } else { /* Packed characters; count will have already been read */
            char* dst = memdata->data.data;
            if(!xdr_opaque(xdrs,dst,xdrcount)) {ocstat = OC_EXDR; goto fail;}
        }
    } break;        

    case OC_Int16: case OC_UInt16: {
        unsigned short* dst = (unsigned short*)memdata->data.data;
        unsigned int* src;
        size_t xdrsize = xdrcount*BYTES_PER_XDR_UNIT;
        src = (unsigned int*)ocmalloc(xdrsize);
        if(!xdr_opaque(xdrs,(char*)src,xdrsize)) {ocfree(src); ocstat = OC_EXDR; goto fail;}
	if(!oc_network_order) {
            for(i=0;i<xdrcount;i++) { /* Write in place */
                unsigned int hostint = src[i];
		swapinline(dst[i],hostint);
	    }
        }
        ocfree(src);
    } break;

    case OC_Int32: case OC_UInt32:
    case OC_Float32: {
        unsigned int* dst = (unsigned int*)memdata->data.data;
        size_t xdrsize = xdrcount*BYTES_PER_XDR_UNIT;
        if(!xdr_opaque(xdrs,(char*)dst,xdrsize)) {ocstat = OC_EXDR; goto fail;}
	if(!oc_network_order) {
            for(i=0;i<xdrcount;i++) {
                unsigned int hostint = dst[i];
		swapinline(dst[i],hostint);
	    }
	}
    } break;
        
    case OC_Int64: case OC_UInt64:
    case OC_Float64: {
        unsigned int* dst = (unsigned int*)memdata->data.data;
        size_t xdrsize = 2*xdrcount*BYTES_PER_XDR_UNIT;
        if(!xdr_opaque(xdrs,(char*)dst,xdrsize)) {ocstat = OC_EXDR; goto fail;}
	if(!oc_network_order) {
            for(i=0;i<2*xdrcount;i++) {
                unsigned int hostint = dst[i];
		swapinline(dst[i],hostint);
	    }
	}
        if(oc_invert_xdr_double) { /* May need to invert each pair */
            for(i=0;i<2*xdrcount;i+=2) {
                unsigned int tmp = dst[i];
                dst[i] = dst[i+1];
                dst[i+1] = tmp;
            }
        }
    } break;

    default: OCPANIC1("unexpected etype: %d",xnode->etype);
    } /* switch */

/*ok:*/
    if(memdatap) *memdatap = memdata;
    return THROW(ocstat);

fail:
    freeocmemdata(memdata);
    return THROW(ocstat);
}
Exemplo n.º 7
0
static void
dumpocnode1(OCnode* node, int depth)
{
    unsigned int n;
    switch (node->octype) {
    case OC_Atomic: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	if(node->name == NULL) OCPANIC("prim without name");
	fprintf(stdout,"%s %s",octypetostring(node->etype),node->name);
	dumpdimensions(node);
	fprintf(stdout," &%lx",(unsigned long)node);
	fprintf(stdout,"\n");
    } break;

    case OC_Dataset: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	fprintf(stdout,"dataset %s\n",
		(node->name?node->name:""));
	for(n=0;n<oclistlength(node->subnodes);n++) {
	    dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
	}
    } break;

    case OC_Structure: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	fprintf(stdout,"struct %s",
		(node->name?node->name:""));
	dumpdimensions(node);
	fprintf(stdout," &%lx",(unsigned long)node);
	fprintf(stdout,"\n");
	for(n=0;n<oclistlength(node->subnodes);n++) {
	    dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
	}
    } break;

    case OC_Sequence: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	fprintf(stdout,"sequence %s",
		(node->name?node->name:""));
	dumpdimensions(node);
	fprintf(stdout," &%lx",(unsigned long)node);
	fprintf(stdout,"\n");
	for(n=0;n<oclistlength(node->subnodes);n++) {
	    dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
	}
    } break;

    case OC_Grid: {
	unsigned int i;
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	fprintf(stdout,"grid %s",
		(node->name?node->name:""));
	dumpdimensions(node);
	fprintf(stdout," &%lx",(unsigned long)node);
	fprintf(stdout,"\n");
	fprintf(stdout,"%sarray:\n",dent2(depth+1));
	dumpocnode1((OCnode*)oclistget(node->subnodes,0),depth+2);
	fprintf(stdout,"%smaps:\n",dent2(depth+1));
	for(i=1;i<oclistlength(node->subnodes);i++) {
	    dumpocnode1((OCnode*)oclistget(node->subnodes,i),depth+2);
	}
    } break;

    case OC_Attribute: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	if(node->name == NULL) OCPANIC("Attribute without name");
	fprintf(stdout,"%s %s",octypetostring(node->etype),node->name);
	for(n=0;n<oclistlength(node->att.values);n++) {
	    char* value = (char*)oclistget(node->att.values,n);
	    if(n > 0) fprintf(stdout,",");
	    fprintf(stdout," %s",value);
	}
	fprintf(stdout," &%lx",(unsigned long)node);
	fprintf(stdout,"\n");
    } break;

    case OC_Attributeset: {
        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
	fprintf(stdout,"%s:\n",node->name?node->name:"Attributes");
	for(n=0;n<oclistlength(node->subnodes);n++) {
	    dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
	}
    } break;

    default:
	OCPANIC1("encountered unexpected node type: %x",node->octype);
    }

    if(node->attributes != NULL) {
	unsigned int i;
	for(i=0;i<oclistlength(node->attributes);i++) {
	    OCattribute* att = (OCattribute*)oclistget(node->attributes,i);
	    fprintf(stdout,"%s[%s=",dent2(depth+2),att->name);
	    if(att->nvalues == 0)
		OCPANIC("Attribute.nvalues == 0");
	    if(att->nvalues == 1) {
		dumpattvalue(att->etype,att->values,0);
	    } else {
		unsigned int j;
	        fprintf(stdout,"{");
		for(j=0;j<att->nvalues;j++) {
		    if(j>0) fprintf(stdout,", ");
		    dumpattvalue(att->etype,att->values,j);
		}
	        fprintf(stdout,"}");
	    }
	    fprintf(stdout,"]\n");
	}
    }
}
Exemplo n.º 8
0
/* Skip arbitrary dimensioned instance; handles dimensioning.*/
int
ocskip(OCnode* node, XDR* xdrs)
{
    unsigned int i,j,rank;
    int stat = OC_NOERR;
    unsigned int xdrcount;
    unsigned int len;

    switch (node->octype) {
        case OC_Primitive:
            /* handle non-uniform types separately*/
            if(node->etype == OC_String || node->etype == OC_URL) {
                rank = node->array.rank;
        	xdrcount = 1;
                if(rank > 0 && !xdr_u_int(xdrs,&xdrcount)) return xdrerror();
                len = xdrcount;
        	for(i=0;i<xdrcount;i++) {
                    if(!xdr_u_int(xdrs,&len)) return xdrerror();
        	    if(!xdr_skip(xdrs,len)) return xdrerror();
        	}
            } else { /* uniform => do a direct skip*/
        	OCASSERT((node->dap.arraysize > 0
                          && node->dap.instancesize > 0));
		if(node->array.rank > 0) {
        	    if(!xdr_skip(xdrs,node->dap.arraysize)) return xdrerror();
		} else {
        	    if(!xdr_skip(xdrs,node->dap.instancesize)) return xdrerror();
		}
            }
	    break;

        case OC_Grid:
	    OCASSERT((node->array.rank == 0));
            if(node->dap.instancesize > 0) { /* do a direct skip*/
                if(!xdr_skip(xdrs,node->dap.arraysize)) return xdrerror();
		break;
            } else { /* Non-uniform size*/
                /* Walk array and maps*/
                for(j=0;j<oclistlength(node->subnodes);j++) {
                    OCnode* field = (OCnode*)oclistget(node->subnodes,j);
                    stat = ocskip(field,xdrs);
                    if(stat != OC_NOERR) {THROWCHK(stat); break;}
                }
                if(stat != OC_NOERR) {THROWCHK(stat); break;}
	    }
	    break;

	case OC_Dataset:
            OCASSERT((node->array.rank == 0));
	    /* fall-thru*/
        case OC_Structure:
            if(node->dap.instancesize > 0) { /* do a direct skip*/
                if(!xdr_skip(xdrs,node->dap.arraysize)) return xdrerror();
            } else {
                /* Non-uniform size, we have to skip element by element*/
                rank = node->array.rank;
                xdrcount = 1;
                if(rank > 0 && !xdr_u_int(xdrs,&xdrcount)) return xdrerror();
                for(i=0;i<xdrcount;i++) { /* skip element by element*/
                    /* Walk each structure field*/
                    for(j=0;j<oclistlength(node->subnodes);j++) {
                        OCnode* field = (OCnode*)oclistget(node->subnodes,j);
                        stat = ocskip(field,xdrs);
                        if(stat != OC_NOERR) {THROWCHK(stat); break;}
                    }
                    if(stat != OC_NOERR) {THROWCHK(stat); break;}
                }
	    }
	    break;

        case OC_Sequence: /* not uniform, so walk record by record*/
	    OCASSERT((node->array.rank == 0));
            for(;;) {
                /* pick up the sequence record begin marker*/
                char tmp[sizeof(unsigned int)];
                /* extract the tag byte*/
                if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror();
                if(tmp[0] == StartOfoclist) {
                    /* Walk each member field*/
                    for(j=0;j<oclistlength(node->subnodes);j++) {
                        OCnode* member = (OCnode*)oclistget(node->subnodes,j);
                        stat = ocskip(member,xdrs);
                        if(stat != OC_NOERR) {THROWCHK(stat); break;}
                    }
                } else if(tmp[0] == EndOfoclist) {
                    break; /* we are done with the this sequence instance*/
                } else {
                    oc_log(LOGERR,"missing/invalid begin/end record marker\n");
                    stat = OC_EINVALCOORDS;
                    {THROWCHK(stat); break;}
                }
                if(stat != OC_NOERR) {THROWCHK(stat); break;}
            }
            break;

        default:
	    OCPANIC1("oc_move: encountered unexpected node type: %x",node->octype);
	    break;
    }
    return THROW(stat);
}
Exemplo n.º 9
0
/* Skip arbitrary single instance; except for primitives
   Assumes that parent will handle arrays of compound instances
   or records of compound instances of this node type
   Specifically, all array counts have been absorbed by some parent caller.*/
int
ocskipinstance(OCnode* node, XDR* xdrs)
{
    unsigned int i;
    int stat = OC_NOERR;
    unsigned int xdrcount;

#if 0
    unsigned int j,rank;

    switch (node->octype) {
	case OC_Dataset:
        case OC_Grid:
	    OCASSERT((node->array.rank == 0));
	    stat = ocskip(node,xdrs);
	    break;

        case OC_Sequence: /* instance is essentially same a structure */
        case OC_Structure:
            if(node->dap.instancesize > 0) { /* do a direct skip*/
                if(!xdr_skip(xdrs,node->dap.instancesize)) return xdrerror();
            } else {
                /* Non-uniform size, we have to skip field by field*/
                /* Walk each structure/sequence field*/
                for(j=0;j<oclistlength(node->subnodes);j++) {
                    OCnode* field = (OCnode*)oclistget(node->subnodes,j);
                    stat = ocskip(field,xdrs);
                    if(stat != OC_NOERR) break;
                }
                if(stat != OC_NOERR) break;
	    }
	    break;
	case OC_Primitive:
	    if(node->etype == OC_String || node->etype == OC_URL) {
                if(!xdr_u_int(xdrs,&xdrcount)) return xdrerror();
		if(!xdr_skip(xdrs,xdrcount)) return xdrerror();
	    } else {
	        OCASSERT((node->dap.instancesize > 0));
                if(!xdr_skip(xdrs,node->dap.instancesize)) return xdrerror();
	    }
	    break;

        default:
	    OCPANIC1("oc_move: encountered unexpected node type: %x",node->octype);
	    break;
    }
#else
    if(node->dap.instancesize > 0) { /* do a direct skip*/
        if(!xdr_skip(xdrs,node->dap.instancesize)) return xdrerror();
    } else if(node->octype == OC_Primitive) {
	OCASSERT((node->etype == OC_String || node->etype == OC_URL));
        if(!xdr_u_int(xdrs,&xdrcount)) return xdrerror();
	if(!xdr_skip(xdrs,xdrcount)) return xdrerror();
    } else {
        /* Non-uniform size Grid/Sequence/Structure/Dataset;*/
        /* we have to skip field by field*/
        for(i=0;i<oclistlength(node->subnodes);i++) {
            OCnode* field = (OCnode*)oclistget(node->subnodes,i);
            stat = ocskip(field,xdrs);
            if(stat != OC_NOERR) break;
        }
    }
#endif
    return THROW(stat);
}
Exemplo n.º 10
0
/* For those nodes that are uniform in size, compute size
   size of the node*/
size_t
ocsetsize(OCnode* node)
{
    size_t count, subnodesum;
    unsigned int i;
    int isscalar = (node->array.rank == 0);
    size_t instancesize;
    size_t dimsize; /* to give to parent*/

    instancesize = 0; /* assume not uniform*/
    dimsize = 0;

    /* compute total # of elements if dimensioned*/
    count = 1;
    for(i=0;i<node->array.rank;i++) {
	OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i);
	count *= (dim->dim.declsize);
    }

    /* Recursively compute sizes of subnodes, if any*/
    subnodesum = 0;
    if(node->subnodes != NULL) {
	int nonuniform = 0;
        for(i=0;i<oclistlength(node->subnodes);i++) {
	    OCnode* subnode = (OCnode*)oclistget(node->subnodes,i);
	    size_t subsize = ocsetsize(subnode); /* includes subnode dimension counts*/
	    if(subsize == 0) nonuniform = 1;
	    subnodesum += subsize;
	}
	if(nonuniform) subnodesum = 0;
    }

    switch (node->octype) {
        case OC_Primitive:
	    switch (node->etype) {
	    case OC_String: case OC_URL: /* not uniform*/
		instancesize = 0;
		dimsize = 0; /* not uniform*/
		break; /* not uniform*/
	    case OC_Byte:
	    case OC_UByte:
	    case OC_Char:
		instancesize = (isscalar?BYTES_PER_XDR_UNIT:1);
	        dimsize = instancesize;
		/* We have to watch out for the fact that packed instances have padding in the xdr packet*/
		if(!isscalar) { /* padding to multiple of BYTE_PER_XDR_UNIT*/
		    unsigned int rem;
	            dimsize = count*instancesize;
		    rem = (dimsize % BYTES_PER_XDR_UNIT);
		    if(rem > 0) dimsize += (BYTES_PER_XDR_UNIT - rem);
		    dimsize += 2*BYTES_PER_XDR_UNIT; /* the dimension counts (repeated)*/
		}
		break;
	    case OC_Float64:
	    case OC_Int64:
	    case OC_UInt64:
		instancesize = (2*BYTES_PER_XDR_UNIT); /*double = 2 xdr units*/
	        dimsize = count*instancesize + (isscalar?0:2*BYTES_PER_XDR_UNIT);
		break;
	    default:
		instancesize = (BYTES_PER_XDR_UNIT); /* all others: 1 xdr unit*/
	        dimsize = count*instancesize + (isscalar?0:2*BYTES_PER_XDR_UNIT);
		break;
	    }
	    break;

        case OC_Sequence: /* never uniform, but instances may be*/
	    dimsize = 0;
	    instancesize = subnodesum;
	    break;

        case OC_Grid:
	case OC_Dataset:
        case OC_Structure:
	    instancesize = subnodesum;
	    dimsize = count*instancesize + (isscalar?0:BYTES_PER_XDR_UNIT);
	    break;

        default: OCPANIC1("ocmap: encountered unexpected node type: %x",node->octype);
	    break;
    }
    node->dap.instancesize = instancesize;
    node->dap.arraysize = dimsize;
    return dimsize;
}