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); }
OCerror ocdata_read(OCstate* state, OCdata* data, size_t start, size_t count, void* memory, size_t memsize) { int stat = OC_NOERR; XXDR* xdrs; OCtype etype, octype; int isscalar; size_t elemsize, totalsize, countsize; OCnode* pattern; octrace("read", state, data); assert(state != NULL); assert(data != NULL); assert(memory != NULL); assert(memsize > 0); pattern = data->pattern; octype = pattern->octype; assert(octype == OC_Atomic); etype = pattern->etype; isscalar = (pattern->array.rank == 0 ? 1 : 0); /* validate memory space*/ elemsize = octypesize(etype); totalsize = elemsize*data->ninstances; countsize = elemsize*count; if(totalsize < countsize || memsize < countsize) return OCTHROW(OC_EINVAL); /* Get XXDR* */ xdrs = pattern->root->tree->data.xdrs; if(isscalar) { /* Extract the data */ stat = ocread(data,xdrs,(char*)memory,memsize,0,1); } else { /* Validate the start and count */ if(start >= data->ninstances || (start+count) > data->ninstances) return OCTHROW(OC_EINVALCOORDS); /* Extract the data */ stat = ocread(data,xdrs,(char*)memory,memsize,start,count); } return OCTHROW(stat); }
void* oclinearize(OCtype etype, unsigned int nstrings, char** strings) { int i; size_t typesize; char* memp; char* memory; if(nstrings == 0) return NULL; typesize = octypesize(etype); memory = (char*)ocmalloc(nstrings*typesize); MEMCHECK(memory,NULL); memp = memory; for(i=0;i<nstrings;i++) { char* value = strings[i]; converttype(etype,value,memp); memp += typesize; } return memory; }
static void ocdumpmemdata1(OCmemdata* md, OCbytes* buf, int depth) { OCmemdata** mdp; unsigned int i; char tmp[1024]; switch ((OCtype)md->octype) { case OC_Sequence: case OC_Grid: case OC_Structure: case OC_Dataset: sprintf(tmp,"%s%s/%s (%lu) {\n",dent(depth), octypetostring((OCtype)md->octype), ocmodestr(md->mode), (unsigned long)md->count); ocbytescat(buf,tmp); mdp = (OCmemdata**)md->data.data; switch ((OCmode)md->mode) { case Fieldmode: for(i=0;i<md->count;i++) { sprintf(tmp,"%s[%u]",dent(depth+1),i); ocbytescat(buf,tmp); ocdumpmemdata1(mdp[i],buf,depth+1); } break; case Dimmode: for(i=0;i<md->count;i++) { sprintf(tmp,"%s(%u)",dent(depth+1),i); ocbytescat(buf,tmp); ocdumpmemdata1(mdp[i],buf,depth+1); } break; case Recordmode: for(i=0;i<md->count;i++) { sprintf(tmp,"%s{%u}",dent(depth+1),i); ocbytescat(buf,tmp); ocdumpmemdata1(mdp[i],buf,depth+1); } break; default: break; } sprintf(tmp,"%s}\n",dent(depth)); break; case OC_Primitive: { OCtype etype = (OCtype)md->etype; char* data = md->data.data; sprintf(tmp,"%s%s/%s (%lu) {",dent(depth), octypetostring(etype),ocmodestr(md->mode),(unsigned long)md->count); ocbytescat(buf,tmp); for(i=0;i<md->count;i++) { char* p = data + (octypesize(etype)*i); ocbytescat(buf," "); octypeprint(etype,tmp,sizeof(tmp),(void*)p); ocbytescat(buf,tmp); } ocbytescat(buf," }\n"); } break; default: break; } }
static OCerror ocread(OCdata* data, XXDR* xdrs, char* memory, size_t memsize, size_t start, size_t count) { int i; OCnode* pattern; OCtype etype; off_t elemsize, totalsize, xdrtotal, xdrstart; int scalar; OCASSERT(data != NULL); OCASSERT(memory != NULL); OCASSERT(memsize > 0); OCASSERT(count > 0); OCASSERT((start+count) <= data->ninstances); pattern = data->pattern; etype = pattern->etype; scalar = (pattern->array.rank == 0); /* Note that for strings, xdrsize == 0 */ xdrtotal = count*data->xdrsize; /* amount (in xdr sizes) to read */ xdrstart = start*data->xdrsize; /* offset from the start of the data */ elemsize = octypesize(etype); /* wrt memory, not xdrsize */ totalsize = elemsize*count; /* validate memory space*/ if(memsize < totalsize) return OCTHROW(OC_EINVAL); /* copy out with appropriate byte-order conversions */ switch (etype) { case OC_Int32: case OC_UInt32: case OC_Float32: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} if(!xxdr_network_order) { unsigned int* p; for(p=(unsigned int*)memory,i=0;i<count;i++,p++) { swapinline32(p); } } break; case OC_Int64: case OC_UInt64: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} if(!xxdr_network_order) { unsigned long long* llp; for(llp=(unsigned long long*)memory,i=0;i<count;i++,llp++) { swapinline64(llp); } } break; case OC_Float64: xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} { double* dp; for(dp=(double*)memory,i=0;i<count;i++,dp++) { double swap; xxdrntohdouble((char*)dp,&swap); *dp = swap; } } break; /* non-packed fixed length, but memory size < xdrsize */ case OC_Int16: case OC_UInt16: { /* In order to avoid allocating a lot of space, we do this one int at a time */ /* Remember also that the short is not packed, so its xdr size is twice its memory size */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(scalar) { if(!xxdr_ushort(xdrs,(unsigned short*)memory)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } else { unsigned short* sp = (unsigned short*)memory; for(i=0;i<count;i++,sp++) { unsigned int tmp; if(!xxdr_getbytes(xdrs,(char*)&tmp,(off_t)XDRUNIT)) {OCTHROW(OC_EDATADDS); goto xdrfail;} /* convert from network order if necessary */ if(!xxdr_network_order) swapinline32(&tmp); /* store as unsigned short */ *sp = (unsigned short)tmp; } } } break; /* Do the byte types, packed/unpacked */ case OC_Byte: case OC_UByte: case OC_Char: if(scalar) { /* scalar bytes are stored in xdr as int */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_uchar(xdrs,(unsigned char*)memory)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } else { /* the xdroffset will always be at the start of the packed data, so we need to add the start count to it */ xxdr_setpos(xdrs,data->xdroffset+xdrstart); if(!xxdr_getbytes(xdrs,memory,xdrtotal)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } break; /* Hard case, because strings are variable length */ case OC_String: case OC_URL: { /* use the data->nstrings data->string fields */ char** sp = (char**)memory; if(count > data->nstrings) return OCTHROW(OC_EDATADDS); for(i=0;i<count;i++,sp++) { off_t len; off_t offset = data->strings[start+i]; xxdr_setpos(xdrs,offset); /* get the string */ if(!xxdr_string(xdrs,sp,&len)) {OCTHROW(OC_EDATADDS); goto xdrfail;} } } break; default: OCPANIC("unexpected etype"); break; } return OC_NOERR; xdrfail: oclog(OCLOGERR,"DAP DATADDS packet is apparently too short"); return OCTHROW(OC_EDATADDS); }
/* 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); }
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; }
/* OCtype management */ size_t oc_typesize(OCtype etype) { return octypesize(etype); }