mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Rebuilt the filter parameter handling code to use a common
parser everywhere.
This commit is contained in:
parent
22ebecab23
commit
3e47f5f300
@ -162,8 +162,8 @@ also can easily be represented as 32 bit unsigned integers by
|
||||
proper casting to an unsigned integer so that the bit pattern
|
||||
is preserved. Simple integer values of type short or char
|
||||
(or the unsigned versions) can also be mapped to an unsigned
|
||||
integer by either sign extension or just padding with zeros in some
|
||||
consistent way.
|
||||
integer by truncating to 16 or 8 bits respectively and then
|
||||
zero extending.
|
||||
|
||||
Machine byte order (aka endian-ness) is an issue for passing
|
||||
some kinds of parameters. You might define the parameters when
|
||||
@ -238,10 +238,10 @@ the <a href="#ParamEncode">parameter encoding section</a>.
|
||||
The currently supported constants are as follows.
|
||||
<table>
|
||||
<tr halign="center"><th>Example<th>Type<th>Format Tag<th>Notes
|
||||
<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>
|
||||
<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>
|
||||
<tr><td>-25S<td>signed 16-bit short<td>s|S<td>
|
||||
<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>
|
||||
<tr><td>-17b<td>signed 8-bit byte<td>b|B<td>Truncated to 8 bits and zero extended to 32 bits
|
||||
<tr><td>23ub<td>unsigned 8-bit byte<td>u|U b|B<td>Truncated to 8 bits and zero extended to 32 bits
|
||||
<tr><td>-25S<td>signed 16-bit short<td>s|S<td>Truncated to 16 bits and zero extended to 32 bits
|
||||
<tr><td>27US<td>unsigned 16-bit short<td>u|U s|S<td>Truncated to 16 bits and zero extended to 32 bits
|
||||
<tr><td>-77<td>implicit signed 32-bit integer<td>Leading minus sign and no tag<td>
|
||||
<tr><td>77<td>implicit unsigned 32-bit integer<td>No tag<td>
|
||||
<tr><td>93U<td>explicit unsigned 32-bit integer<td>u|U<td>
|
||||
|
@ -1,8 +1,14 @@
|
||||
SET(CMAKE_BUILD_TYPE "")
|
||||
|
||||
SET(libbzip2_SOURCES blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c H5Zbzip2.c)
|
||||
SET(libbzip2_SOURCES bzlib.h bzlib_private.h
|
||||
blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
|
||||
H5Zbzip2.c h5bzip2.h
|
||||
)
|
||||
|
||||
SET(libmisc_SOURCES H5Zmisc.c)
|
||||
# Get the compilable sources from nc_test4/hdf5plugins
|
||||
FOREACH(S ${libbzip2_SOURCES})
|
||||
FILE(COPY ${CMAKE_SOURCE_DIR}/nc_test4/hdf5plugins/${S} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
ENDFOREACH(S)
|
||||
|
||||
IF(ENABLE_FILTER_TESTING)
|
||||
IF(BUILD_UTILITIES)
|
||||
|
@ -1,228 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <hdf5.h>
|
||||
/* Older versions of the hdf library may define H5PL_type_t here */
|
||||
#include <H5PLextern.h>
|
||||
|
||||
#ifndef DLL_EXPORT
|
||||
#define DLL_EXPORT
|
||||
#endif
|
||||
|
||||
#include "h5misc.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
static int paramcheck(size_t nparams, const unsigned int* params);
|
||||
static void byteswap8(unsigned char* mem);
|
||||
static void mismatch(size_t i, const char* which);
|
||||
|
||||
const H5Z_class2_t H5Z_TEST[1] = {{
|
||||
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
|
||||
(H5Z_filter_t)(H5Z_FILTER_TEST), /* Filter id number */
|
||||
1, /* encoder_present flag (set to true) */
|
||||
1, /* decoder_present flag (set to true) */
|
||||
"test", /* Filter name for debugging */
|
||||
(H5Z_can_apply_func_t)H5Z_test_can_apply, /* The "can apply" callback */
|
||||
NULL, /* The "set local" callback */
|
||||
(H5Z_func_t)H5Z_filter_test, /* The actual filter function */
|
||||
}};
|
||||
|
||||
/* External Discovery Functions */
|
||||
H5PL_type_t
|
||||
H5PLget_plugin_type(void)
|
||||
{
|
||||
return H5PL_TYPE_FILTER;
|
||||
}
|
||||
|
||||
const void*
|
||||
H5PLget_plugin_info(void)
|
||||
{
|
||||
return H5Z_TEST;
|
||||
}
|
||||
|
||||
/* Make this explicit */
|
||||
/*
|
||||
* The "can_apply" callback returns positive a valid combination, zero for an
|
||||
* invalid combination and negative for an error.
|
||||
*/
|
||||
htri_t
|
||||
H5Z_test_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id)
|
||||
{
|
||||
return 1; /* Assume it can always apply */
|
||||
}
|
||||
|
||||
/*
|
||||
This filter does some verification
|
||||
that the parameters passed to the filter
|
||||
are correct. Specifically, that endian-ness
|
||||
is correct. As a filter, it is the identify
|
||||
function, passing input to output unchanged.
|
||||
|
||||
Test cases format:
|
||||
1.The first param is the test index i.e. which test to execute.
|
||||
2. The remaining parameters are those for the test chosen in #1
|
||||
|
||||
*/
|
||||
|
||||
size_t
|
||||
H5Z_filter_test(unsigned int flags, size_t cd_nelmts,
|
||||
const unsigned int cd_values[], size_t nbytes,
|
||||
size_t *buf_size, void **buf)
|
||||
{
|
||||
void* newbuf;
|
||||
unsigned int testcase = 0;
|
||||
|
||||
if(cd_nelmts == 0)
|
||||
goto fail;
|
||||
|
||||
testcase = cd_values[0];
|
||||
|
||||
if(testcase == TC_ENDIAN) {
|
||||
if(!paramcheck(cd_nelmts,cd_values))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (flags & H5Z_FLAG_REVERSE) {
|
||||
|
||||
/* Replace buffer */
|
||||
newbuf = malloc(*buf_size);
|
||||
if(newbuf == NULL) abort();
|
||||
memcpy(newbuf,*buf,*buf_size);
|
||||
*buf = newbuf;
|
||||
|
||||
} else {
|
||||
|
||||
/* Replace buffer */
|
||||
newbuf = malloc(*buf_size);
|
||||
if(newbuf == NULL) abort();
|
||||
memcpy(newbuf,*buf,*buf_size);
|
||||
*buf = newbuf;
|
||||
|
||||
}
|
||||
|
||||
return *buf_size;
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
paramcheck(size_t nparams, const unsigned int* params)
|
||||
{
|
||||
size_t i;
|
||||
/* Test endianness of this machine */
|
||||
const unsigned char b[4] = {0x0,0x0,0x0,0x1}; /* value 1 in big-endian*/
|
||||
int bigendian = (1 == *(unsigned int*)b); /* 1=>big 0=>little*/
|
||||
|
||||
if(nparams != 14) {
|
||||
fprintf(stderr,"Too few parameters: need=16 sent=%ld\n",(unsigned long)nparams);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i=0;i<nparams;i++) {
|
||||
switch (i) {
|
||||
case 0: break; /* this is the testcase # */
|
||||
case 1: if(((signed char)-17) != (signed int)(params[i]))
|
||||
{mismatch(i,"signed byte"); return 0; };
|
||||
break;
|
||||
case 2: if(((unsigned char)23) != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned byte"); return 0; };
|
||||
break;
|
||||
case 3: if(((signed short)-25) != (signed int)(params[i]))
|
||||
{mismatch(i,"signed short"); return 0; };
|
||||
break;
|
||||
case 4: if(((unsigned short)27) != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned short"); return 0; };
|
||||
break;
|
||||
case 5: if(77 != (signed int)(params[i]))
|
||||
{mismatch(i,"signed int"); return 0; };
|
||||
break;
|
||||
case 6: if(93u != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned int"); return 0; };
|
||||
break;
|
||||
case 7: if(789.0f != *(float*)(¶ms[i]))
|
||||
{mismatch(i,"float"); return 0; };
|
||||
break;
|
||||
case 8: {/*double*/
|
||||
double x = *(double*)¶ms[i];
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
if(DBLVAL != x) {
|
||||
mismatch(i,"double");
|
||||
return 0;
|
||||
}
|
||||
}; break;
|
||||
case 10: {/*signed long long*/
|
||||
signed long long x = *(signed long long*)¶ms[i];
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
if(-9223372036854775807L != x) {
|
||||
mismatch(i,"signed long long");
|
||||
return 0;
|
||||
}
|
||||
}; break;
|
||||
case 12: {/*unsigned long long*/
|
||||
unsigned long long x = *(unsigned long long*)¶ms[i];
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
if(18446744073709551615UL != x) {
|
||||
mismatch(i,"unsigned long long");
|
||||
return 0;
|
||||
}
|
||||
}; break;
|
||||
|
||||
default:
|
||||
mismatch(i,"unexpected parameter");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
size_t i;
|
||||
fprintf(stderr,"bigendian=%d nparams=%d params=\n",bigendian,nparams);
|
||||
for(i=0;i<nparams;i++) {
|
||||
fprintf(stderr,"[%d] %ud %d %f\n", (unsigned int)i, params[i],(signed int)params[i],*(float*)¶ms[i]);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
byteswap8(unsigned char* mem)
|
||||
{
|
||||
unsigned char c;
|
||||
c = mem[0];
|
||||
mem[0] = mem[7];
|
||||
mem[7] = c;
|
||||
c = mem[1];
|
||||
mem[1] = mem[6];
|
||||
mem[6] = c;
|
||||
c = mem[2];
|
||||
mem[2] = mem[5];
|
||||
mem[5] = c;
|
||||
c = mem[3];
|
||||
mem[3] = mem[4];
|
||||
mem[4] = c;
|
||||
}
|
||||
|
||||
static void
|
||||
mismatch(size_t i, const char* which)
|
||||
{
|
||||
fprintf(stderr,"mismatch: [%ld] %s\n",(unsigned long)i,which);
|
||||
fflush(stderr);
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <hdf5.h>
|
||||
/* Older versions of the hdf library may define H5PL_type_t here */
|
||||
#include <H5PLextern.h>
|
||||
#include "xxxx.h"
|
||||
|
||||
/*
|
||||
Provide a textual template (not a C++ template)
|
||||
from which one can construct a new filter.
|
||||
The filter "name is marked with "XXXX" or "xxxx"
|
||||
|
||||
*/
|
||||
|
||||
const H5Z_class2_t H5Z_XXXX[1] = {{
|
||||
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
|
||||
(H5Z_filter_t)H5Z_FILTER_XXXX, /* Filter id number */
|
||||
1, /* encoder_present flag (set to true) */
|
||||
1, /* decoder_present flag (set to true) */
|
||||
"xxxx", /* Filter name for debugging */
|
||||
NULL, /* The "can apply" callback */
|
||||
NULL, /* The "set local" callback */
|
||||
(H5Z_func_t)H5Z_filter_xxxx, /* The actual filter function */
|
||||
}};
|
||||
|
||||
/* External Discovery Functions */
|
||||
H5PL_type_t
|
||||
H5PLget_plugin_type(void)
|
||||
{
|
||||
return H5PL_TYPE_FILTER;
|
||||
}
|
||||
|
||||
const void*
|
||||
H5PLget_plugin_info(void)
|
||||
{
|
||||
return H5Z_XXXX;
|
||||
}
|
||||
|
||||
size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
|
||||
const unsigned int cd_values[], size_t nbytes,
|
||||
size_t *buf_size, void **buf);
|
||||
|
||||
|
||||
size_t H5Z_filter_xxxx(unsigned int flags, size_t cd_nelmts,
|
||||
const unsigned int cd_values[], size_t nbytes,
|
||||
size_t *buf_size, void **buf)
|
||||
{
|
||||
char *outbuf = NULL;
|
||||
size_t outbuflen, outdatalen;
|
||||
int ret;
|
||||
|
||||
if (flags & H5Z_FLAG_REVERSE) {
|
||||
|
||||
/** Decompress data.
|
||||
**
|
||||
** This process is troublesome since the size of uncompressed data
|
||||
** is unknown, so the low-level interface must be used.
|
||||
** Data is decompressed to the output buffer (which is sized
|
||||
** for the average case); if it gets full, its size is doubled
|
||||
** and decompression continues. This avoids repeatedly trying to
|
||||
** decompress the whole block, which could be really inefficient.
|
||||
**/
|
||||
|
||||
char *newbuf = NULL;
|
||||
size_t newbuflen;
|
||||
|
||||
} else {
|
||||
|
||||
/** Compress data.
|
||||
**
|
||||
** This is quite simple, since the size of compressed data in the worst
|
||||
** case is known and it is not much bigger than the size of uncompressed
|
||||
** data. This allows us to use the simplified one-shot interface to
|
||||
** compression.
|
||||
**/
|
||||
|
||||
unsigned int odatalen; /* maybe not the same size as outdatalen */
|
||||
|
||||
/* Prepare the output buffer. */
|
||||
outbuflen = M; /* worst case */
|
||||
outbuf = malloc(outbuflen);
|
||||
if (outbuf == NULL) {
|
||||
fprintf(stderr, "memory allocation failed for xxxx compression\n");
|
||||
goto cleanupAndFail;
|
||||
}
|
||||
|
||||
/* Compress data. */
|
||||
|
||||
}
|
||||
|
||||
/* Always replace the input buffer with the output buffer. */
|
||||
free(*buf);
|
||||
*buf = outbuf;
|
||||
*buf_size = outbuflen;
|
||||
return outdatalen;
|
||||
|
||||
cleanupAndFail:
|
||||
if (outbuf)
|
||||
free(outbuf);
|
||||
return 0;
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
# Copyright 2018, UCAR/Unidata
|
||||
# See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
|
||||
BZIP2HDRS=bzlib.h bzlib_private.h
|
||||
BZIP2SRC= blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
|
||||
BZIP2SRC = bzlib.h bzlib_private.h blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c
|
||||
|
||||
PLUGINSRC=H5Zbzip2.c
|
||||
PLUGINHDRS=h5bzip2.h
|
||||
PLUGINSRC = H5Zbzip2.c h5bzip2.h
|
||||
|
||||
EXTRA_DIST=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS} \
|
||||
H5Ztemplate.c H5Zmisc.c
|
||||
TARGETS = ${PLUGINSRC} ${BZIP2SRC}
|
||||
|
||||
BUILT_SOURCES = ${TARGETS}
|
||||
|
||||
${TARGETS}:
|
||||
for x in ${TARGETS} ; do 'cp' -f ${top_srcdir}/nc_test4/hdf5plugins/$$x . ; done
|
||||
|
||||
CLEANFILES = ${TARGETS}
|
||||
|
||||
if ENABLE_FILTER_TESTING
|
||||
|
||||
DLLSRC=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS}
|
||||
DLLSRC=${PLUGINSRC} ${BZIP2SRC}
|
||||
|
||||
lib_LTLIBRARIES = libbzip2.la libmisc.la
|
||||
lib_LTLIBRARIES = libbzip2.la
|
||||
|
||||
libbzip2_la_SOURCES = ${DLLSRC}
|
||||
libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
|
||||
|
||||
libmisc_la_SOURCES = H5Zmisc.c h5misc.h
|
||||
libmisc_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
|
||||
|
||||
endif #ENABLE_FILTER_TESTING
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
#ifndef H5MISC_H
|
||||
#define H5MISC_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef DLL_EXPORT /* define when building the library */
|
||||
#define DECLSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define DECLSPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DECLSPEC extern
|
||||
#endif
|
||||
|
||||
/* use an integer greater than 256 to be id of the registered filter. */
|
||||
#define H5Z_FILTER_TEST 32768
|
||||
|
||||
/* Define the test cases */
|
||||
|
||||
typedef enum H5testcase {
|
||||
TC_NONE = 0,
|
||||
TC_ENDIAN = 1,
|
||||
} H5testcase;
|
||||
|
||||
/* declare the hdf5 interface */
|
||||
DECLSPEC H5PL_type_t H5PLget_plugin_type(void);
|
||||
DECLSPEC const void* H5PLget_plugin_info(void);
|
||||
DECLSPEC const H5Z_class2_t H5Z_TEST[1];
|
||||
|
||||
/* Declare filter specific functions */
|
||||
DECLSPEC htri_t H5Z_test_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id);
|
||||
DECLSPEC size_t H5Z_filter_test(unsigned flags,size_t cd_nelmts,const unsigned cd_values[],
|
||||
size_t nbytes,size_t *buf_size,void**buf);
|
||||
|
||||
#endif /*H5MISC_H*/
|
@ -5,8 +5,6 @@
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../../test_common.sh
|
||||
|
||||
set -x
|
||||
|
||||
echo "*** Running examples for netCDF-4."
|
||||
set -e
|
||||
|
||||
|
@ -18,6 +18,8 @@ extern "C" {
|
||||
/* Provide consistent filter spec parser */
|
||||
EXTERNL int NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
|
||||
|
||||
EXTERNL void NC_byteswap8(unsigned char* mem);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -19,9 +19,7 @@ Common utilities related to filters.
|
||||
|
||||
|
||||
/* Forward */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
static void byteswap8(unsigned char* mem);
|
||||
#endif
|
||||
static int gettype(const int q0, const int q1, int* unsignedp);
|
||||
|
||||
/**************************************************/
|
||||
/*
|
||||
@ -39,13 +37,15 @@ of unsigned ints.
|
||||
EXTERNL int
|
||||
NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
int sstat; /* for scanf */
|
||||
char* p;
|
||||
char* sdata = NULL;
|
||||
int stat;
|
||||
unsigned int id;
|
||||
size_t count; /* no. of comma delimited params */
|
||||
size_t nparams; /* final no. of unsigned ints */
|
||||
size_t i;
|
||||
size_t len;
|
||||
int i;
|
||||
unsigned int* ulist = NULL;
|
||||
unsigned char mem[8]; /* to convert to network byte order */
|
||||
|
||||
@ -67,9 +67,10 @@ NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsign
|
||||
|
||||
/* Extract the filter id */
|
||||
p = sdata;
|
||||
stat = sscanf(p,"%u",&id);
|
||||
if(stat != 1) goto fail;
|
||||
p = p + strlen(p) + 1; /* skip the filter id */
|
||||
sstat = sscanf(p,"%u",&id);
|
||||
if(sstat != 1) goto fail;
|
||||
/* skip past the filter id */
|
||||
p = p + strlen(p) + 1;
|
||||
count--;
|
||||
|
||||
/* Allocate the max needed space; *2 in case the params are all doubles */
|
||||
@ -77,41 +78,38 @@ NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsign
|
||||
if(ulist == NULL) goto fail;
|
||||
|
||||
/* walk and convert */
|
||||
nparams = 0;
|
||||
for(i=0;i<count;i++) {
|
||||
char* q;
|
||||
nparams = 0; /* actual count */
|
||||
for(i=0;i<count;i++) { /* step thru param strings */
|
||||
unsigned long long val64u;
|
||||
unsigned int val32u;
|
||||
double vald;
|
||||
float valf;
|
||||
unsigned int *vector;
|
||||
int isunsigned;
|
||||
int isnegative;
|
||||
int type;
|
||||
int isunsigned = 0;
|
||||
int isnegative = 0;
|
||||
int type = 0;
|
||||
char* q;
|
||||
|
||||
/* Get trailing discrimination characters */
|
||||
isunsigned = 0;
|
||||
isnegative = 0;
|
||||
type = 0;
|
||||
if(strchr(p,'-') != NULL) isnegative = 1;
|
||||
q = p+strlen(p)-2;
|
||||
if(*q == 'U' || *q == 'u') isunsigned = 1;
|
||||
q++;
|
||||
switch (*q) {
|
||||
case 'f': case 'F': type = 'f'; break; /* short */
|
||||
case 'd': case 'D': type = 'd'; break; /* double */
|
||||
case 'b': case 'B': type = 'b'; break; /* byte */
|
||||
case 's': case 'S': type = 's'; break; /* short */
|
||||
case 'l': case 'L': type = 'l'; break; /* long long */
|
||||
case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* integer */
|
||||
case '.':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
|
||||
default:
|
||||
if(*q == '\0')
|
||||
type = 'i';
|
||||
else goto fail;
|
||||
len = strlen(p);
|
||||
/* skip leading white space */
|
||||
while(strchr(" ",*p) != NULL) {p++; len--;}
|
||||
/* Get leading sign character, if any */
|
||||
if(*p == '-') isnegative = 1;
|
||||
/* Get trailing type tag characters */
|
||||
switch (len) {
|
||||
case 0:
|
||||
goto fail; /* empty parameter */
|
||||
case 1:
|
||||
case 2:
|
||||
q = (p + len) - 1; /* point to last char */
|
||||
type = gettype(*q,'\0',&isunsigned);
|
||||
break;
|
||||
default: /* > 2 => we might have a two letter tag */
|
||||
q = (p + len) - 2;
|
||||
type = gettype(*q,*(q+1),&isunsigned);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now parse */
|
||||
switch (type) {
|
||||
case 'b':
|
||||
@ -119,25 +117,31 @@ NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsign
|
||||
case 'i':
|
||||
/* special case for a positive integer;for back compatibility.*/
|
||||
if(!isnegative)
|
||||
stat = sscanf(p,"%u",&val32u);
|
||||
sstat = sscanf(p,"%u",&val32u);
|
||||
else
|
||||
stat = sscanf(p,"%d",(int*)&val32u);
|
||||
if(stat != 1) goto fail;
|
||||
sstat = sscanf(p,"%d",(int*)&val32u);
|
||||
if(sstat != 1) goto fail;
|
||||
switch(type) {
|
||||
case 'b': val32u = (val32u & 0xFF); break;
|
||||
case 's': val32u = (val32u & 0xFFFF); break;
|
||||
}
|
||||
ulist[nparams++] = val32u;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
sstat = sscanf(p,"%lf",&vald);
|
||||
if(sstat != 1) goto fail;
|
||||
valf = (float)vald;
|
||||
ulist[nparams++] = *(unsigned int*)&valf;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
sstat = sscanf(p,"%lf",&vald);
|
||||
if(sstat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&vald,sizeof(mem));
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
byteswap8(mem); /* convert big endian to little endian */
|
||||
NC_byteswap8(mem); /* convert big endian to little endian */
|
||||
#endif
|
||||
vector = (unsigned int*)mem;
|
||||
ulist[nparams++] = vector[0];
|
||||
@ -145,10 +149,10 @@ NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsign
|
||||
break;
|
||||
case 'l': /* long long */
|
||||
if(isunsigned)
|
||||
stat = sscanf(p,"%llu",&val64u);
|
||||
sstat = sscanf(p,"%llu",&val64u);
|
||||
else
|
||||
stat = sscanf(p,"%lld",(long long*)&val64u);
|
||||
if(stat != 1) goto fail;
|
||||
sstat = sscanf(p,"%lld",(long long*)&val64u);
|
||||
if(sstat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&val64u,sizeof(mem));
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
@ -170,19 +174,51 @@ NC_parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsign
|
||||
*paramsp = ulist;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
}
|
||||
done:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 1;
|
||||
return stat;
|
||||
fail:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 0;
|
||||
stat = NC_EFILTER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Look at q0 and q1) to determine type */
|
||||
static int
|
||||
gettype(const int q0, const int q1, int* isunsignedp)
|
||||
{
|
||||
int type = 0;
|
||||
int isunsigned = 0;
|
||||
char typechar;
|
||||
|
||||
isunsigned = (q0 == 'u' || q0 == 'U');
|
||||
if(q1 == '\0')
|
||||
typechar = q0; /* we were given only a single char */
|
||||
else if(isunsigned)
|
||||
typechar = q1; /* we have something like Ux as the tag */
|
||||
else
|
||||
typechar = q1; /* look at last char for tag */
|
||||
switch (typechar) {
|
||||
case 'f': case 'F': case '.': type = 'f'; break; /* float */
|
||||
case 'd': case 'D': type = 'd'; break; /* double */
|
||||
case 'b': case 'B': type = 'b'; break; /* byte */
|
||||
case 's': case 'S': type = 's'; break; /* short */
|
||||
case 'l': case 'L': type = 'l'; break; /* long long */
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
|
||||
case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* unsigned int */
|
||||
case '\0': type = 'i'; break;
|
||||
default: break;
|
||||
}
|
||||
if(isunsignedp) *isunsignedp = isunsigned;
|
||||
return type;
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
/* Byte swap an 8-byte integer in place */
|
||||
static void
|
||||
byteswap8(unsigned char* mem)
|
||||
EXTERNL
|
||||
void
|
||||
NC_byteswap8(unsigned char* mem)
|
||||
{
|
||||
unsigned char c;
|
||||
c = mem[0];
|
||||
|
@ -1,9 +1,12 @@
|
||||
# Test c output
|
||||
T=test_filter_misc
|
||||
#SRC=hdf5plugins/H5Zmisc.c
|
||||
|
||||
#CMD=valgrind --leak-check=full
|
||||
CMD=gdb --args
|
||||
|
||||
FILTER=H5Zmisc
|
||||
#FILTER=H5Zmisc
|
||||
#FILTEROBJ=hdf5plugins/${FILTER}.o
|
||||
|
||||
#PAR=1
|
||||
#SZIP=1
|
||||
@ -31,7 +34,7 @@ all:: cmp
|
||||
|
||||
cmp::
|
||||
export LD_LIBRARY_PATH=${LLP}; export CFLAGS; export LDFLAGS; \
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} hdf5plugins/${FILTER}.o ${LDFLAGS}
|
||||
${CC} -o t ${CFLAGS} ${T}.c ${SRC} ${FILTEROBJ} ${LDFLAGS}
|
||||
|
||||
filter::
|
||||
${CC} ${CFLAGS} -c hdf5plugins/${FILTER}.c ${LDFLAGS}
|
||||
|
@ -13,6 +13,12 @@
|
||||
|
||||
#include "h5misc.h"
|
||||
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
static int paramcheck(size_t nparams, const unsigned int* params);
|
||||
@ -119,72 +125,88 @@ paramcheck(size_t nparams, const unsigned int* params)
|
||||
|
||||
if(nparams != 14) {
|
||||
fprintf(stderr,"Too few parameters: need=16 sent=%ld\n",(unsigned long)nparams);
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for(i=0;i<nparams;i++) {
|
||||
unsigned int ival;
|
||||
unsigned long long lval;
|
||||
float fval;
|
||||
double dval;
|
||||
switch (i) {
|
||||
case 0: break; /* this is the testcase # */
|
||||
case 1: if(((signed char)-17) != (signed int)(params[i]))
|
||||
{mismatch(i,"signed byte"); return 0; };
|
||||
case 1:
|
||||
ival = (-17) & 0xff;
|
||||
if(ival != (signed int)(params[i]))
|
||||
{mismatch(i,"signed byte"); goto fail; };
|
||||
break;
|
||||
case 2: if(((unsigned char)23) != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned byte"); return 0; };
|
||||
case 2:
|
||||
ival = 23;
|
||||
if(ival != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned byte"); goto fail; };
|
||||
break;
|
||||
case 3: if(((signed short)-25) != (signed int)(params[i]))
|
||||
{mismatch(i,"signed short"); return 0; };
|
||||
case 3:
|
||||
ival = (-25) & 0xffff;
|
||||
if(ival != (signed int)(params[i]))
|
||||
{mismatch(i,"signed short"); goto fail; };
|
||||
break;
|
||||
case 4: if(((unsigned short)27) != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned short"); return 0; };
|
||||
case 4:
|
||||
ival = 27;
|
||||
if(ival != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned short"); goto fail; };
|
||||
break;
|
||||
case 5: if(77 != (signed int)(params[i]))
|
||||
{mismatch(i,"signed int"); return 0; };
|
||||
case 5:
|
||||
ival = 77;
|
||||
if(ival != (signed int)(params[i]))
|
||||
{mismatch(i,"signed int"); goto fail; };
|
||||
break;
|
||||
case 6: if(93u != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned int"); return 0; };
|
||||
case 6:
|
||||
ival = 93u;
|
||||
if(ival != (unsigned int)(params[i]))
|
||||
{mismatch(i,"unsigned int"); goto fail; };
|
||||
break;
|
||||
case 7: if(789.0f != *(float*)(¶ms[i]))
|
||||
{mismatch(i,"float"); return 0; };
|
||||
case 7:
|
||||
fval = 789.0f;
|
||||
if(fval != *(float*)(¶ms[i]))
|
||||
{mismatch(i,"float"); goto fail; };
|
||||
break;
|
||||
case 8: {/*double*/
|
||||
double x = *(double*)¶ms[i];
|
||||
dval = DBLVAL;
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
if(DBLVAL != x) {
|
||||
if(dval != x) {
|
||||
mismatch(i,"double");
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
}; break;
|
||||
case 10: {/*signed long long*/
|
||||
signed long long x = *(signed long long*)¶ms[i];
|
||||
lval = -9223372036854775807L;
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
if(-9223372036854775807L != x) {
|
||||
if(lval != x) {
|
||||
mismatch(i,"signed long long");
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
}; break;
|
||||
case 12: {/*unsigned long long*/
|
||||
unsigned long long x = *(unsigned long long*)¶ms[i];
|
||||
lval = 18446744073709551615UL;
|
||||
i++; /* takes two parameters */
|
||||
if(bigendian)
|
||||
byteswap8((unsigned char*)&x);
|
||||
if(18446744073709551615UL != x) {
|
||||
if(lval != x) {
|
||||
mismatch(i,"unsigned long long");
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
}; break;
|
||||
|
||||
default:
|
||||
mismatch(i,"unexpected parameter");
|
||||
return 0;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -200,6 +222,8 @@ paramcheck(size_t nparams, const unsigned int* params)
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -11,15 +11,21 @@
|
||||
#include <hdf5.h>
|
||||
#include "netcdf.h"
|
||||
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
|
||||
#define TEST_ID 32768
|
||||
|
||||
#define MAXERRS 8
|
||||
|
||||
#define MAXPARAMS 32
|
||||
|
||||
#define NBASELINE 14
|
||||
#define NPARAMS 14
|
||||
|
||||
static unsigned int baseline[NBASELINE];
|
||||
static unsigned int baseline[NPARAMS];
|
||||
|
||||
#define MAXDIMS 8
|
||||
|
||||
@ -29,6 +35,8 @@ static unsigned int baseline[NBASELINE];
|
||||
|
||||
#define TESTFILE "testmisc.nc"
|
||||
|
||||
#define spec "32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL"
|
||||
|
||||
static size_t dimsize = DEFAULTDIMSIZE;
|
||||
static size_t chunksize = DEFAULTCHUNKSIZE;
|
||||
static size_t actualdims = DEFAULTACTUALDIMS;
|
||||
@ -131,7 +139,7 @@ create(void)
|
||||
static void
|
||||
setvarfilter(void)
|
||||
{
|
||||
CHECK(nc_def_var_filter(ncid,varid,TEST_ID,NBASELINE,baseline));
|
||||
CHECK(nc_def_var_filter(ncid,varid,TEST_ID,NPARAMS,baseline));
|
||||
verifyparams();
|
||||
}
|
||||
|
||||
@ -141,7 +149,7 @@ verifyparams(void)
|
||||
int i;
|
||||
CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
|
||||
if(filterid != TEST_ID) REPORT("id mismatch");
|
||||
if(nparams != NBASELINE) REPORT("nparams mismatch");
|
||||
if(nparams != NPARAMS) REPORT("nparams mismatch");
|
||||
for(i=0;i<nparams;i++) {
|
||||
if(params[i] != baseline[i])
|
||||
REPORT("param mismatch");
|
||||
@ -166,16 +174,16 @@ openfile(void)
|
||||
CHECK(nc_inq_var_filter(ncid,varid,&filterid,&nparams,params));
|
||||
}
|
||||
if(filterid != TEST_ID) {
|
||||
printf("open: test id mismatch: %d\n",filterid);
|
||||
fprintf(stderr,"open: test id mismatch: %d\n",filterid);
|
||||
return NC_EFILTER;
|
||||
}
|
||||
if(nparams != NBASELINE) {
|
||||
if(nparams != NPARAMS) {
|
||||
size_t i;
|
||||
unsigned int inqparams[MAXPARAMS];
|
||||
printf("nparams mismatch\n");
|
||||
fprintf(stderr,"nparams mismatch\n");
|
||||
for(nerrs=0,i=0;i<nparams;i++) {
|
||||
if(inqparams[i] != baseline[i]) {
|
||||
printf("open: testparam mismatch: %ld\n",(unsigned long)i);
|
||||
fprintf(stderr,"open: testparam mismatch: %ld\n",(unsigned long)i);
|
||||
nerrs++;
|
||||
}
|
||||
}
|
||||
@ -231,7 +239,7 @@ compare(void)
|
||||
int i;
|
||||
for(i=0;i<actualproduct;i++) {
|
||||
if(expected[i] != array[i]) {
|
||||
fprintf(stderr,"mismatch: array[%d]=%f expected[%d]=%f\n",
|
||||
fprintf(stderr,"data mismatch: array[%d]=%f expected[%d]=%f\n",
|
||||
i,array[i],i,expected[i]);
|
||||
errs++;
|
||||
if(errs >= MAXERRS)
|
||||
@ -245,7 +253,7 @@ compare(void)
|
||||
int offset = odom_offset();
|
||||
float expect = expectedvalue();
|
||||
if(array[offset] != expect) {
|
||||
fprintf(stderr,"mismatch: array[%d]=%f expected=%f\n",
|
||||
fprintf(stderr,"data mismatch: array[%d]=%f expected=%f\n",
|
||||
offset,array[offset],expect);
|
||||
errs++;
|
||||
if(errs >= MAXERRS)
|
||||
@ -264,14 +272,15 @@ static void
|
||||
showparameters(void)
|
||||
{
|
||||
int i;
|
||||
printf("test: nparams=%ld: params=",(unsigned long)nparams);
|
||||
fprintf(stderr,"test: nparams=%ld: params=",(unsigned long)nparams);
|
||||
for(i=0;i<nparams;i++) {
|
||||
printf(" %u",params[i]);
|
||||
fprintf(stderr," %u",params[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr,"\n");
|
||||
for(i=0;i<actualdims;i++)
|
||||
printf("%s%ld",(i==0?" chunks=":","),(unsigned long)chunks[i]);
|
||||
printf("\n");
|
||||
fprintf(stderr,"%s%ld",(i==0?" chunks=":","),(unsigned long)chunks[i]);
|
||||
fprintf(stderr,"\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -292,11 +301,11 @@ buildbaseline(unsigned int testcasenumber)
|
||||
baseline[0] = testcasenumber;
|
||||
switch (testcasenumber) {
|
||||
case 1:
|
||||
val4 = (unsigned int)-17;
|
||||
val4 = ((unsigned int)-17) & 0xff;
|
||||
insert(1,&val4,sizeof(val4)); /* 1 signed int*/
|
||||
val4 = (unsigned int)23;
|
||||
insert(2,&val4,sizeof(val4)); /* 2 unsigned int*/
|
||||
val4 = (unsigned int)-25;
|
||||
val4 = ((unsigned int)-25) & 0xffff;
|
||||
insert(3,&val4,sizeof(val4)); /* 3 signed int*/
|
||||
val4 = (unsigned int)27;
|
||||
insert(4,&val4,sizeof(val4)); /* 4 unsigned int*/
|
||||
@ -306,11 +315,6 @@ buildbaseline(unsigned int testcasenumber)
|
||||
insert(6,&val4,sizeof(val4)); /* 6 unsigned int*/
|
||||
float4 = 789.0f;
|
||||
insert(7,&float4,sizeof(float4)); /* 7 float */
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
float8 = DBLVAL;
|
||||
insert(8,&float8,sizeof(float8)); /* 8 double */
|
||||
val8 = -9223372036854775807L;
|
||||
@ -333,7 +337,7 @@ test_test1(void)
|
||||
|
||||
buildbaseline(1);
|
||||
|
||||
printf("test1: compression.\n");
|
||||
fprintf(stderr,"test1: compression.\n");
|
||||
create();
|
||||
setchunking();
|
||||
setvarfilter();
|
||||
@ -346,7 +350,7 @@ test_test1(void)
|
||||
CHECK(nc_put_var(ncid,varid,expected));
|
||||
CHECK(nc_close(ncid));
|
||||
|
||||
printf("test1: decompression.\n");
|
||||
fprintf(stderr,"test1: decompression.\n");
|
||||
reset();
|
||||
openfile();
|
||||
CHECK(nc_get_var_float(ncid, varid, array));
|
||||
@ -441,6 +445,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
H5Eprint(stderr);
|
||||
nc_set_log_level(1);
|
||||
init(argc,argv);
|
||||
if(!test_test1()) ERRR;
|
||||
exit(nerrs > 0?1:0);
|
||||
|
@ -3,8 +3,6 @@
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
set -e
|
||||
|
||||
# Which test cases to exercise
|
||||
API=1
|
||||
NG=1
|
||||
@ -79,7 +77,7 @@ rm -f ./tmp
|
||||
trimleft ./tmp2 ./tmp
|
||||
rm -f ./tmp2
|
||||
cat >./tmp2 <<EOF
|
||||
var:_Filter = "32768,1,4294967279,23,4294967271,27,77,93,1145389056,3287505826,1097305129,1,2147483648,4294967295,4294967295" ;
|
||||
var:_Filter = "32768,1,239,23,65511,27,77,93,1145389056,3287505826,1097305129,1,2147483648,4294967295,4294967295" ;
|
||||
EOF
|
||||
diff -b -w ./tmp ./tmp2
|
||||
echo "*** Pass: parameter passing"
|
||||
|
@ -11,30 +11,28 @@
|
||||
#include "netcdf.h"
|
||||
#include "ncfilter.h"
|
||||
|
||||
#undef USE_INTERNAL
|
||||
|
||||
#define PARAMS_ID 32768
|
||||
|
||||
static const unsigned int baseline[] = {
|
||||
-17, /* 0 signed int*/
|
||||
23, /* 1 unsigned int*/
|
||||
-25, /* 2 signed int*/
|
||||
27, /* 3 unsigned int*/
|
||||
77, /* 4 signed int*/
|
||||
93, /* 5 unsigned int*/
|
||||
1145389056U, /* 6 float*/
|
||||
3287505826, 1097305129, /* 7-8 double*/
|
||||
1, 2147483648, /* 9-10 signed long long*/
|
||||
4294967295, 4294967295, /* 11-12 unsigned long long*/
|
||||
/* Edge cases */
|
||||
2147483647, /* 13 max signed int*/
|
||||
-2147483648, /* 14 min signed int*/
|
||||
4294967295 /* 15 max unsigned int with no trailing U*/
|
||||
};
|
||||
#if defined _MSC_VER || defined __APPLE__
|
||||
#define DBLVAL 12345678.12345678
|
||||
#else
|
||||
#define DBLVAL 12345678.12345678d
|
||||
#endif
|
||||
|
||||
#define MAXPARAMS 32
|
||||
#define NPARAMS 16 /* # of unsigned ints in params */
|
||||
|
||||
static unsigned int baseline[NPARAMS];
|
||||
|
||||
/* Expected contents of baseline:
|
||||
id = 32768
|
||||
params = 4294967279, 23, 4294967271, 27, 77, 93, 1145389056, 3287505826, 1097305129, 1, 2147483648, 4294967295, 4294967295
|
||||
*/
|
||||
|
||||
static const char* spec =
|
||||
"32768, -17b, 23ub, -25S, 27US, 77, 93U, 789f, 12345678.12345678d, -9223372036854775807L, 18446744073709551615UL, 2147483647, -2147483648, 4294967295";
|
||||
|
||||
|
||||
/* Test support for the conversions */
|
||||
/* Not sure if this kind of casting via union is legal C99 */
|
||||
static union {
|
||||
@ -55,30 +53,66 @@ static union {
|
||||
|
||||
static int nerrs = 0;
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
static int parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp);
|
||||
#endif
|
||||
|
||||
#ifdef WORD_BIGENDIAN
|
||||
static void byteswap8(unsigned char* mem);
|
||||
#endif
|
||||
|
||||
static void
|
||||
report(const char* which)
|
||||
mismatch(size_t i, unsigned int *params, const char* tag)
|
||||
{
|
||||
fprintf(stderr,"mismatch: %s\n",which);
|
||||
fprintf(stderr,"mismatch: %s [%d] baseline=%ud params=%u\n",tag,(int)i,baseline[i],params[i]);
|
||||
fflush(stderr);
|
||||
nerrs++;
|
||||
}
|
||||
|
||||
static void
|
||||
mismatch(size_t i, unsigned int baseline, unsigned int params)
|
||||
mismatch2(size_t i, unsigned int *params, const char* tag)
|
||||
{
|
||||
fprintf(stderr,"mismatch: [%d] baseline=%ud spec=%ud\n",(int)i,baseline,params);
|
||||
fprintf(stderr,"mismatch2: %s [%d-%d] baseline=%ud,%ud params=%u,%u\n",
|
||||
tag,(int)i,i+1,baseline[i],baseline[i+1],params[i],params[i+1]);
|
||||
fflush(stderr);
|
||||
nerrs++;
|
||||
}
|
||||
|
||||
static void
|
||||
insert(int index, void* src, size_t size)
|
||||
{
|
||||
void* dst = &baseline[index];
|
||||
memcpy(dst,src,size);
|
||||
}
|
||||
|
||||
static void
|
||||
buildbaseline(void)
|
||||
{
|
||||
unsigned int val4;
|
||||
unsigned long long val8;
|
||||
float float4;
|
||||
double float8;
|
||||
|
||||
val4 = ((unsigned int)-17) & 0xff;
|
||||
insert(0,&val4,sizeof(val4)); /* 0 signed int*/
|
||||
val4 = (unsigned int)23;
|
||||
insert(1,&val4,sizeof(val4)); /* 1 unsigned int*/
|
||||
val4 = ((unsigned int)-25) & 0xffff;
|
||||
insert(2,&val4,sizeof(val4)); /* 3 signed int*/
|
||||
val4 = (unsigned int)27;
|
||||
insert(3,&val4,sizeof(val4)); /* 4 unsigned int*/
|
||||
val4 = (unsigned int)77;
|
||||
insert(4,&val4,sizeof(val4)); /* 4 signed int*/
|
||||
val4 = (unsigned int)93;
|
||||
insert(5,&val4,sizeof(val4)); /* 5 unsigned int*/
|
||||
float4 = 789.0f;
|
||||
insert(6,&float4,sizeof(float4)); /* 6 float */
|
||||
float8 = DBLVAL;
|
||||
insert(7,&float8,sizeof(float8)); /* 7 double */
|
||||
val8 = -9223372036854775807L;
|
||||
insert(9,&val8,sizeof(val8)); /* 9 signed long long */
|
||||
val8 = 18446744073709551615UL;
|
||||
insert(11,&val8,sizeof(val8)); /* 11 unsigned long long */
|
||||
val4 = 2147483647;
|
||||
insert(13,&val4,sizeof(val4)); /* 13 signed int */
|
||||
val4 = -2147483648;
|
||||
insert(14,&val4,sizeof(val4)); /* 14 signed int */
|
||||
val4 = 4294967295;
|
||||
insert(15,&val4,sizeof(val4)); /* 15 unsigned int */
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -90,44 +124,44 @@ main(int argc, char **argv)
|
||||
|
||||
printf("\nTesting filter parser.\n");
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
stat = parsefilterspec(spec,&id,&nparams,¶ms);
|
||||
#else
|
||||
buildbaseline(); /* Build our comparison vector */
|
||||
|
||||
stat = NC_parsefilterspec(spec,&id,&nparams,¶ms);
|
||||
#endif
|
||||
if(!stat) {
|
||||
report("NC_parsefilterspec failed");
|
||||
if(stat) {
|
||||
fprintf(stderr,"NC_parsefilterspec failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if(id != PARAMS_ID)
|
||||
fprintf(stderr,"mismatch: id: expected=%u actual=%u\n",PARAMS_ID,id);
|
||||
for(i=0;i<nparams;i++) {
|
||||
if(baseline[i] != params[i])
|
||||
mismatch(i,baseline[i],params[i]);
|
||||
mismatch(i,params,"N.A.");
|
||||
}
|
||||
/* Now some specialized tests */
|
||||
uf.ui = params[6];
|
||||
if(uf.f != (float)789.0)
|
||||
report("uf.f");
|
||||
mismatch(6,params,"uf.f");
|
||||
ud.ui[0] = params[7];
|
||||
ud.ui[1] = params[8];
|
||||
#ifdef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ud.d);
|
||||
#endif
|
||||
if(ud.d != (double)12345678.12345678)
|
||||
report("ud.d");
|
||||
if(ud.d != DBLVAL)
|
||||
mismatch2(7,params,"ud.d");
|
||||
ul.ui[0] = params[9];
|
||||
ul.ui[1] = params[10];
|
||||
#ifdef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ul.ll);
|
||||
#endif
|
||||
if(ul.ll != -9223372036854775807LL)
|
||||
report("ul.ll");
|
||||
mismatch2(9,params,"ul.ll");
|
||||
ul.ui[0] = params[11];
|
||||
ul.ui[1] = params[12];
|
||||
#ifdef WORD_BIGENDIAN
|
||||
byteswap8((unsigned char*)&ul.ull);
|
||||
#endif
|
||||
if(ul.ull != 18446744073709551615ULL)
|
||||
report("ul.ull");
|
||||
mismatch2(11,params,"ul.ull");
|
||||
|
||||
if (params)
|
||||
free(params);
|
||||
@ -158,146 +192,3 @@ byteswap8(unsigned char* mem)
|
||||
mem[4] = c;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_INTERNAL
|
||||
static int
|
||||
parsefilterspec(const char* spec, unsigned int* idp, size_t* nparamsp, unsigned int** paramsp)
|
||||
{
|
||||
char* p;
|
||||
char* sdata = NULL;
|
||||
int stat;
|
||||
unsigned int uval, id;
|
||||
size_t count; /* no. of comma delimited params */
|
||||
size_t nparams; /* final no. of unsigned ints */
|
||||
size_t i;
|
||||
unsigned int* ulist = NULL;
|
||||
unsigned char mem[8]; /* to convert to network byte order */
|
||||
|
||||
if(spec == NULL || strlen(spec) == 0) goto fail;
|
||||
sdata = strdup(spec);
|
||||
|
||||
/* Count number of parameters + id and delimit */
|
||||
p=sdata;
|
||||
for(count=0;;count++) {
|
||||
char* q = strchr(p,',');
|
||||
if(q == NULL) break;
|
||||
*q++ = '\0';
|
||||
p = q;
|
||||
}
|
||||
count++; /* for final piece */
|
||||
|
||||
if(count == 0)
|
||||
goto fail; /* no id and no parameters */
|
||||
|
||||
/* Extract the filter id */
|
||||
p = sdata;
|
||||
stat = sscanf(p,"%u",&id);
|
||||
if(stat != 1) goto fail;
|
||||
p = p + strlen(p) + 1; /* skip the filter id */
|
||||
count--;
|
||||
|
||||
/* Allocate the max needed space; *2 in case the params are all doubles */
|
||||
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count)*2);
|
||||
if(ulist == NULL) goto fail;
|
||||
|
||||
/* walk and convert */
|
||||
nparams = 0;
|
||||
for(i=0;i<count;i++) {
|
||||
char* q;
|
||||
unsigned long long val64u;
|
||||
unsigned int val32u;
|
||||
double vald;
|
||||
float valf;
|
||||
unsigned int *vector;
|
||||
int isunsigned;
|
||||
int isnegative;
|
||||
int type;
|
||||
|
||||
/* Get trailing discrimination characters */
|
||||
isunsigned = 0;
|
||||
isnegative = 0;
|
||||
type = 0;
|
||||
if(strchr(p,'-') != NULL) isnegative = 1;
|
||||
q = p+strlen(p)-2;
|
||||
if(*q == 'U' || *q == 'u') isunsigned = 1;
|
||||
q++;
|
||||
switch (*q) {
|
||||
case 'f': case 'F': type = 'f'; break; /* short */
|
||||
case 'd': case 'D': type = 'd'; break; /* double */
|
||||
case 'b': case 'B': type = 'b'; break; /* byte */
|
||||
case 's': case 'S': type = 's'; break; /* short */
|
||||
case 'l': case 'L': type = 'l'; break; /* long long */
|
||||
case 'u': case 'U': type = 'i'; isunsigned = 1; break; /* integer */
|
||||
case '.':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': type = 'i'; break;
|
||||
default:
|
||||
if(*q == '\0')
|
||||
type = 'i';
|
||||
else goto fail;
|
||||
}
|
||||
/* Now parse */
|
||||
switch (type) {
|
||||
case 'b':
|
||||
case 's':
|
||||
case 'i':
|
||||
/* special case for a positive integer;for back compatibility.*/
|
||||
if(!isnegative)
|
||||
stat = sscanf(p,"%u",&val32u);
|
||||
else
|
||||
stat = sscanf(p,"%d",(int*)&val32u);
|
||||
if(stat != 1) goto fail;
|
||||
ulist[nparams++] = val32u;
|
||||
break;
|
||||
case 'f':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
valf = (float)vald;
|
||||
ulist[nparams++] = *(unsigned int*)&valf;
|
||||
break;
|
||||
case 'd':
|
||||
stat = sscanf(p,"%lf",&vald);
|
||||
if(stat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&vald,sizeof(mem));
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
byteswap8(mem); /* convert little endian to big endian */
|
||||
#endif
|
||||
vector = (unsigned int*)mem;
|
||||
ulist[nparams++] = vector[0];
|
||||
ulist[nparams++] = vector[1];
|
||||
break;
|
||||
case 'l': /* long long */
|
||||
if(isunsigned)
|
||||
stat = sscanf(p,"%llu",&val64u);
|
||||
else
|
||||
stat = sscanf(p,"%lld",(long long*)&val64u);
|
||||
if(stat != 1) goto fail;
|
||||
/* convert to network byte order */
|
||||
memcpy(mem,&val64u,sizeof(mem));
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
byteswap8(mem); /* convert little endian to big endian */
|
||||
#endif
|
||||
vector = (unsigned int*)mem;
|
||||
ulist[nparams++] = vector[0];
|
||||
ulist[nparams++] = vector[1];
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
p = p + strlen(p) + 1; /* move to next param */
|
||||
}
|
||||
/* Now return results */
|
||||
if(idp) *idp = id;
|
||||
if(nparamsp) *nparamsp = nparams;
|
||||
if(paramsp) *paramsp = ulist;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 1;
|
||||
fail:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 0;
|
||||
}
|
||||
#endif /*USE_INTERNAL*/
|
||||
|
@ -233,6 +233,7 @@ done:
|
||||
static int
|
||||
parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
char* optarg = NULL;
|
||||
unsigned int* params = NULL;
|
||||
size_t nparams;
|
||||
@ -263,14 +264,14 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
}
|
||||
|
||||
/* Collect the id+parameters */
|
||||
if(!NC_parsefilterspec(remainder,&id,&nparams,¶ms))
|
||||
return 0;
|
||||
if(spec != NULL) {
|
||||
spec->filterid = id;
|
||||
spec->nparams = nparams;
|
||||
spec->params = params;
|
||||
if((stat = NC_parsefilterspec(remainder,&id,&nparams,¶ms)) == NC_NOERR) {
|
||||
if(spec != NULL) {
|
||||
spec->filterid = id;
|
||||
spec->nparams = nparams;
|
||||
spec->params = params;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
@ -1969,7 +1970,8 @@ main(int argc, char**argv)
|
||||
break;
|
||||
case 'F': /* optional filter spec for a specified variable */
|
||||
#ifdef USE_NETCDF4
|
||||
if(!parsefilterspec(optarg,&filterspec)) usage();
|
||||
if(parsefilterspec(optarg,&filterspec) != NC_NOERR)
|
||||
usage();
|
||||
if(nfilterspecs >= (MAX_FILTER_SPECS-1))
|
||||
error("too many -F filterspecs\n");
|
||||
filterspecs[nfilterspecs] = filterspec;
|
||||
@ -2015,7 +2017,6 @@ main(int argc, char**argv)
|
||||
#endif /*DEBUGFILTER*/
|
||||
#endif /*USE_NETCDF4*/
|
||||
|
||||
|
||||
if(copy(inputfile, outputfile) != NC_NOERR)
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -141,8 +141,8 @@ typedef struct Specialdata {
|
||||
int _Endianness; /* 1 =>little, 2 => big*/
|
||||
int _Fill ; /* 0 => false, 1 => true WATCHOUT: this is inverse of NOFILL*/
|
||||
unsigned int _FilterID;
|
||||
unsigned int* _FilterParams; /* NULL => defaults*/
|
||||
size_t nparams; /* |_FilterParms| ; 0 => not specified*/
|
||||
size_t nparams; /* |_FilterParms| ; 0 => not specified*/
|
||||
unsigned int* _FilterParams; /* NULL => defaults*/
|
||||
} Specialdata;
|
||||
|
||||
typedef struct GlobalSpecialdata {
|
||||
|
@ -1330,8 +1330,12 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
|
||||
} break;
|
||||
case _FILTER_FLAG:
|
||||
/* Parse the filter spec */
|
||||
if(parsefilterflag(sdata,special))
|
||||
if(parsefilterflag(sdata,special) == NC_NOERR)
|
||||
special->flags |= _FILTER_FLAG;
|
||||
else {
|
||||
efree(special->_FilterParams);
|
||||
derror("_Filter: unparseable filter spec: %s",sdata);
|
||||
}
|
||||
break;
|
||||
default: PANIC1("makespecial: illegal token: %d",tag);
|
||||
}
|
||||
@ -1448,55 +1452,15 @@ Parse a filter spec string and store it in special
|
||||
static int
|
||||
parsefilterflag(const char* sdata0, Specialdata* special)
|
||||
{
|
||||
char* p;
|
||||
char* sdata = NULL;
|
||||
int stat;
|
||||
size_t count;
|
||||
unsigned int* ulist = NULL;
|
||||
int stat = NC_NOERR;
|
||||
|
||||
if(sdata0 == NULL || strlen(sdata0) == 0) goto fail;
|
||||
sdata = strdup(sdata0);
|
||||
|
||||
/* Count number of unsigned integers and delimit */
|
||||
p=sdata;
|
||||
for(count=0;;count++) {
|
||||
char* q = strchr(p,',');
|
||||
if(q == NULL) break;
|
||||
*q++ = '\0'; /* delimit */
|
||||
p = q;
|
||||
}
|
||||
count++; /* for final piece */
|
||||
|
||||
/* Start by collecting the filter id */
|
||||
p = sdata;
|
||||
stat = sscanf(p,"%u",&special->_FilterID);
|
||||
if(stat != 1) goto fail;
|
||||
count--; /* actual param count minus the id */
|
||||
|
||||
ulist = (unsigned int*)malloc(sizeof(unsigned int)*(count));
|
||||
if(ulist == NULL) goto fail;
|
||||
|
||||
special->nparams = count;
|
||||
for(count=0;count < special->nparams ;) {
|
||||
unsigned int uval;
|
||||
p = p + strlen(p) + 1; /* move to next param */
|
||||
stat = sscanf(p,"%u",&uval);
|
||||
if(stat != 1) goto fail;
|
||||
ulist[count++] = uval;
|
||||
}
|
||||
special->_FilterParams = ulist;
|
||||
ulist = NULL; /* avoid duplicate free */
|
||||
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
return 1;
|
||||
fail:
|
||||
if(sdata) free(sdata);
|
||||
if(ulist) free(ulist);
|
||||
if(special) special->_FilterID = 0;
|
||||
derror("Malformed filter spec: %s",sdata);
|
||||
|
||||
return 0;
|
||||
stat = NC_parsefilterspec(sdata0, &special->_FilterID, &special->nparams, &special->_FilterParams);
|
||||
if(stat)
|
||||
derror("Malformed filter spec: %s",sdata);
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user