Пример #1
0
/* DRNO need to explicitly get and walk string values*/
int
oc_stringcontent(OCstate* state, OCcontent* content, char** stringp, size_t* slenp)
{
    int stat = OC_NOERR;
    XDR* xdrs;
    unsigned int slen;
    char* stringmemory;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);

    if(content->node->octype != OC_Primitive) return OCTHROW(OC_EINVAL);
    if(content->node->etype != OC_String
            && content->node->etype != OC_URL) return OCTHROW(OC_EINVAL);

    xdrs = state->dap.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    if(oc_contentmode(state,content) != Datamode) return OCTHROW(OC_EINVAL);
    /* We are at a single instance of a string data type*/
    if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror();
    if(!xdr_u_int(xdrs,&slen)) return xdrerror();
    stringmemory = (char*)ocmalloc(slen+1);
    MEMCHECK(stringmemory,OC_ENOMEM);
    if(!xdr_opaque(xdrs,stringmemory,slen)) return xdrerror();
    stringmemory[slen] = '\0';
    /* restore location*/
    if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror();
    if(stringp != NULL) *stringp = stringmemory;
    if(slenp != NULL) *slenp = slen;
    return OCTHROW(stat);
}
Пример #2
0
int
countrecords(OCnode* node, XDR* xdrs, size_t* nrecordsp)
{
    int stat = OC_NOERR;
    size_t nrecords = 0;
    unsigned int xdroffset;
    if(node->octype != OC_Sequence) return THROW(OC_EINVAL);
    /* checkpoint the xdr position*/
    xdroffset = xdr_getpos(xdrs);
    for(;;) { unsigned int i;
        /* 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(i=0;i<oclistlength(node->subnodes);i++) {
                OCnode* member = (OCnode*)oclistget(node->subnodes,i);
                stat = ocskip(member,xdrs);
                if(stat != OC_NOERR) break;
            }
	    nrecords++;
        } 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;
            break;
        }
        if(stat != OC_NOERR) break;
    }
    /* move to checkpoint position*/
    if(!xdr_setpos(xdrs,xdroffset)) return xdrerror();
    if(nrecordsp != NULL) *nrecordsp = nrecords;
    return THROW(stat);
}
OCerror
ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCnode** rootp)
{
    OCtree* tree = NULL;
    OCnode* root = NULL;
    OCerror stat = OC_NOERR;
    
    tree = (OCtree*)ocmalloc(sizeof(OCtree));
    MEMCHECK(tree,OC_ENOMEM);
    memset((void*)tree,0,sizeof(OCtree));
    tree->dxdclass = kind;
    tree->state = state;
    tree->constraint = constraintescape(constraint);
    if(tree->constraint == NULL)
	tree->constraint = nulldup(constraint);

    ocbytesclear(state->packet);

    switch (kind) {
    case OCDAS:
        stat = readDAS(state,tree);
	if(stat == OC_NOERR) {
            tree->text = ocbytesdup(state->packet);
	    if(tree->text == NULL) stat = OC_EDAS;
	}
	break;
    case OCDDS:
        stat = readDDS(state,tree);
	if(stat == OC_NOERR) {
            tree->text = ocbytesdup(state->packet);
	    if(tree->text == NULL) stat = OC_EDDS;
	}
	break;
    case OCDATADDS:
#ifdef OC_DISK_STORAGE
       /* Create the datadds file immediately
           so that DRNO can reference it*/
        /* Make the tmp file*/
        stat = createtempfile(state,tree);
        if(stat) {THROWCHK(stat); goto unwind;}
        stat = readDATADDS(state,tree);
	if(stat == OC_NOERR) {
            /* Separate the DDS from data and return the dds;
	       will modify packet */
            stat = ocextractdds(state,tree);
	}
#else
        stat = readDATADDS(state,tree);
	if(stat == OC_NOERR) {
            /* Separate the DDS from data*/
            stat = ocextractdds(state,tree);
	    tree->data.xdrdata = ocbytesdup(state->packet);
	}
#endif
	break;
    }
    if(stat != OC_NOERR) {
	/* Obtain any http code */
	state->error.httpcode = ocfetchhttpcode(state->curl);
	if(state->error.httpcode >= 400) {
	    oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode);
	} else {
	    oc_log(LOGWARN,"oc_open: Could not read url");
	}
	return THROW(stat);
    }

    tree->nodes = NULL;
    stat = DAPparse(state,tree,tree->text);
    /* Check and report on an error return from the server */
    if(stat == OC_EDAPSVC  && state->error.code != NULL) {
	oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"",
		  state->error.code,	
		  (state->error.message?state->error.message:""));
    }
    if(stat) {THROWCHK(stat); goto unwind;}
    root = tree->root;
    /* make sure */
    tree->root = root;
    root->tree = tree;

    /* Verify the parse */
    switch (kind) {
    case OCDAS:
        if(root->octype != OC_Attributeset)
	    {THROWCHK(stat=OC_EDAS); goto unwind;}
	break;
    case OCDDS:
        if(root->octype != OC_Dataset)
	    {THROWCHK(stat=OC_EDDS); goto unwind;}
	break;
    case OCDATADDS:
        if(root->octype != OC_Dataset)
	    {THROWCHK(stat=OC_EDATADDS); goto unwind;}
	/* Modify the tree kind */
	tree->dxdclass = OCDATADDS;
	break;
    default: return OC_EINVAL;
    }

    if(kind != OCDAS) {
        /* Process ocnodes to fix various semantic issues*/
        computeocsemantics(tree->nodes);
    }

    /* Process ocnodes to compute name info*/
    computeocfullnames(tree->root);

    if(kind != OCDAS) {
        /* Process ocnodes to compute sizes when uniform in size*/
        ocsetsize(tree->root);
    }

    if(kind == OCDATADDS) {
        tree->data.xdrs = (XDR*)ocmalloc(sizeof(XDR));
        MEMCHECK(tree->data.xdrs,OC_ENOMEM);
#ifdef OC_DISK_STORAGE
        ocxdrstdio_create(tree->data.xdrs,tree->data.file,XDR_DECODE);
#else
	xdrmem_create(tree->data.xdrs,tree->data.xdrdata,tree->data.datasize,XDR_DECODE);
#endif
        if(!xdr_setpos(tree->data.xdrs,tree->data.bod)) return xdrerror();
    }

