Files
hdf5/c++/test/tcompound.cpp
T
a09e1ea219 Hdf5 merge issue #458 to hdf5_1_12 (#463)
* Snapshot version 1.12 release 1-3.  Update  version to 1.12.1-4.

* First cut of the H5 public API documentation. (#80)

* First cut of the H5 public API documentation.

* Added H5Z "bonus track."

* Applied Quincey's patch.

* Added the missing patches from Quincey's original patch.

* H5PL (complete) and basic H5VL API documentation.

* Added H5I API docs.

* Added H5L API docs.

* First installment from Elena's H5T batch.

* Second installment of Elena's H5T batch.

* Final installment of Elena's H5T batch.

* Full set of current H5F documentation. (#105)

* First cut of the H5 public API documentation.

* Added H5Z "bonus track."

* Applied Quincey's patch.

* Added the missing patches from Quincey's original patch.

* H5PL (complete) and basic H5VL API documentation.

* Added H5I API docs.

* Added H5L API docs.

* First installment from Elena's H5T batch.

* Second installment of Elena's H5T batch.

* Final installment of Elena's H5T batch.

* Migrated documentation for SWMR functions.

* Catching up on MDC functions.

* Integrated the H5F MDC function documentation.

* Added MDC and parallel H5F functions.

* Slightly updated main page.

* Added doxygen/dox/H5AC_cache_config_t.dox to MANIFEST.

* Doxygen - added (mostly) beginner functions (#112)

* Doxygen - added (mostly) beginner functions

* Removed duplicate H5Pset_szip function

* Add src/H5module.h to MANIFEST.

* close #195. (#196)

* Update HDF5PluginMacros.cmake

* Update HDF5PluginMacros.cmake

* Avoid aligned access for references by decoding into temporary buffer and then copying the result into the actual buffer.   Update test to be more thorough with using compound datatype fields everywhere. (#206)

* Modify temporary rpath for testing in java example scripts. (#230)

* Fix undefined left shifting of negative numbers (#338)

Undefined Bahavior Sanitizer errored here about left shifting negative numbers.

* Fixes various warnings noticed on Windows (#425)

* Fixes various warnings noticed on Windows

- Adds a prototype for our implementation of vasprintf
- Return type of H5_get_utf16_str() is now non-const
- Fixes possible uninitialized return type in Wremove_utf8
- Better isolation of fork() code in accum.c:test_swmr_write_big()
- Better isolation of non-zlib code in dsets.c:test_filter_delete()
- Removed unused variable in trefer.c:test_reference_cmpnd_obj()

* Fixes clang-format issues

* Applied clang-tidy readability-non-const-parameter warning fixes auto… (#429)

* Automatically applied clang-tidy readability-avoid-const-params-in-decls fixes

Removes useless const declarations.

* Fixed most readability-non-const-parameter warnings

These changes were made automatically by clang-tidy, but I manually reverted the changes related to the H5Z_func_t signature.

* Reformat source with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Added C++11 override keyword where appropriate (#433)

Added H5_OVERRIDE macro for compatibility with both C++11 and older.

* Various clang tidy warning fixes (#448)

* Fixed clang-tidy bugprone-reserved-identifier warnings

* Fixed clang-tidy bugprone-assert-side-effect warnings

* Fixed clang-tidy bugprone-copy-constructor-init warning

* Fixed clang-tidy readability-redundant-preprocessor warning

For error_test.c the removed code was already dead, because it was in the else of an `#if H5_USE_16_API` block.

Based on H5Location.h, I think p_get_ref_obj_type was meant to be in `#ifndef DOXYGEN_SHOULD_SKIP_THIS` and an `#endif` was missing.  Similarly, in the header, getObjTypeByIdx is only in H5_NO_DEPRECATED_SYMBOLS, not DOXYGEN_SHOULD_SKIP_THIS.

* Fixed clang-tidy readability-redundant-string-init warnings

* Fixed some clang-tidy performance-type-promotion-in-math-fn warnings

* Fixed clang-tidy performance-unnecessary-value-param warnings

* Reformat source with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Removed checks/workarounds for pre-C++89 compatibility (#449)

After 30+ years, just assume that the following exist:
- extension-less includes
- namespaces
- std::
- static_cast
- bool

* Fixed all clang-tidy bugprone-suspicious-string-compare warnings (#451)

* Fixed all clang-tidy bugprone-suspicious-string-compare warnings

This change was generated entirely by clang-tidy itself.

* Reformat code with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Remove 2 functions incorrectly merged from develop in a cherry-pick merge of PR #451.

Co-authored-by: Gerd Heber <gheber@hdfgroup.org>
Co-authored-by: bljhdf <58825073+bljhdf@users.noreply.github.com>
Co-authored-by: H. Joe Lee <hyoklee@hdfgroup.org>
Co-authored-by: Quincey Koziol <quincey@koziol.cc>
Co-authored-by: Sean McBride <sean@rogue-research.com>
Co-authored-by: Dana Robinson <43805+derobins@users.noreply.github.com>
2021-03-12 12:00:15 -06:00

792 lines
28 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://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
*
* Programmer Binh-Minh Ribler (using C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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 = (unsigned char *)HDmalloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
bkg = (unsigned char *)HDmalloc(nelmts * sizeof(dst_typ_t));
orig = (unsigned char *)HDmalloc(nelmts * sizeof(src_typ_t));
for (i = 0; i < nelmts; i++) {
s_ptr = ((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, (size_t)nelmts, buf, bkg);
// Compare results
for (i = 0; i < nelmts; i++) {
s_ptr = ((src_typ_t *)orig) + i;
d_ptr = ((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
HDfree(buf);
HDfree(bkg);
HDfree(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());
}
if (array_dt)
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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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 = (unsigned char *)HDmalloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
bkg = (unsigned char *)HDmalloc(nelmts * sizeof(dst_typ_t));
orig = (unsigned char *)HDmalloc(nelmts * sizeof(src_typ_t));
for (i = 0; i < nelmts; i++) {
s_ptr = ((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, (size_t)nelmts, buf, bkg);
/* Compare results */
for (i = 0; i < nelmts; i++) {
s_ptr = ((src_typ_t *)orig) + i;
d_ptr = ((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;
} // if
} // for
/* Release resources */
HDfree(buf);
HDfree(bkg);
HDfree(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());
}
if (array_dt)
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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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 = (unsigned char *)HDmalloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
bkg = (unsigned char *)HDmalloc(nelmts * sizeof(dst_typ_t));
orig = (unsigned char *)HDmalloc(nelmts * sizeof(src_typ_t));
for (i = 0; i < nelmts; i++) {
s_ptr = ((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, (size_t)nelmts, buf, bkg);
/* Compare results */
for (i = 0; i < nelmts; i++) {
s_ptr = ((src_typ_t *)orig) + i;
d_ptr = ((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 */
HDfree(buf);
HDfree(bkg);
HDfree(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());
}
if (array_dt)
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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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 = HDcalloc(2, sizeof(dst_typ_t));
void * bkg = HDcalloc(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, (size_t)2, buf, bkg);
dst = (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 */
HDfree(buf);
HDfree(bkg);
dst = NULL;
PASSED();
} // end of try block
catch (Exception &E) {
issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
}
if (array_dt)
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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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 = (unsigned char *)HDmalloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
bkg = (unsigned char *)HDmalloc(nelmts * sizeof(dst_typ_t));
orig = (unsigned char *)HDmalloc(nelmts * sizeof(src_typ_t));
for (i = 0; i < nelmts; i++) {
s_ptr = ((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, (size_t)nelmts, buf, bkg);
/* Compare results */
for (i = 0; i < nelmts; i++) {
s_ptr = ((src_typ_t *)orig) + i;
d_ptr = ((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;
} // if
} // for
/* Release resources */
HDfree(buf);
HDfree(bkg);
HDfree(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
*
* Programmer Binh-Minh Ribler (use C version)
* January, 2007
*-------------------------------------------------------------------------
*/
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
*
* Programmer Binh-Minh Ribler (use partial C version test_ooo_order)
* March, 2014
*-------------------------------------------------------------------------
*/
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((size_t)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(new_size, (size_t)33, "DataType::getSize", __LINE__, __FILE__);
// Shrink the type, and verify that it became packed
dtype.setSize((size_t)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(new_size, (size_t)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
*
* Programmer Binh-Minh Ribler
* January 2007
*-------------------------------------------------------------------------
*/
extern "C" void
test_compound()
{
// 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()
{
HDremove(COMPFILE.c_str());
} // cleanup_file