mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-26 04:09:39 +03:00
Makes testing parameters specified with AddTest non-const again when passed to test functions. This allows test functions to update their parameters during execution and is particularly useful for tests which use those parameters to accumulate statistics, error counts, etc. without resorting to global variables.
766 lines
27 KiB
C++
766 lines
27 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* 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 LICENSE file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*****************************************************************************
|
|
FILE
|
|
tcompound.cpp - HDF5 C++ testing the compound data type functionality
|
|
|
|
***************************************************************************/
|
|
#include <iostream>
|
|
using std::cerr;
|
|
using std::endl;
|
|
|
|
#include <string>
|
|
#include "H5Cpp.h" // C++ API header file
|
|
using namespace H5;
|
|
|
|
#include "h5test.h"
|
|
#include "h5cpputil.h" // C++ utilility header file
|
|
|
|
/* Number of elements in each test */
|
|
#define NTESTELEM 100000
|
|
|
|
typedef struct complex_t {
|
|
double re;
|
|
double im;
|
|
} complex_t;
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_1
|
|
*
|
|
* Purpose Tests various things about compound data types.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_1()
|
|
{
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Data Types");
|
|
try {
|
|
// Create an empty compound datatype
|
|
CompType complex_type(sizeof(complex_t));
|
|
|
|
// Add a couple of fields
|
|
complex_type.insertMember("real", HOFFSET(complex_t, re), PredType::NATIVE_DOUBLE);
|
|
complex_type.insertMember("imaginary", HOFFSET(complex_t, im), PredType::NATIVE_DOUBLE);
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
} // test_compound_1()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_2
|
|
*
|
|
* Purpose Tests a compound type conversion where the source and
|
|
* destination are the same except for the order of the
|
|
* elements.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_2()
|
|
{
|
|
typedef struct {
|
|
int a, b, c[4], d, e;
|
|
} src_typ_t;
|
|
typedef struct {
|
|
int e, d, c[4], b, a;
|
|
} dst_typ_t;
|
|
|
|
src_typ_t *s_ptr;
|
|
dst_typ_t *d_ptr;
|
|
const int nelmts = NTESTELEM;
|
|
const hsize_t four = 4;
|
|
int i;
|
|
unsigned char *buf = NULL, *orig = NULL, *bkg = NULL;
|
|
ArrayType *array_dt = NULL;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Element Reordering");
|
|
try {
|
|
// Sizes should be the same, but be careful just in case
|
|
buf = static_cast<unsigned char *>(malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t))));
|
|
bkg = static_cast<unsigned char *>(malloc(nelmts * sizeof(dst_typ_t)));
|
|
orig = static_cast<unsigned char *>(malloc(nelmts * sizeof(src_typ_t)));
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
s_ptr->a = i * 8 + 0;
|
|
s_ptr->b = i * 8 + 1;
|
|
s_ptr->c[0] = i * 8 + 2;
|
|
s_ptr->c[1] = i * 8 + 3;
|
|
s_ptr->c[2] = i * 8 + 4;
|
|
s_ptr->c[3] = i * 8 + 5;
|
|
s_ptr->d = i * 8 + 6;
|
|
s_ptr->e = i * 8 + 7;
|
|
}
|
|
memcpy(buf, orig, nelmts * sizeof(src_typ_t));
|
|
|
|
// Build hdf5 datatypes
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType st(sizeof(src_typ_t));
|
|
st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
|
|
st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
|
|
st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
|
|
st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
|
|
st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
delete array_dt;
|
|
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType dt(sizeof(dst_typ_t));
|
|
dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
|
|
dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_INT);
|
|
dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
|
|
dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_INT);
|
|
dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
|
|
// Perform the conversion
|
|
st.convert(dt, static_cast<size_t>(nelmts), buf, bkg);
|
|
|
|
// Compare results
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
d_ptr = (reinterpret_cast<dst_typ_t *>(buf)) + i;
|
|
if (s_ptr->a != d_ptr->a || s_ptr->b != d_ptr->b || s_ptr->c[0] != d_ptr->c[0] ||
|
|
s_ptr->c[1] != d_ptr->c[1] || s_ptr->c[2] != d_ptr->c[2] || s_ptr->c[3] != d_ptr->c[3] ||
|
|
s_ptr->d != d_ptr->d || s_ptr->e != d_ptr->e) {
|
|
H5_FAILED();
|
|
cerr << " i=" << i << endl;
|
|
cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b << "c=[" << s_ptr->c[0] << ","
|
|
<< s_ptr->c[1] << "," << s_ptr->c[2] << "," << s_ptr->c[3] << ", d=" << s_ptr->d
|
|
<< ", e=" << s_ptr->e << "}" << endl;
|
|
cerr << " dst={a=" << s_ptr->a << ", b=" << s_ptr->b << "c=[" << s_ptr->c[0] << ","
|
|
<< s_ptr->c[1] << "," << s_ptr->c[2] << "," << s_ptr->c[3] << ", d=" << s_ptr->d
|
|
<< ", e=" << s_ptr->e << "}" << endl;
|
|
}
|
|
}
|
|
// Release resources
|
|
free(buf);
|
|
free(bkg);
|
|
free(orig);
|
|
s_ptr = NULL;
|
|
d_ptr = NULL;
|
|
st.close();
|
|
dt.close();
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
delete array_dt;
|
|
} // test_compound_2()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_3
|
|
*
|
|
* Purpose Tests compound conversions where the source and destination
|
|
* are the same except the destination is missing a couple
|
|
* members which appear in the source.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_3()
|
|
{
|
|
typedef struct {
|
|
int a, b, c[4], d, e;
|
|
} src_typ_t;
|
|
typedef struct {
|
|
int a, c[4], e;
|
|
} dst_typ_t;
|
|
|
|
src_typ_t *s_ptr;
|
|
dst_typ_t *d_ptr;
|
|
int i;
|
|
const int nelmts = NTESTELEM;
|
|
const hsize_t four = 4;
|
|
unsigned char *buf = NULL, *orig = NULL, *bkg = NULL;
|
|
ArrayType *array_dt = NULL;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Datatype Subset Conversions");
|
|
try {
|
|
/* Initialize */
|
|
buf = static_cast<unsigned char *>(malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t))));
|
|
bkg = static_cast<unsigned char *>(malloc(nelmts * sizeof(dst_typ_t)));
|
|
orig = static_cast<unsigned char *>(malloc(nelmts * sizeof(src_typ_t)));
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
s_ptr->a = i * 8 + 0;
|
|
s_ptr->b = i * 8 + 1;
|
|
s_ptr->c[0] = i * 8 + 2;
|
|
s_ptr->c[1] = i * 8 + 3;
|
|
s_ptr->c[2] = i * 8 + 4;
|
|
s_ptr->c[3] = i * 8 + 5;
|
|
s_ptr->d = i * 8 + 6;
|
|
s_ptr->e = i * 8 + 7;
|
|
}
|
|
memcpy(buf, orig, nelmts * sizeof(src_typ_t));
|
|
|
|
/* Build hdf5 datatypes */
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType st(sizeof(src_typ_t));
|
|
st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
|
|
st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
|
|
st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
|
|
st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
|
|
st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
delete array_dt;
|
|
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType dt(sizeof(dst_typ_t));
|
|
dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
|
|
dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
|
|
dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
|
|
/* Perform the conversion */
|
|
st.convert(dt, static_cast<size_t>(nelmts), buf, bkg);
|
|
|
|
/* Compare results */
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
d_ptr = (reinterpret_cast<dst_typ_t *>(buf)) + i;
|
|
if (s_ptr->a != d_ptr->a || s_ptr->c[0] != d_ptr->c[0] || s_ptr->c[1] != d_ptr->c[1] ||
|
|
s_ptr->c[2] != d_ptr->c[2] || s_ptr->c[3] != d_ptr->c[3] || s_ptr->e != d_ptr->e) {
|
|
H5_FAILED();
|
|
cerr << " i=" << i << endl;
|
|
cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b << ", c=[" << s_ptr->c[0] << ","
|
|
<< s_ptr->c[1] << "," << s_ptr->c[2] << "," << s_ptr->c[3] << "], d=" << s_ptr->d
|
|
<< ", e=" << s_ptr->e << "}" << endl;
|
|
cerr << " dst={a=" << d_ptr->a << ", c=[" << d_ptr->c[0] << "," << d_ptr->c[1] << ","
|
|
<< d_ptr->c[2] << "," << d_ptr->c[3] << "], e=" << d_ptr->e << "}" << endl;
|
|
}
|
|
}
|
|
|
|
/* Release resources */
|
|
free(buf);
|
|
free(bkg);
|
|
free(orig);
|
|
s_ptr = NULL;
|
|
d_ptr = NULL;
|
|
st.close();
|
|
dt.close();
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
delete array_dt;
|
|
} // test_compound_3()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_4
|
|
*
|
|
* Purpose Tests compound conversions when the destination has the same
|
|
* fields as the source but one or more of the fields are
|
|
* smaller.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_4()
|
|
{
|
|
|
|
typedef struct {
|
|
int a, b, c[4], d, e;
|
|
} src_typ_t;
|
|
|
|
typedef struct {
|
|
short b;
|
|
int a, c[4];
|
|
short d;
|
|
int e;
|
|
} dst_typ_t;
|
|
|
|
src_typ_t *s_ptr;
|
|
dst_typ_t *d_ptr;
|
|
int i;
|
|
const int nelmts = NTESTELEM;
|
|
const hsize_t four = 4;
|
|
unsigned char *buf = NULL, *orig = NULL, *bkg = NULL;
|
|
ArrayType *array_dt = NULL;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Element Shrinking & Reordering");
|
|
try {
|
|
/* Sizes should be the same, but be careful just in case */
|
|
buf = static_cast<unsigned char *>(malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t))));
|
|
bkg = static_cast<unsigned char *>(malloc(nelmts * sizeof(dst_typ_t)));
|
|
orig = static_cast<unsigned char *>(malloc(nelmts * sizeof(src_typ_t)));
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
s_ptr->a = i * 8 + 0;
|
|
s_ptr->b = (i * 8 + 1) & 0x7fff;
|
|
s_ptr->c[0] = i * 8 + 2;
|
|
s_ptr->c[1] = i * 8 + 3;
|
|
s_ptr->c[2] = i * 8 + 4;
|
|
s_ptr->c[3] = i * 8 + 5;
|
|
s_ptr->d = (i * 8 + 6) & 0x7fff;
|
|
s_ptr->e = i * 8 + 7;
|
|
}
|
|
memcpy(buf, orig, nelmts * sizeof(src_typ_t));
|
|
|
|
/* Build hdf5 datatypes */
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType st(sizeof(src_typ_t));
|
|
st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
|
|
st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
|
|
st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
|
|
st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
|
|
st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
delete array_dt;
|
|
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
|
|
|
|
// Create an empty compound datatype
|
|
CompType dt(sizeof(dst_typ_t));
|
|
dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
|
|
dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_SHORT);
|
|
dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
|
|
dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_SHORT);
|
|
dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
|
|
array_dt->close();
|
|
|
|
/* Perform the conversion */
|
|
st.convert(dt, static_cast<size_t>(nelmts), buf, bkg);
|
|
|
|
/* Compare results */
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
d_ptr = (reinterpret_cast<dst_typ_t *>(buf)) + i;
|
|
if (s_ptr->a != d_ptr->a || s_ptr->b != d_ptr->b || s_ptr->c[0] != d_ptr->c[0] ||
|
|
s_ptr->c[1] != d_ptr->c[1] || s_ptr->c[2] != d_ptr->c[2] || s_ptr->c[3] != d_ptr->c[3] ||
|
|
s_ptr->d != d_ptr->d || s_ptr->e != d_ptr->e) {
|
|
H5_FAILED();
|
|
cerr << " i=" << i << endl;
|
|
cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b << "c=[" << s_ptr->c[0] << ","
|
|
<< s_ptr->c[1] << "," << s_ptr->c[2] << "," << s_ptr->c[3] << ", d=" << s_ptr->d
|
|
<< ", e=" << s_ptr->e << "}" << endl;
|
|
cerr << " dst={a=" << d_ptr->a << ", b=" << d_ptr->b << "c=[" << d_ptr->c[0] << ","
|
|
<< d_ptr->c[1] << "," << d_ptr->c[2] << "," << d_ptr->c[3] << ", d=" << d_ptr->d
|
|
<< ", e=" << d_ptr->e << "}" << endl;
|
|
} // if
|
|
} // for
|
|
|
|
/* Release resources */
|
|
free(buf);
|
|
free(bkg);
|
|
free(orig);
|
|
s_ptr = NULL;
|
|
d_ptr = NULL;
|
|
st.close();
|
|
dt.close();
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
delete array_dt;
|
|
} // test_compound_4()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_5
|
|
*
|
|
* Purpose Many versions of HDF5 have a bug in the optimized compound
|
|
* datatype conversion function, H5T_conv_struct_opt(), which
|
|
* is triggered when the top-level type contains a struct
|
|
* which must undergo a conversion.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_5()
|
|
{
|
|
typedef struct {
|
|
char name[16];
|
|
short tdim;
|
|
short coll_ids[4];
|
|
} src_typ_t;
|
|
|
|
typedef struct {
|
|
char name[16];
|
|
short tdim;
|
|
int coll_ids[4];
|
|
} dst_typ_t;
|
|
|
|
hsize_t dims[1] = {4};
|
|
src_typ_t src[2] = {{"one", 102, {104, 105, 106, 107}}, {"two", 202, {204, 205, 206, 207}}};
|
|
dst_typ_t *dst;
|
|
void *buf = calloc(2, sizeof(dst_typ_t));
|
|
void *bkg = calloc(2, sizeof(dst_typ_t));
|
|
ArrayType *array_dt = NULL;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Optimized Struct Converter");
|
|
try {
|
|
|
|
/* Build datatypes */
|
|
array_dt = new ArrayType(PredType::NATIVE_SHORT, 1, dims);
|
|
CompType short_array(4 * sizeof(short));
|
|
short_array.insertMember("_", 0, *array_dt);
|
|
array_dt->close();
|
|
delete array_dt;
|
|
|
|
CompType int_array(4 * sizeof(int));
|
|
array_dt = new ArrayType(PredType::NATIVE_INT, 1, dims);
|
|
int_array.insertMember("_", 0, *array_dt);
|
|
array_dt->close();
|
|
|
|
StrType strg(PredType::C_S1, 16);
|
|
CompType src_type(sizeof(src_typ_t));
|
|
src_type.insertMember("name", HOFFSET(src_typ_t, name), strg);
|
|
src_type.insertMember("tdim", HOFFSET(src_typ_t, tdim), PredType::NATIVE_SHORT);
|
|
src_type.insertMember("coll_ids", HOFFSET(src_typ_t, coll_ids), short_array);
|
|
|
|
CompType dst_type(sizeof(dst_typ_t));
|
|
dst_type.insertMember("name", HOFFSET(dst_typ_t, name), strg);
|
|
dst_type.insertMember("tdim", HOFFSET(dst_typ_t, tdim), PredType::NATIVE_SHORT);
|
|
dst_type.insertMember("coll_ids", HOFFSET(dst_typ_t, coll_ids), int_array);
|
|
|
|
/* Convert data */
|
|
memcpy(buf, src, sizeof(src));
|
|
src_type.convert(dst_type, 2, buf, bkg);
|
|
dst = static_cast<dst_typ_t *>(buf);
|
|
|
|
/* Cleanup */
|
|
src_type.close();
|
|
dst_type.close();
|
|
strg.close();
|
|
short_array.close();
|
|
int_array.close();
|
|
|
|
/* Check results */
|
|
if (memcmp(src[1].name, dst[1].name, sizeof(src[1].name)) != 0 || src[1].tdim != dst[1].tdim ||
|
|
src[1].coll_ids[0] != dst[1].coll_ids[0] || src[1].coll_ids[1] != dst[1].coll_ids[1] ||
|
|
src[1].coll_ids[2] != dst[1].coll_ids[2] || src[1].coll_ids[3] != dst[1].coll_ids[3]) {
|
|
H5_FAILED();
|
|
}
|
|
|
|
/* Free memory buffers */
|
|
free(buf);
|
|
free(bkg);
|
|
dst = NULL;
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
delete array_dt;
|
|
} // test_compound_5()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_6
|
|
*
|
|
* Purpose Tests compound conversions when the destination has the same
|
|
* fields as the source but one or more of the fields are
|
|
* larger.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_6()
|
|
{
|
|
typedef struct {
|
|
short b;
|
|
short d;
|
|
} src_typ_t;
|
|
|
|
typedef struct {
|
|
long b;
|
|
long d;
|
|
} dst_typ_t;
|
|
|
|
src_typ_t *s_ptr;
|
|
dst_typ_t *d_ptr;
|
|
int i;
|
|
const int nelmts = NTESTELEM;
|
|
unsigned char *buf = NULL, *orig = NULL, *bkg = NULL;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Element Growing");
|
|
try {
|
|
/* Sizes should be the same, but be careful just in case */
|
|
buf = static_cast<unsigned char *>(malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t))));
|
|
bkg = static_cast<unsigned char *>(malloc(nelmts * sizeof(dst_typ_t)));
|
|
orig = static_cast<unsigned char *>(malloc(nelmts * sizeof(src_typ_t)));
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
s_ptr->b = (i * 8 + 1) & 0x7fff;
|
|
s_ptr->d = (i * 8 + 6) & 0x7fff;
|
|
}
|
|
memcpy(buf, orig, nelmts * sizeof(src_typ_t));
|
|
|
|
/* Build hdf5 datatypes */
|
|
CompType st(sizeof(src_typ_t));
|
|
st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_SHORT);
|
|
st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_SHORT);
|
|
|
|
CompType dt(sizeof(dst_typ_t));
|
|
dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_LONG);
|
|
dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_LONG);
|
|
|
|
/* Perform the conversion */
|
|
st.convert(dt, static_cast<size_t>(nelmts), buf, bkg);
|
|
|
|
/* Compare results */
|
|
for (i = 0; i < nelmts; i++) {
|
|
s_ptr = (reinterpret_cast<src_typ_t *>(orig)) + i;
|
|
d_ptr = (reinterpret_cast<dst_typ_t *>(buf)) + i;
|
|
if (s_ptr->b != d_ptr->b || s_ptr->d != d_ptr->d) {
|
|
H5_FAILED();
|
|
cerr << " i=" << i << endl;
|
|
cerr << " src={b=" << s_ptr->b << ", d=" << s_ptr->d << "}" << endl;
|
|
cerr << " dst={b=" << d_ptr->b << ", d=" << d_ptr->d << "}" << endl;
|
|
}
|
|
}
|
|
|
|
/* Release resources */
|
|
free(buf);
|
|
free(bkg);
|
|
free(orig);
|
|
s_ptr = NULL;
|
|
d_ptr = NULL;
|
|
st.close();
|
|
dt.close();
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
} // test_compound_6()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_7
|
|
*
|
|
* Purpose Tests inserting fields into compound datatypes when the field
|
|
* overlaps the end of the compound datatype.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_compound_7()
|
|
{
|
|
typedef struct {
|
|
int a;
|
|
float b;
|
|
long c;
|
|
} s1_typ_t;
|
|
|
|
typedef struct {
|
|
int a;
|
|
float b;
|
|
long c;
|
|
double d;
|
|
} s2_typ_t;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Compound Element Insertion");
|
|
try {
|
|
CompType tid1(sizeof(s1_typ_t));
|
|
|
|
tid1.insertMember("a", HOFFSET(s1_typ_t, a), PredType::NATIVE_INT);
|
|
tid1.insertMember("b", HOFFSET(s1_typ_t, b), PredType::NATIVE_FLOAT);
|
|
tid1.insertMember("c", HOFFSET(s1_typ_t, c), PredType::NATIVE_LONG);
|
|
|
|
size_t type_size = tid1.getSize();
|
|
verify_val(type_size, sizeof(s1_typ_t), "DataType::getSize", __LINE__, __FILE__);
|
|
|
|
CompType tid2;
|
|
tid2.copy(tid1);
|
|
|
|
type_size = tid2.getSize();
|
|
verify_val_noteq(type_size, sizeof(s2_typ_t), "DataType::getSize", __LINE__, __FILE__);
|
|
|
|
/* Should not be able to insert field past end of compound datatype */
|
|
try {
|
|
tid2.insertMember("d", HOFFSET(s2_typ_t, d), PredType::NATIVE_DOUBLE);
|
|
// Should FAIL but didn't, so throw an invalid action exception
|
|
throw InvalidActionException("CompType::insertMember",
|
|
"Attempted to insert field past end of compound data type.");
|
|
}
|
|
catch (DataTypeIException &err) {
|
|
}
|
|
|
|
/* Release resources */
|
|
tid1.close();
|
|
tid2.close();
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
} // test_compound_7()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound_set_size
|
|
*
|
|
* Purpose Tests member function setSize() on compound datatype
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
const H5std_string COMPFILE("tcompound_types.h5");
|
|
|
|
static void
|
|
test_compound_set_size()
|
|
{
|
|
typedef struct {
|
|
int a, b, c[4], d, e;
|
|
} src_typ_t;
|
|
|
|
// Output message about test being performed
|
|
SUBTEST("Setting Size on Compound Datatype");
|
|
try {
|
|
// Create File
|
|
H5File file(COMPFILE, H5F_ACC_TRUNC);
|
|
|
|
// Create a compound datatype
|
|
CompType dtype(sizeof(src_typ_t));
|
|
|
|
dtype.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
|
|
dtype.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_FLOAT);
|
|
dtype.insertMember("c", HOFFSET(src_typ_t, c), PredType::NATIVE_LONG);
|
|
dtype.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_DOUBLE);
|
|
|
|
// Verify that the compound is not packed
|
|
// bool packed = dtype.packed(); // not until C library provides API
|
|
// verify_val(packed, FALSE, "DataType::packed", __LINE__, __FILE__);
|
|
|
|
dtype.commit(file, "dtype");
|
|
|
|
// Close the type and file
|
|
dtype.close();
|
|
file.close();
|
|
|
|
// Open the file for read/write
|
|
file.openFile(COMPFILE, H5F_ACC_RDWR);
|
|
|
|
// Open the data type "dtype"
|
|
CompType dtype_tmp = file.openCompType("dtype");
|
|
|
|
// Make a copy of the data type
|
|
dtype.copy(dtype_tmp);
|
|
|
|
// Verify that the compound is not packed
|
|
// packed = dtype_tmp.packed(); // not until C library provides API
|
|
// verify_val(packed, FALSE, "DataType::packed", __LINE__, __FILE__);
|
|
|
|
// Expand the type, and verify that it became unpacked
|
|
dtype.setSize(33);
|
|
// packed = dtype.packed(); // not until C library provides API
|
|
// verify_val(packed, FALSE, "DataType::packed", __LINE__, __FILE__);
|
|
|
|
// Verify setSize() actually set size
|
|
size_t new_size = dtype.getSize();
|
|
verify_val(static_cast<long>(new_size), 33, "DataType::getSize", __LINE__, __FILE__);
|
|
|
|
// Shrink the type, and verify that it became packed
|
|
dtype.setSize(32);
|
|
// packed = dtype.packed(); // not until C library provides API
|
|
// verify_val(packed, TRUE, "DataType::packed", __LINE__, __FILE__);
|
|
|
|
// Verify setSize() actually set size again
|
|
new_size = dtype.getSize();
|
|
verify_val(static_cast<long>(new_size), 32, "DataType::getSize", __LINE__, __FILE__);
|
|
|
|
/* Close types and file */
|
|
dtype_tmp.close();
|
|
dtype.close();
|
|
file.close();
|
|
|
|
PASSED();
|
|
} // end of try block
|
|
|
|
catch (Exception &E) {
|
|
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
} // test_compound_set_size()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_compound
|
|
*
|
|
* Purpose Main compound datatype testing routine
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
extern "C" void
|
|
test_compound(void *params)
|
|
{
|
|
(void)params;
|
|
|
|
// Output message about test being performed
|
|
MESSAGE(5, ("Testing Compound Data Type operations\n"));
|
|
|
|
test_compound_1(); // various things about compound data types
|
|
test_compound_2(); // compound element reordering
|
|
test_compound_3(); // compound datatype subset conversions
|
|
test_compound_4(); // compound element shrinking & reordering
|
|
test_compound_5(); // optimized struct converter
|
|
test_compound_6(); // compound element growing
|
|
test_compound_7(); // compound element insertion
|
|
test_compound_set_size(); // set size on compound data types
|
|
} // test_compound()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: cleanup_compound
|
|
*
|
|
* Purpose Cleanup temporary test files - nothing at this time.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
extern "C" void
|
|
cleanup_compound(void *params)
|
|
{
|
|
(void)params;
|
|
|
|
if (GetTestCleanup()) {
|
|
HDremove(COMPFILE.c_str());
|
|
}
|
|
} // cleanup_file
|