Files
hdf5/c++/test/tcompound.cpp
jhendersonHDF af0b2315bd Remove const from testing parameters in testframe framework (#5214)
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.
2025-01-08 13:33:00 -06:00

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