Files
hdf5/c++/test/tcompound.cpp
T
jhendersonHDF 34d6ef545a Refactor h5test.c, testframe.c and testpar.h testing frameworks (#4891)
Added new testframe.h header to document testing framework functions and
split them away from h5test.h and from test programs that don't
integrate with the testframe.c testing framework

Added new test setup callback to testframe.c testing framework

Added parameters to AddTest() to specify size of test parameters so they
can be copied for later use

Enabled HDF5 error stacks in testframe.c framework by default and added
some error stack suppressions to some testhdf5 tests

Added new maxthreads option to testframe.c framework to allow specifying
the maximum number of threads a multi-threaded test can use

Moved TestExpress functionality out of testframe.c and into more general
h5test.c for wider use by tests through getter and setter

Updated some tests to not mix and match functionality between h5test.c/h
and testframe.c/h

Moved some functionality from testphdf5.h into testpar.h for parallel
tests that aren't part of testphdf5

Added new parallel test library that contains common shared
functionality for parallel tests (similar to h5test library)
2024-10-01 16:10:03 -05:00

762 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 COPYING 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(const 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)
{
if (GetTestCleanup()) {
HDremove(COMPFILE.c_str());
}
} // cleanup_file