static NCerror buildattribute3a(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int varid) { int i; NCerror ncstat = NC_NOERR; unsigned int nvalues = nclistlength(att->values); NC* drno = dapcomm->controller; /* If the type of the attribute is string, then we need*/ /* to convert to a single character string by concatenation. modified: 10/23/09 to insert newlines. modified: 10/28/09 to interpret escapes */ if(att->etype == NC_STRING || att->etype == NC_URL) { char* newstring; size_t newlen = 0; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); newlen += (1+strlen(s)); } newstring = (char*)malloc(newlen); MEMCHECK(newstring,NC_ENOMEM); newstring[0] = '\0'; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); if(i > 0) strcat(newstring,"\n"); strcat(newstring,s); } dapexpandescapes(newstring); if(newstring[0]=='\0') ncstat = nc_put_att_text(drno->substrate,varid,att->name,1,newstring); else ncstat = nc_put_att_text(drno->substrate,varid,att->name,strlen(newstring),newstring); free(newstring); } else { nc_type atype; unsigned int typesize; void* mem; /* It turns out that some servers upgrade the type of _FillValue in order to correctly preserve the original value. However, since the type of the underlying variable is not changes, we get a type mismatch. So, make sure the type of the fillvalue is the same as that of the controlling variable. */ if(varid != NC_GLOBAL && strcmp(att->name,"_FillValue")==0) atype = nctypeconvert(dapcomm,vartype); else atype = nctypeconvert(dapcomm,att->etype); typesize = nctypesizeof(atype); mem = malloc(typesize * nvalues); ncstat = dapcvtattrval3(atype,mem,att->values); ncstat = nc_put_att(drno->substrate,varid,att->name,atype,nvalues,mem); nullfree(mem); } return THROW(ncstat); }
static NCerror slicestring(OClink conn, char* stringmem, DCEslice* slice, struct NCMEMORY* memory) { size_t stringlen; unsigned int i; NCerror ncstat = NC_NOERR; char* lastchar; size_t charcount; /* number of characters inserted into memory */ /* libnc-dap chooses to convert string escapes to the corresponding character; so we do likewise. */ dapexpandescapes(stringmem); stringlen = strlen(stringmem); #ifdef DEBUG2 fprintf(stderr,"moveto: slicestring: string/%lu=%s\n",stringlen,stringmem); fprintf(stderr,"slicestring: %lu string=|%s|\n",stringlen,stringmem); fprintf(stderr,"slicestring: slice=[%lu:%lu:%lu/%lu]\n", slice->first,slice->stride,slice->stop,slice->declsize); #endif /* Stride across string; if we go past end of string, then pad*/ charcount = 0; for(i=slice->first;i<slice->length;i+=slice->stride) { if(i < stringlen) *memory->next = stringmem[i]; else /* i >= stringlen*/ *memory->next = NC_FILL_CHAR; memory->next++; charcount++; } lastchar = (memory->next); if(charcount > 0) { lastchar--; } return THROW(ncstat); }