#ifdef OC_DISK_STORAGE
    if(ocdebug == 0 && tree->data.filename != NULL) {
	unlink(tree->data.filename);
    }
#endif

    /* Put root into the state->trees list */
    oclistpush(state->trees,(ocelem)root);

    if(rootp) *rootp = root;
    return stat;

unwind:
    ocfreetree(tree);
    return THROW(stat);
}
Пример #4
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);
}
Пример #5
0
/*
Extract data from the xdr packet into a chunk of memory.
Normally, it is assumed that we are (at least virtually)
"at" a single instance in the xdr packet; which we read.
Virtually because for packed data, we need to point to
the beginning of the packed data and use the index to indicate
which packed element to get.
*/
int
ocxdrread(XDR* xdrs, char* memory, size_t memsize, int packed, OCtype octype, unsigned int start, size_t count)
{
    int stat = OC_NOERR;
    unsigned int i;
    size_t elemsize = octypesize(octype);
    char* localmem = NULL;
    char* startmem = NULL;
    size_t totalsize;
    size_t xdrsize;
    unsigned int xdrckp = xdr_getpos(xdrs);

    /* validate memory space*/
    totalsize = elemsize*count;
    if(memsize < totalsize) return THROW(OC_EINVAL);

    /* Handle packed data specially*/
    /* WARNING: assumes that the initial count has been read*/
    if(packed) {
        char tmp[LOCALMEMMAX];
	unsigned int readsize = start+count;
	if(readsize <= LOCALMEMMAX) /* avoid malloc/free for common case*/
	    localmem = tmp;
	else {
            localmem = (char*)ocmalloc(readsize);
	    MEMCHECK(localmem,OC_ENOMEM);
	}
	if(!xdr_opaque(xdrs,(char*)localmem,readsize)) return xdrerror();
	memcpy((void*)memory,(void*)(localmem+start),count);
	if(readsize > LOCALMEMMAX) ocfree(localmem);
	if(!xdr_setpos(xdrs,xdrckp)) return xdrerror(); /* revert to beginning*/
	return THROW(OC_NOERR);
    }

    /* Not packed: extract count items; use xdr_opaque to speed up*/
    if(octype == OC_String || octype == OC_URL) {
	/* do nothing here; handle below*/
    } else if(octype == OC_Float64
              || octype == OC_UInt64
              || octype == OC_Int64) {
	unsigned int* p;
        xdrsize = 2*(start+count)*BYTES_PER_XDR_UNIT;
        localmem = (char*)ocmalloc(xdrsize);
	startmem = localmem+(2*start*BYTES_PER_XDR_UNIT);
	MEMCHECK(localmem,OC_ENOMEM);
	if(!xdr_opaque(xdrs,(char*)localmem,xdrsize)) return xdrerror();
	if(!oc_network_order) {
	    for(p=(unsigned int*)startmem,i=0;i<2*count;i++,p++) {
		unsigned int swap = *p;
		swapinline(*p,swap);
	    }
	}
    } else {
	unsigned int* p;
        xdrsize = (start+count)*BYTES_PER_XDR_UNIT;
        localmem = (char*)ocmalloc(xdrsize);
	MEMCHECK(localmem,OC_ENOMEM);
	startmem = localmem+(start*BYTES_PER_XDR_UNIT);
	if(!xdr_opaque(xdrs,(char*)localmem,xdrsize)) return xdrerror();
	if(!oc_network_order) {
	    for(p=(unsigned int*)startmem,i=0;i<count;i++,p++) {
		unsigned int swap = *p;
		swapinline(*p,swap);
	    }
	}
    }

    switch (octype) {

    case OC_Char: case OC_Byte: case OC_UByte: {
	char* pmem = (char*)memory;
	unsigned int* p = (unsigned int*)startmem;
	for(i=0;i<count;i++) {*pmem++ = (char)(*p++);}
	} break;

    case OC_Int16: case OC_UInt16: {
	unsigned short* pmem = (unsigned short*)memory;
	unsigned int* p = (unsigned int*)startmem;
	for(i=0;i<count;i++) {*pmem++ = (unsigned short)(*p++);}
	} break;

    case OC_Int32: case OC_UInt32: {
	memcpy((void*)memory,(void*)startmem,count*sizeof(unsigned int));
	} break;

    case OC_Float32: {
	memcpy((void*)memory,(void*)startmem,count*sizeof(float));
	} break;

    case OC_Int64: case OC_UInt64: case OC_Float64: {
	unsigned int* p;
	unsigned int* pmem = (unsigned int*)memory;
	/* Sometimes need to invert order*/
	for(p=(unsigned int*)startmem,i=0;i<count;i++) {
	    if(oc_invert_xdr_double) {
	        pmem[1] = (unsigned int)(*p++);
	        pmem[0] = (unsigned int)(*p++);
	    } else {
	        pmem[0] = (unsigned int)(*p++);
	        pmem[1] = (unsigned int)(*p++);
	    }
	    pmem += 2;
	}
	} break;

    case OC_String: case OC_URL: {
        char* s = NULL;
	char** pmem = (char**)memory;
	/* First skip to the starting string */
	for(i=0;i<start;i++) {
	    s = NULL; /* make xdr_string alloc the space */
            if(!xdr_string(xdrs,&s,OC_INT32_MAX)) return xdrerror();
	    ocfree(s);
        }
	/* Read count strings */
	for(i=0;i<count;i++) {
	    s = NULL; /* make xdr_string alloc the space */	
            if(!xdr_string(xdrs,&s,OC_INT32_MAX)) return xdrerror();
	    pmem[i] = s;
	}
	} break;

    default: return THROW(OC_EINVAL);
    }
    ocfree(localmem);
    if(!xdr_setpos(xdrs,xdrckp)) return xdrerror(); /* revert to beginning*/
    return THROW(stat);
}
Пример #6
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);
}
Пример #7
0
/* Remember: we are operating wrt the datadds count, not the dds count */
int
ocarraycontent(OCstate* state, OCcontent* content, OCcontent* newcontent, size_t index)
{
    unsigned int i;
    int stat = OC_NOERR;
    XDR* xdrs;
    unsigned int xdrcount;
    int packed;
    OCtype etype,octype;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);
    if(content->mode != Dimmode) return OCTHROW(OC_EINVAL);
    if(content->node->array.rank == 0) return OCTHROW(OC_EINVAL);

    etype = content->node->etype;
    octype = content->node->octype;

    if(content->maxindex > 0 && content->maxindex <= index)
	return OCTHROW(OC_EINVALCOORDS);
    content->index = index; /* Track our location in parent content */

    /* check if the data is packed*/
    packed = (octype == OC_Primitive &&
              (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    ocresetcontent(state,newcontent);
    /* Set the some of the new content*/
    newcontent->state = state; /* make sure*/
    newcontent->tree = content->tree;
    newcontent->node = content->node; /* keep same node*/
    newcontent->packed = packed;
    newcontent->mode = modetransition(newcontent->node, content->mode);
    newcontent->index = 0;
    newcontent->maxindex = maxindexfor(newcontent->node, content->mode);

    if(content->memdata != NULL) { /* Get data from the compiled version */
        OCASSERT((content->memdata->mode == Dimmode));
        /* Leave the primitive alone to be picked up by oc_getcontent */
	if(octype != OC_Primitive) {
   	    OCmemdata* next;
	    OCASSERT((octype == OC_Structure));
  	    if(content->memdata->count <= index) return OCTHROW(OC_ENODATA);
   	    next = ((OCmemdata**)content->memdata->data.data)[index];
	    newcontent->memdata = next;
	} else
	    newcontent->memdata = content->memdata; /* use same memdata */
	goto done;
    }

    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* checkpoint the beginning of this instance*/
    if(!content->xdrpos.valid) {
	content->xdrpos.offset = xdr_getpos(xdrs);
	content->xdrpos.valid = 1;
    }
    /* move to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

    /* Collect the dimension count from the xdr data packet*/
    if(!xdr_u_int(xdrs,&xdrcount)) return xdrerror();
    if(xdrcount < index) return OCTHROW(OC_ENODATA);

    /* pull out redundant second count*/
    /* (note that String/URL do not redundant count)*/
    if(octype == OC_Primitive && etype != OC_String && etype != OC_URL) {
        if(!xdr_u_int(xdrs,&xdrcount)) return xdrerror();
    }

    /* We have to treat OC_Byte/UByte/Char specially*/
    /* because the data is packed in the xdr packet*/
    if(packed) {
        /* In effect, compile where the data is, but wait*/
        /* until a getcontent to retrieve it*/
        OCASSERT((newcontent->mode == Datamode));
        newcontent->index = index; /* record final destination in the packed data*/
        newcontent->packed = 1;
        return OCTHROW(OC_NOERR);
    }

    for(i=0;i<index;i++) {
        stat = ocskipinstance(content->node,xdrs);
        if(stat != OC_NOERR) return OCTHROW(stat);
    }
    /* Record the location of the newcontent */
    newcontent->xdrpos.offset = xdr_getpos(xdrs);
    newcontent->xdrpos.valid = 1;

    /* move back to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

done:
    return OCTHROW(stat);
}
Пример #8
0
int
ocgetcontent(OCstate* state, OCcontent* content, void* memory, size_t memsize,
                 size_t start, size_t count)
{
    int stat = OC_NOERR;
    XDR* xdrs;
    OCtype etype;
    int isscalar;
    size_t elemsize, totalsize;
    int packed;
    unsigned int xdrcount;

    if(state == NULL || content == NULL || memory == NULL)
	{OCTHROWCHK(stat=OC_EINVAL); goto done;}
    if(content->node->octype != OC_Primitive)
	{OCTHROWCHK(stat=OC_EINVAL); goto done;}
    if(content->maxindex > 0 && content->maxindex < start+count)
	return OCTHROW(OC_ENODATA);

    etype = content->node->etype;
    isscalar = (content->node->array.rank == 0);
    if(isscalar && (start != 0 || count != 1))
	{OCTHROWCHK(stat=OC_EINVALCOORDS); goto done;}

    /* validate memory space*/
    elemsize = octypesize(etype);
    totalsize = elemsize*count;
    if(memsize < totalsize) return OCTHROW(OC_EINVAL);

    OCASSERT((occontentmode(state,content)==Dimmode || isscalar));

    if(content->memdata != NULL) { /* Get data from the compiled version */
	stat = ocgetmemdata(state,content,memory,memsize,start,count);
	goto done;
    }
    /* No memdata => use xdr */
    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* check if the data is packed*/
    packed = (!isscalar && (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    content->packed = packed;

    /* Make sure we are at the proper offset: ie at count if !scalar */
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) goto shortxdr;

    if(!isscalar) {
        /* Collect the dimension count from the xdr data packet*/
        if(!xdr_u_int(xdrs,&xdrcount)) goto shortxdr;
        if(xdrcount < start) return OCTHROW(OC_EINVALCOORDS);
        if(xdrcount < start+count) return OCTHROW(OC_EINVALCOORDS);
        /* pull out redundant second count*/
        /* (note that String/URL do not have redundant count)*/
        if(etype != OC_String && etype != OC_URL) {
            if(!xdr_u_int(xdrs,&xdrcount)) goto shortxdr;
        }
    }
    /* Extract the data */
#ifdef OCPROGRESS
    oc_log(LOGNOTE,"reading xdr: %lu bytes",(unsigned long)memsize);
#endif
    stat = ocxdrread(xdrs,(char*)memory,memsize,packed,content->node->etype,start,count);
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror(); /* restore location*/
done:
    return OCTHROW(stat);
shortxdr:
    oc_log(LOGERR,"DAP DATADDS appears to be too short");
    return OC_EDATADDS;
}
Пример #9
0
/*
The ocfieldcontent procedure has to deal with the fact
that the dap constraints may have removed some fields
from the datadds and hence some fields may have no
representation in the xdr data (or compiled data).
*/
int
ocfieldcontent(OCstate* state, OCcontent* content, OCcontent* fieldcontent, size_t index)
{
    unsigned int i;
    int stat = OC_NOERR;
    XDR* xdrs;
    OCtype octype,etype;
    int packed;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);
    if(content->mode != Fieldmode) return OCTHROW(OC_EINVAL);

    if(content->maxindex > 0 && content->maxindex <= index)
	return OCTHROW(OC_EINVALCOORDS);

    content->index = index; /* Track our location in parent content */

    octype = content->node->octype;
    etype = content->node->etype;

    /* check if the data is packed*/
    packed = (octype == OC_Primitive &&
              (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    ocresetcontent(state,fieldcontent);
    /* Set the state of the new content*/
    fieldcontent->state = state; /* make sure*/
    fieldcontent->tree = content->tree;
    fieldcontent->node = (OCnode*)oclistget(content->node->subnodes,index);
    fieldcontent->packed = packed;
    fieldcontent->mode = modetransition(fieldcontent->node, content->mode);
    fieldcontent->index = 0; /* record where we want to be */
    fieldcontent->maxindex = maxindexfor(fieldcontent->node,content->mode);

    if(content->memdata != NULL) { /* Get data from the compiled version */
	OCmemdata* md = content->memdata;
	OCmemdata* next;
        OCASSERT((md->mode == Fieldmode));
	if(md->count <= index) {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	next = ((OCmemdata**)md->data.data)[index];
	if(next == NULL) {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	fieldcontent->memdata = next;
	goto done;
    }

    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* checkpoint the beginning of this instance*/
    if(!content->xdrpos.valid) {
	content->xdrpos.offset = xdr_getpos(xdrs);
	content->xdrpos.valid = 1;
    }
    /* move to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

    switch (content->node->octype) {
    case OC_Grid:
	/* Note that the Grid array is field 0 and the maps are 1..nsubnodes*/
    case OC_Sequence:
    case OC_Dataset:
    case OC_Structure:
	if(index >= oclistlength(content->node->subnodes)) return OCTHROW(OC_EINVALCOORDS);
        for(i=0;i<index;i++) {
  	    OCnode* field = (OCnode*)oclistget(content->node->subnodes,i);
	    stat = ocskip(field,xdrs);
	    if(stat != OC_NOERR) return OCTHROW(stat);
        }
        fieldcontent->xdrpos.offset = xdr_getpos(xdrs);
	fieldcontent->xdrpos.valid = 1;
	break;

    case OC_Primitive:
    default: return OCTHROW(OC_EINVAL);
    }

    /* move back to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

done:
    return OCTHROW(stat);
}
Пример #10
0
int
ocrecordcontent(OCstate* state,OCcontent* content, OCcontent* recordcontent, size_t index)
{
    unsigned int i;
    int stat = OC_NOERR;
    XDR* xdrs;
    char tmp[BYTES_PER_XDR_UNIT];
    OCtype octype,etype;
    int packed;

    if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL);
    if(content->mode != Recordmode) return OCTHROW(OC_EINVAL);

    if(content->maxindex > 0 && content->maxindex <= index)
	return OCTHROW(OC_EINVALCOORDS);
    content->index = index; /* Track our location in parent content */

    octype = content->node->octype;
    etype = content->node->etype;

    /* check if the data is packed*/
    packed = (octype == OC_Primitive &&
              (etype == OC_Byte || etype == OC_UByte || etype == OC_Char));

    ocresetcontent(state,recordcontent);
    /* Set some of the new content*/
    recordcontent->state = state; /* make sure*/
    recordcontent->tree = content->tree;
    recordcontent->node = content->node;
    recordcontent->packed = packed;
    recordcontent->mode = modetransition(recordcontent->node, content->mode);
    recordcontent->index = 0;
    recordcontent->maxindex = maxindexfor(recordcontent->node,content->mode);

    if(content->memdata != NULL) { /* Get data from the compiled version */
	OCmemdata* next;
        OCASSERT((content->memdata->mode == Recordmode));
	if(content->memdata->count <= index)
	    {OCTHROWCHK(stat=OC_ENODATA); goto done;}
	next = ((OCmemdata**)content->memdata->data.data)[index];
	recordcontent->memdata = next;
	goto done;
    }

    xdrs = content->tree->data.xdrs;
    if(xdrs == NULL) return OCTHROW(OC_EXDR);

    /* checkpoint the beginning of this instance*/
    if(!content->xdrpos.valid) {
	content->xdrpos.offset = xdr_getpos(xdrs);
	content->xdrpos.valid = 1;
    }
    /* move to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

    switch (content->node->octype) {
    case OC_Sequence:
        for(i=0;i<index;i++) {
            /* pick up the sequence record begin marker*/
            /* extract the tag byte*/
            if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror();
            if(tmp[0] == StartOfoclist) {
                /* skip instance*/
                stat = ocskipinstance(content->node,xdrs);
            } else if(tmp[0] == EndOfoclist) {
                stat = OC_EINVALCOORDS; /* not enough records*/
                break;
            } else {
                oc_log(LOGERR,"missing/invalid begin/end record marker\n");
                stat = OC_EINVAL;
                break;
            }
        }
	if(stat != OC_NOERR) return OCTHROW(stat);

	/* skip the sequence begin marker for the chosen record*/
	/* so we are at its contents*/
        if(!xdr_opaque(xdrs,tmp,sizeof(tmp))) return xdrerror();
        if(tmp[0] != StartOfoclist) return OCTHROW(OC_EINVALCOORDS);

	/* Set contents of the output content*/
        recordcontent->xdrpos.offset = xdr_getpos(xdrs);
	recordcontent->xdrpos.valid = 1;
	break;

    case OC_Dataset:
    case OC_Structure:
    case OC_Grid:
    case OC_Primitive:
    default: return OCTHROW(OC_EINVAL);
    }

    /* move back to checkpoint position*/
    if(!xdr_setpos(xdrs,content->xdrpos.offset)) return xdrerror();

done:
    return OCTHROW(stat);
}