@@ -15,7 +15,7 @@ static int ncz_jsonize_atts(NCindex* attlist, NCjson** jattrsp);
1515static int load_jatts (NCZMAP * map , NC_OBJ * container , NCjson * * jattrsp , NClist * * atypes );
1616static int zconvert (nc_type typeid , size_t typelen , void * dst , NCjson * src );
1717static int computeattrinfo (const char * name , NClist * atypes , NCjson * values ,
18- nc_type * typeidp , size_t * lenp , void * * datap );
18+ nc_type * typeidp , size_t * typelenp , size_t * lenp , void * * datap );
1919static int parse_group_content (NCjson * jcontent , NClist * dimdefs , NClist * varnames , NClist * subgrps );
2020static int parse_group_content_pure (NCZ_FILE_INFO_T * zinfo , NC_GRP_INFO_T * grp , NClist * varnames , NClist * subgrps );
2121static int define_grp (NC_FILE_INFO_T * file , NC_GRP_INFO_T * grp );
@@ -28,7 +28,7 @@ static int locategroup(NC_FILE_INFO_T* file, size_t nsegs, NClist* segments, NC_
2828static int createdim (NC_FILE_INFO_T * file , const char * name , size64_t dimlen , NC_DIM_INFO_T * * dimp );
2929static int parsedimrefs (NC_FILE_INFO_T * , NClist * dimnames , size64_t * shape , NC_DIM_INFO_T * * dims , int create );
3030static int decodeints (NCjson * jshape , size64_t * shapes );
31- static int computeattrdata (nc_type * typeidp , NCjson * values , size_t * lenp , void * * datap );
31+ static int computeattrdata (nc_type * typeidp , NCjson * values , size_t * typelenp , size_t * lenp , void * * datap );
3232static int inferattrtype (NCjson * values , nc_type * typeidp );
3333static int mininttype (unsigned long long u64 , int negative );
3434static int computedimrefs (NC_FILE_INFO_T * file , NC_VAR_INFO_T * var , int purezarr , int xarray , int ndims , NClist * dimnames , size64_t * shapes , NC_DIM_INFO_T * * dims );
@@ -244,6 +244,7 @@ ncz_sync_var(NC_FILE_INFO_T* file, NC_VAR_INFO_T* var)
244244 NCjson * jncvar = NULL ;
245245 NCjson * jdimrefs = NULL ;
246246 NCjson * jtmp = NULL ;
247+ NCjson * jfill = NULL ;
247248 size64_t shape [NC_MAX_VAR_DIMS ];
248249 NCZ_VAR_INFO_T * zvar = var -> format_var_info ;
249250
@@ -325,7 +326,6 @@ ncz_sync_var(NC_FILE_INFO_T* file, NC_VAR_INFO_T* var)
325326 if (!var -> no_fill ) {
326327 int fillsort ;
327328 int atomictype = var -> type_info -> hdr .id ;
328- NCjson * jfill = NULL ;
329329 /* A scalar value providing the default value to use for uninitialized
330330 portions of the array, or ``null`` if no fill_value is to be used. */
331331 /* Use the defaults defined in netdf.h */
@@ -339,9 +339,17 @@ ncz_sync_var(NC_FILE_INFO_T* file, NC_VAR_INFO_T* var)
339339 if ((stat = nc4_get_default_fill_value (atomictype ,var -> fill_value ))) goto done ;
340340 }
341341 /* Convert var->fill_value to a string */
342- if ((stat = NCZ_stringconvert (atomictype ,1 ,var -> fill_value ,& jfill )))
343- goto done ;
344- if ((stat = NCJinsert (jvar ,"fill_value" ,jfill ))) goto done ;
342+ if ((stat = NCZ_stringconvert (atomictype ,1 ,var -> fill_value ,& jfill ))) goto done ;
343+ if (jfill -> sort == NCJ_ARRAY ) { /* stringconvert should prevent this from happening */
344+ assert (NCJlength (jfill ) > 0 );
345+ if ((stat = NCJarrayith (jfill ,0 ,& jtmp ))) goto done ; /* use the 0th element */
346+ if ((stat = NCJclone (jtmp ,& jtmp ))) goto done ; /* clone so we can free it later */
347+ NCJreclaim (jfill );
348+ jfill = jtmp ;
349+ jtmp = NULL ;
350+ }
351+ if ((stat = NCJinsert (jvar ,"fill_value" ,jfill ))) goto done ;
352+ jfill = NULL ;
345353 }
346354
347355 /* order key */
@@ -463,6 +471,7 @@ ncz_sync_var(NC_FILE_INFO_T* file, NC_VAR_INFO_T* var)
463471 NCJreclaim (jvar );
464472 NCJreclaim (jncvar );
465473 NCJreclaim (jtmp );
474+ NCJreclaim (jfill );
466475 return THROW (stat );
467476}
468477
@@ -683,6 +692,8 @@ ncz_sync_atts(NC_FILE_INFO_T* file, NC_OBJ* container, NCindex* attlist)
683692/**
684693@internal Convert a list of attributes to corresponding json.
685694Note that this does not push to the file.
695+ Also note that attributes of length 1 are stored as singletons, not arrays.
696+ This is to be more consistent with pure zarr.
686697@param attlist - [in] the attributes to dictify
687698@param jattrsp - [out] the json'ized att list
688699@return NC_NOERR
@@ -858,11 +869,11 @@ Extract type and data for an attribute
858869*/
859870static int
860871computeattrinfo (const char * name , NClist * atypes , NCjson * values ,
861- nc_type * typeidp , size_t * lenp , void * * datap )
872+ nc_type * typeidp , size_t * typelenp , size_t * lenp , void * * datap )
862873{
863874 int stat = NC_NOERR ;
864875 int i ;
865- size_t len ;
876+ size_t len , typelen ;
866877 void * data ;
867878 nc_type typeid ;
868879
@@ -880,10 +891,11 @@ computeattrinfo(const char* name, NClist* atypes, NCjson* values,
880891 }
881892 if (typeid >= NC_STRING )
882893 {stat = NC_EINTERNAL ; goto done ;}
883- if ((stat = computeattrdata (& typeid , values , & len , & data ))) goto done ;
894+ if ((stat = computeattrdata (& typeid , values , & typelen , & len , & data ))) goto done ;
884895
885896 if (typeidp ) * typeidp = typeid ;
886897 if (lenp ) * lenp = len ;
898+ if (typelenp ) * typelenp = typelen ;
887899 if (datap ) {* datap = data ; data = NULL ;}
888900
889901done :
@@ -895,7 +907,7 @@ computeattrinfo(const char* name, NClist* atypes, NCjson* values,
895907Extract data for an attribute
896908*/
897909static int
898- computeattrdata (nc_type * typeidp , NCjson * values , size_t * lenp , void * * datap )
910+ computeattrdata (nc_type * typeidp , NCjson * values , size_t * typelenp , size_t * lenp , void * * datap )
899911{
900912 int stat = NC_NOERR ;
901913 size_t datalen ;
@@ -911,7 +923,7 @@ computeattrdata(nc_type* typeidp, NCjson* values, size_t* lenp, void** datap)
911923
912924 /* Collect the length of the attribute; might be a singleton */
913925 switch (values -> sort ) {
914- case NCJ_DICT : stat = NC_EINTERNAL ; goto done ;
926+ case NCJ_DICT : stat = NC_ENCZARR ; goto done ;
915927 case NCJ_ARRAY :
916928 datalen = nclistlength (values -> contents );
917929 break ;
@@ -923,21 +935,22 @@ computeattrdata(nc_type* typeidp, NCjson* values, size_t* lenp, void** datap)
923935 break ;
924936 }
925937
926- /* Allocate data space */
927- if (( stat = NC4_inq_atomic_type ( typeid , NULL , & typelen )))
928- goto done ;
929- if ( typeid == NC_CHAR )
930- data = malloc ( typelen * ( datalen + 1 ));
931- else
932- data = malloc ( typelen * datalen );
933- if ( data == NULL )
934- { stat = NC_ENOMEM ; goto done ;}
935-
936- /* convert to target type */
937- if ((stat = zconvert (typeid , typelen , data , values )))
938- goto done ;
939-
938+ if ( datalen > 0 ) {
939+ /* Allocate data space */
940+ if (( stat = NC4_inq_atomic_type ( typeid , NULL , & typelen )))
941+ goto done ;
942+ if ( typeid == NC_CHAR )
943+ data = malloc ( typelen * ( datalen + 1 ));
944+ else
945+ data = malloc ( typelen * datalen );
946+ if ( data == NULL )
947+ { stat = NC_ENOMEM ; goto done ;}
948+ /* convert to target type */
949+ if ((stat = zconvert (typeid , typelen , data , values )))
950+ goto done ;
951+ }
940952 if (lenp ) * lenp = datalen ;
953+ if (typelenp ) * typelenp = typelen ;
941954 if (datap ) {* datap = data ; data = NULL ;}
942955 if (typeidp ) * typeidp = typeid ; /* return possibly inferred type */
943956
@@ -982,7 +995,7 @@ inferattrtype(NCjson* value, nc_type* typeidp)
982995 typeid = NC_CHAR ;
983996 break ;
984997 default :
985- return NC_EINTERNAL ;
998+ return NC_ENCZARR ;
986999 }
9871000 if (typeidp ) * typeidp = typeid ;
9881001 return NC_NOERR ;
@@ -1203,7 +1216,7 @@ ncz_read_atts(NC_FILE_INFO_T* file, NC_OBJ* container)
12031216 /* Create the attribute */
12041217 /* Collect the attribute's type and value */
12051218 if ((stat = computeattrinfo (key -> value ,atypes ,value ,
1206- & typeid ,& len ,& data )))
1219+ & typeid ,NULL , & len ,& data )))
12071220 goto done ;
12081221 if ((stat = ncz_makeattr (container ,attlist ,key -> value ,typeid ,len ,data ,& att )))
12091222 goto done ;
@@ -1430,9 +1443,10 @@ define_vars(NC_FILE_INFO_T* file, NC_GRP_INFO_T* grp, NClist* varnames)
14301443 if (jvalue == NULL )
14311444 var -> no_fill = 1 ;
14321445 else {
1446+ size_t fvlen ;
14331447 typeid = var -> type_info -> hdr .id ;
14341448 var -> no_fill = 0 ;
1435- if ((stat = computeattrdata (& typeid , jvalue , NULL , & var -> fill_value )))
1449+ if ((stat = computeattrdata (& typeid , jvalue , NULL , & fvlen , & var -> fill_value )))
14361450 goto done ;
14371451 assert (typeid == var -> type_info -> hdr .id );
14381452 /* Note that we do not create the _FillValue
0 commit comments