netcdf-c/plugins/NCZmisc.c
Dennis Heimbigner 06d2fe5b13 # Addendum
As suggested by Ward, I ensured that this PR supports
read backward compatibility with old key format.
This addition also adds a test case for this.

## Misc. Other Changes
* Remove some unused code
* Cleanup json error handling
* Fix some more unsigned/signed conversions warning
2024-06-25 17:13:02 -06:00

184 lines
5.2 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Programmer: Robb Matzke
* Friday, August 27, 1999
*/
/* Converted to NCZarr support by Dennis Heimbigner 5/1/2021 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include "netcdf_json.h"
#include "netcdf.h"
#include "netcdf_filter.h"
#include "netcdf_filter_build.h"
#include "h5misc.h"
/**************************************************/
/* NCZarr Filter Objects */
/* Codec Format
{
"id": "test",
"testcase": "n",
"byte": "<unsigned int>",
"ubyte": "<unsigned int>",
"short": "<unsigned int>",
"ushort": "<unsigned int>",
"int": "<unsigned int>",
"uint": "<unsigned int>",
"float": "<unsigned int>",
"double0": "<unsigned int>",
"double1": "<unsigned int>",
"int640": "<unsigned int>",
"int641": "<unsigned int>",
"uint640": "<unsigned int>",
"uint641": "<unsigned int>",
}
*/
/* Give unique dict key names for parameters */
static const char* fields[14] = {
"testcase",
"byte",
"ubyte",
"short",
"ushort",
"int",
"uint",
"float",
"double_0",
"double_1",
"int64_0",
"int64_1",
"uint64_0",
"uint64_1"
};
/* Forward */
static int NCZ_misc_codec_to_hdf5(const char* codec, size_t* nparamsp, unsigned** paramsp);
static int NCZ_misc_hdf5_to_codec(size_t nparams, const unsigned* params, char** codecp);
/* Structure for NCZ_PLUGIN_CODEC */
static NCZ_codec_t NCZ_misc_codec = {/* NCZ_codec_t codec fields */
NCZ_CODEC_CLASS_VER, /* Struct version number */
NCZ_CODEC_HDF5, /* Struct sort */
"test", /* Standard name/id of the codec */
H5Z_FILTER_TEST, /* HDF5 alias for misc */
NULL, /*NCZ_misc_codec_initialize*/
NULL, /*NCZ_misc_codec_finalize*/
NCZ_misc_codec_to_hdf5,
NCZ_misc_hdf5_to_codec,
NULL, /*NCZ_misc_modify_parameters*/
};
/* External Export API */
DLLEXPORT
const void*
NCZ_get_codec_info(void)
{
return (void*)&NCZ_misc_codec;
}
/* NCZarr Interface Functions */
static int
NCZ_misc_codec_to_hdf5(const char* codec_json, size_t* nparamsp, unsigned** paramsp)
{
int stat = NC_NOERR;
NCjson* jcodec = NULL;
const NCjson* jtmp = NULL;
size_t i,nparams = 0;
unsigned* params = NULL;
/* parse the JSON */
if(NCJparse(codec_json,0,&jcodec))
{stat = NC_EFILTER; goto done;}
if(NCJsort(jcodec) != NCJ_DICT) {stat = NC_EPLUGIN; goto done;}
/* Verify the codec ID */
if(NCJdictget(jcodec,"id",&jtmp))
{stat = NC_EFILTER; goto done;}
if(jtmp == NULL || !NCJisatomic(jtmp)) {stat = NC_EINVAL; goto done;}
if(strcmp(NCJstring(jtmp),NCZ_misc_codec.codecid)!=0) {stat = NC_EINVAL; goto done;}
/* The codec will have (2*14 + 1) +1 = 29 dict entries + id*/
nparams = (2*14 + 1) + 1;
if(NCJlength(jcodec) != nparams) {
fprintf(stderr,"Incorrect no. of codec parameters: need=29 sent=%ld\n",(unsigned long)(nparams-1));
stat = NC_EINVAL;
goto done;
}
/* Actual # of parameters is 14 (ignoring the testcase number) */
nparams = 14;
if((params = (unsigned*)calloc(nparams,sizeof(unsigned)))== NULL)
{stat = NC_ENOMEM; goto done;}
for(i=0;i<nparams;i++) {
struct NCJconst jc;
if(NCJdictget(jcodec,fields[i],&jtmp))
{stat = NC_EFILTER; goto done;}
if(NCJcvt(jtmp,NCJ_INT,&jc))
{stat = NC_EFILTER; goto done;}
if(jc.ival < 0 || jc.ival > NC_MAX_UINT) {stat = NC_EINVAL; goto done;}
params[i] = (unsigned)jc.ival;
}
if(nparamsp) *nparamsp = nparams;
if(paramsp) {*paramsp = params; params = NULL;}
done:
if(params) free(params);
NCJreclaim(jcodec);
return stat;
}
static int
NCZ_misc_hdf5_to_codec(size_t nparams, const unsigned* params, char** codecp)
{
int i,stat = NC_NOERR;
char json[4096];
char value[1024];
size_t count, jlen;
if(nparams == 0 || params == NULL)
{stat = NC_EINVAL; goto done;}
if(nparams != 14) {
fprintf(stderr,"Incorrect no. of parameters: need=14 sent=%ld\n",(unsigned long)nparams);
stat = NC_EINVAL;
goto done;
}
jlen = sizeof(json);
count = snprintf(json,sizeof(json),"{\"id\": \"%s\"",NCZ_misc_codec.codecid);
for(i=0;i<14;i++) {
size_t len = snprintf(value,sizeof(value),", \"%s\": \"%u\"",fields[i],params[i]);
count += len; assert(jlen > count);
strcat(json,value);
}
count += 1; assert(jlen > count);
strcat(json,"}");
if(codecp) {
if((*codecp = strdup(json))==NULL) {stat = NC_ENOMEM; goto done;}
}
done:
return stat;
}