summaryrefslogtreecommitdiffstats
path: root/hl/test
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2005-03-18 17:19:36 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2005-03-18 17:19:36 (GMT)
commit349ca8daa9a1d0f094d716ea603d7d41ac14b862 (patch)
treed5180e62e013724f1c8972c018963bfe4da74e17 /hl/test
parentf7ee415cdb4e6000636a55ff017c516d65ed64c1 (diff)
downloadhdf5-349ca8daa9a1d0f094d716ea603d7d41ac14b862.zip
hdf5-349ca8daa9a1d0f094d716ea603d7d41ac14b862.tar.gz
hdf5-349ca8daa9a1d0f094d716ea603d7d41ac14b862.tar.bz2
[svn-r10234] Purpose:
Added Packet Table to high-level APIs Description: The Packet Table is an API that allows the user to append records ("packets") to a table, and read the back again. It supports fixed-length records with a defined datatype and variable-length records. It also supports a "current record" index to track the user's position in the table. Solution: The Packet Table code lives in hl/src, and its tests in hl/test. Some code is shared between the H5TB table and the H5PT Packet Table in the form of functions in H5HL_private.c. Some documentation exists for a previous version of the API. Updated documentation and C++ wrapper API coming soon. Platforms tested: sleipnir, eirene, copper, modi4
Diffstat (limited to 'hl/test')
-rw-r--r--hl/test/Makefile.am2
-rw-r--r--hl/test/Makefile.in20
-rw-r--r--hl/test/test_packet.c907
3 files changed, 923 insertions, 6 deletions
diff --git a/hl/test/Makefile.am b/hl/test/Makefile.am
index 0e1c0de..983ac9a 100644
--- a/hl/test/Makefile.am
+++ b/hl/test/Makefile.am
@@ -18,7 +18,7 @@ LDADD=$(LIBH5_HL) $(LIBHDF5)
# Test programs. These are our main targets. They should be listed in the
# order to be executed, generally most specific tests to least specific tests.
-TEST_PROG=test_lite test_image test_table test_ds
+TEST_PROG=test_lite test_image test_table test_ds test_packet
check_PROGRAMS=$(TEST_PROG)
# Temporary files. These files are the ones created by running `make test'.
diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in
index ca9f292..84bc142 100644
--- a/hl/test/Makefile.in
+++ b/hl/test/Makefile.in
@@ -21,7 +21,7 @@
#
# HDF5 High-Level Test Makefile(.in)
#
-SOURCES = test_ds.c test_image.c test_lite.c test_table.c
+SOURCES = test_ds.c test_image.c test_lite.c test_packet.c test_table.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -58,7 +58,7 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/bin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/H5config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = test_lite$(EXEEXT) test_image$(EXEEXT) \
- test_table$(EXEEXT) test_ds$(EXEEXT)
+ test_table$(EXEEXT) test_ds$(EXEEXT) test_packet$(EXEEXT)
test_ds_SOURCES = test_ds.c
test_ds_OBJECTS = test_ds.$(OBJEXT)
test_ds_LDADD = $(LDADD)
@@ -73,6 +73,10 @@ test_lite_SOURCES = test_lite.c
test_lite_OBJECTS = test_lite.$(OBJEXT)
test_lite_LDADD = $(LDADD)
test_lite_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+test_packet_SOURCES = test_packet.c
+test_packet_OBJECTS = test_packet.$(OBJEXT)
+test_packet_LDADD = $(LDADD)
+test_packet_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
test_table_SOURCES = test_table.c
test_table_OBJECTS = test_table.$(OBJEXT)
test_table_LDADD = $(LDADD)
@@ -88,8 +92,10 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = test_ds.c test_image.c test_lite.c test_table.c
-DIST_SOURCES = test_ds.c test_image.c test_lite.c test_table.c
+SOURCES = test_ds.c test_image.c test_lite.c test_packet.c \
+ test_table.c
+DIST_SOURCES = test_ds.c test_image.c test_lite.c test_packet.c \
+ test_table.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -294,7 +300,7 @@ LDADD = $(LIBH5_HL) $(LIBHDF5)
# Test programs. These are our main targets. They should be listed in the
# order to be executed, generally most specific tests to least specific tests.
-TEST_PROG = test_lite test_image test_table test_ds
+TEST_PROG = test_lite test_image test_table test_ds test_packet
# Temporary files. These files are the ones created by running `make test'.
MOSTLYCLEANFILES = combine_tables[1-2].h5 test_ds[1-3].h5 test_image.h5 \
@@ -362,6 +368,9 @@ test_image$(EXEEXT): $(test_image_OBJECTS) $(test_image_DEPENDENCIES)
test_lite$(EXEEXT): $(test_lite_OBJECTS) $(test_lite_DEPENDENCIES)
@rm -f test_lite$(EXEEXT)
$(LINK) $(test_lite_LDFLAGS) $(test_lite_OBJECTS) $(test_lite_LDADD) $(LIBS)
+test_packet$(EXEEXT): $(test_packet_OBJECTS) $(test_packet_DEPENDENCIES)
+ @rm -f test_packet$(EXEEXT)
+ $(LINK) $(test_packet_LDFLAGS) $(test_packet_OBJECTS) $(test_packet_LDADD) $(LIBS)
test_table$(EXEEXT): $(test_table_OBJECTS) $(test_table_DEPENDENCIES)
@rm -f test_table$(EXEEXT)
$(LINK) $(test_table_LDFLAGS) $(test_table_OBJECTS) $(test_table_LDADD) $(LIBS)
@@ -375,6 +384,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ds.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_table.Po@am__quote@
.c.o:
diff --git a/hl/test/test_packet.c b/hl/test/test_packet.c
new file mode 100644
index 0000000..0500edd
--- /dev/null
+++ b/hl/test/test_packet.c
@@ -0,0 +1,907 @@
+
+/****************************************************************************
+ * NCSA HDF *
+ * Scientific Data Technologies *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING f. *
+ * *
+ ****************************************************************************/
+
+#include "H5PT.h"
+#include "H5TB.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+/*-------------------------------------------------------------------------
+ * Packet Table API test
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define NRECORDS 8
+#define BIG_TABLE_SIZE 8000
+#define NFIELDS 5
+#define TEST_FILE_NAME "test_packet_table.h5"
+#define PT_NAME "Test Packet Table"
+#define VL_TABLE_NAME "Varlen Test Table"
+#define H5TB_TABLE_NAME "Table1"
+#define TESTING(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);}
+#define PASSED() {puts(" PASSED");fflush(stdout);}
+#define H5_FAILED() {puts("*FAILED*");fflush(stdout);}
+
+/*-------------------------------------------------------------------------
+ * structure used for some tests, a particle
+ *-------------------------------------------------------------------------
+ */
+typedef struct particle_t
+{
+ char name[16];
+ int lati;
+ int longi;
+ float pressure;
+ double temperature;
+} particle_t;
+
+/*-------------------------------------------------------------------------
+ * a static array of particles for writing and checking reads
+ *-------------------------------------------------------------------------
+ */
+static particle_t testPart[NRECORDS] = {
+ {"zero", 0,0, 0.0f, 0.0},
+ {"one", 10,10, 1.0f, 10.0},
+ {"two", 20,20, 2.0f, 20.0},
+ {"three",30,30, 3.0f, 30.0},
+ {"four", 40,40, 4.0f, 40.0},
+ {"five", 50,50, 5.0f, 50.0},
+ {"six", 60,60, 6.0f, 60.0},
+ {"seven",70,70, 7.0f, 70.0}
+ };
+
+/*-------------------------------------------------------------------------
+ * function that compares one particle
+ *-------------------------------------------------------------------------
+ */
+static int cmp_par(hsize_t i, hsize_t j, particle_t *rbuf, particle_t *wbuf )
+{
+ if ( ( strcmp( rbuf[i].name, wbuf[j].name ) != 0 ) ||
+ rbuf[i].lati != wbuf[j].lati ||
+ rbuf[i].longi != wbuf[j].longi ||
+ rbuf[i].pressure != wbuf[j].pressure ||
+ rbuf[i].temperature != wbuf[j].temperature ) {
+ return -1;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * function to create a datatype representing the particle struct
+ *-------------------------------------------------------------------------
+ */
+static hid_t make_particle_type()
+{
+ hid_t type_id;
+ hid_t string_type;
+ size_t type_size = sizeof(particle_t);
+
+ /* Create the memory data type. */
+ if ((type_id = H5Tcreate (H5T_COMPOUND, type_size )) < 0 )
+ return -1;
+
+ /* Insert fields. */
+ string_type = H5Tcopy( H5T_C_S1 );
+ H5Tset_size( string_type, 16 );
+
+ if ( H5Tinsert(type_id, "Name", HOFFSET(particle_t, name) , string_type ) < 0 )
+ return -1;
+ if ( H5Tinsert(type_id, "Lat", HOFFSET(particle_t, lati) , H5T_NATIVE_INT ) < 0 )
+ return -1;
+ if ( H5Tinsert(type_id, "Long", HOFFSET(particle_t, longi) , H5T_NATIVE_INT ) < 0 )
+ return -1;
+ if ( H5Tinsert(type_id, "Pressure", HOFFSET(particle_t, pressure) , H5T_NATIVE_FLOAT ) < 0 )
+ return -1;
+ if ( H5Tinsert(type_id, "Temperature", HOFFSET(particle_t, temperature) , H5T_NATIVE_DOUBLE ) < 0 )
+ return -1;
+
+ return type_id;
+}
+
+ /* Create a normal HL table just like the HL examples do */
+static int create_hl_table(hid_t fid)
+{
+ particle_t testparticle;
+
+ /* Calculate the offsets of the particle struct members in memory */
+ size_t part_offset[NFIELDS] = { HOFFSET( particle_t, name ),
+ HOFFSET( particle_t, lati ),
+ HOFFSET( particle_t, longi ),
+ HOFFSET( particle_t, pressure ),
+ HOFFSET( particle_t, temperature )};
+
+ size_t part_sizes[NFIELDS] = { sizeof( testparticle.name),
+ sizeof( testparticle.lati),
+ sizeof( testparticle.longi),
+ sizeof( testparticle.pressure),
+ sizeof( testparticle.temperature)};
+
+ /* Define field information */
+ const char *field_names[NFIELDS] =
+ { "Name","Latitude", "Longitude", "Pressure", "Temperature" };
+ hid_t field_type[NFIELDS];
+ hid_t string_type;
+ hsize_t chunk_size = 10;
+ int *fill_data = NULL;
+ int compress = 0;
+ herr_t status;
+
+ /* Initialize the field field_type */
+ string_type = H5Tcopy( H5T_C_S1 );
+ H5Tset_size( string_type, 16 );
+ field_type[0] = string_type;
+ field_type[1] = H5T_NATIVE_INT;
+ field_type[2] = H5T_NATIVE_INT;
+ field_type[3] = H5T_NATIVE_FLOAT;
+ field_type[4] = H5T_NATIVE_DOUBLE;
+
+
+ /*------------------------------------------------------------------------
+ * H5TBmake_table
+ *-------------------------------------------------------------------------
+ */
+
+ status=H5TBmake_table( "Table Title", fid, H5TB_TABLE_NAME, (hsize_t) NFIELDS,
+ (hsize_t)NRECORDS, sizeof(particle_t),
+ field_names, part_offset, field_type,
+ chunk_size, fill_data, compress, testPart );
+
+if(status<0)
+ return -1;
+else
+ return 0;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * test_create_close
+ *
+ * Tests creation and closing of an FL packet table
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int test_create_close(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ hid_t part_t;
+
+ TESTING("H5PTcreate_fl and H5TBclose");
+
+ /* Create a datatype for the particle struct */
+ part_t = make_particle_type();
+
+ assert(part_t != -1);
+
+ /* Create the table */
+ table = H5PTcreate_fl(fid, PT_NAME, part_t, 100);
+ H5Tclose(part_t);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+ if( H5PTis_varlen(table) != 0)
+ goto out;
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_open
+ *
+ * Tests opening and closing a FL packet table
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_open(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+
+ TESTING("H5PTopen");
+
+ /* Open the table */
+ table = H5PTopen(fid, PT_NAME);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+ if( H5PTis_varlen(table) != 0)
+ goto out;
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_append
+ *
+ * Tests appending packets to a FL packet table
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_append(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ hsize_t count;
+
+ TESTING("H5PTappend");
+
+ /* Open the table */
+ table = H5PTopen(fid, PT_NAME);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+
+ /* Count the number of packets in the table */
+ err = H5PTget_num_packets(table, &count);
+ if( err < 0)
+ goto out;
+ /* There should be 0 records in the table */
+ if( count != 0 )
+ goto out;
+
+ /* Append one particle */
+ err = H5PTappend(table, 1, &(testPart[0]));
+ if( err < 0)
+ goto out;
+
+ /* Append several particles */
+ err = H5PTappend(table, 6, &(testPart[1]));
+ if( err < 0)
+ goto out;
+
+ /* Append one more particle */
+ err = H5PTappend(table, 1, &(testPart[7]));
+ if( err < 0)
+ goto out;
+
+ /* Count the number of packets in the table */
+ err = H5PTget_num_packets(table, &count);
+ if( err < 0)
+ goto out;
+ /* There should be 8 records in the table now */
+ if( count != 8 )
+ goto out;
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ if( H5PTis_valid(table) < 0)
+ H5PTclose(table);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_read
+ *
+ * Tests that the packets appended by test_append can be read back.
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_read(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ particle_t readBuf[NRECORDS];
+ int c;
+
+ TESTING("H5PTread_packets");
+
+ /* Open the table */
+ table = H5PTopen(fid, PT_NAME);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+
+ /* Read several particles */
+ err = H5PTread_packets(table, 0, 3, &(readBuf[0]));
+ if( err < 0)
+ goto out;
+
+ /* Read one particle */
+ err = H5PTread_packets(table, 3, 1, &(readBuf[3]));
+ if( err < 0)
+ goto out;
+
+ /* Read several particles */
+ err = H5PTread_packets(table, 4, (NRECORDS - 4 ), &(readBuf[4]));
+ if( err < 0)
+ goto out;
+
+ /* Ensure that particles were read correctly */
+ for(c=0; c<NRECORDS; c++)
+ {
+ if( cmp_par(c%8, c, testPart, readBuf) != 0)
+ goto out;
+ }
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+
+ return 0;
+
+ out:
+ H5_FAILED();
+ if( H5PTis_valid(table) < 0)
+ H5PTclose(table);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_get_next
+ *
+ * Tests the packets written by test_append can be read by
+ * H5PTget_next().
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_get_next(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ particle_t readBuf[NRECORDS];
+ particle_t readBuf2[NRECORDS];
+ int c;
+
+ TESTING("H5PTget_next");
+
+ /* Open the table */
+ table = H5PTopen(fid, PT_NAME);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+
+ /* Read several particles consecutively */
+ for(c=0; c < NRECORDS; c++)
+ {
+ err = H5PTget_next(table, 1, &readBuf[c]);
+ if(err < 0)
+ goto out;
+ }
+
+ /* Ensure that particles were read correctly */
+ for(c=0; c<NRECORDS; c++)
+ {
+ if( cmp_par(c, c, testPart, readBuf) != 0)
+ goto out;
+ }
+
+ H5PTcreate_index(table);
+
+ /* Read particles two by two */
+ for(c=0; c < NRECORDS / 2; c++)
+ {
+ err = H5PTget_next(table, 2, &readBuf2[c * 2]);
+ if(err < 0)
+ goto out;
+ }
+
+ /* Ensure that particles were read correctly */
+ for(c=0; c<NRECORDS; c++)
+ {
+ if( cmp_par(c, c, testPart, readBuf2) != 0)
+ goto out;
+ }
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ if( H5PTis_valid(table) < 0)
+ H5PTclose(table);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_big_table
+ *
+ * Ensures that a FL packet table will not break when many (BIG_TABLE_SIZE)
+ * packets are used.
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_big_table(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ hid_t part_t;
+ int c;
+ particle_t readPart;
+ hsize_t count;
+
+ TESTING("large packet table");
+
+ /* Create a datatype for the particle struct */
+ part_t = make_particle_type();
+
+ assert(part_t != -1);
+
+ /* Create a new table */
+ table = H5PTcreate_fl(fid, "Packet Test Dataset2", part_t, 33);
+ H5Tclose(part_t);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+
+ /* Add many particles */
+ for(c = 0; c < BIG_TABLE_SIZE ; c+=8)
+ {
+ /* Append eight particles at once*/
+ err = H5PTappend(table, 8, &(testPart[0]));
+ if( err < 0)
+ goto out;
+ }
+
+ /* Count the number of packets in the table */
+ err = H5PTget_num_packets(table, &count);
+ if( err < 0)
+ goto out;
+ if( count != BIG_TABLE_SIZE )
+ goto out;
+
+ /* Read particles to ensure that all of them were written correctly */
+ /* Also, ensure that H5PTcreate_fl set the current packet to */
+ /* the first packet in the table */
+ for(c = 0; c < BIG_TABLE_SIZE; c++)
+ {
+ err = H5PTget_next(table, 1, &readPart);
+ if(err < 0)
+ goto out;
+
+ /* Ensure that particles were read correctly */
+ if( cmp_par(c % 8, 0, testPart, &readPart) != 0)
+ goto out;
+ }
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ if( H5PTis_valid(table) < 0)
+ H5PTclose(table);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_varlen
+ *
+ * Tests creation, opening, closing, writing, reading, etc. on a
+ * variable-length packet table.
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_varlen(hid_t fid)
+{
+ herr_t err;
+ hid_t table=H5I_BADID;
+ hsize_t count;
+
+ /* Buffers to hold data */
+ hvl_t writeBuffer[NRECORDS];
+ hvl_t readBuffer[NRECORDS];
+
+ /* This example has three different sizes of "record": longs, shorts, and particles */
+ long longBuffer[NRECORDS];
+ short shortBuffer[NRECORDS];
+ int x;
+
+ TESTING("variable-length packet tables");
+
+ /* Initialize buffers */
+ for(x=0; x<NRECORDS; x++)
+ {
+ longBuffer[x] = -x;
+ shortBuffer[x] = x;
+ }
+
+ /* Fill the write buffer with a mix of variable types */
+ for(x=0; x<8; x+=4)
+ {
+ writeBuffer[x].len = sizeof(long);
+ writeBuffer[x].p = &(longBuffer[x]);
+ writeBuffer[x+1].len = sizeof(short);
+ writeBuffer[x+1].p = &(shortBuffer[x+1]);
+ writeBuffer[x+2].len = sizeof(long);
+ writeBuffer[x+2].p = &(longBuffer[x+2]);
+ writeBuffer[x+3].len = sizeof(particle_t);
+ writeBuffer[x+3].p = &(testPart[x+3]);
+ }
+
+ /* Create the table */
+ table = H5PTcreate_vl(fid, VL_TABLE_NAME, 1001);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+ if( H5PTis_varlen(table) != 1)
+ goto out;
+
+ /* Count the number of packets in the table */
+ err = H5PTget_num_packets(table, &count);
+ if( err < 0)
+ goto out;
+ if( count != 0 )
+ goto out;
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ /* Re-open the table */
+ table = H5PTopen(fid, VL_TABLE_NAME);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+ if( H5PTis_varlen(table) != 1)
+ goto out;
+
+ /* Count the number of packets in the table */
+ err = H5PTget_num_packets(table, &count);
+ if( err < 0)
+ goto out;
+ if( count != 0 )
+ goto out;
+
+ /* Add several variable-length packets */
+ err = H5PTappend(table, 8, writeBuffer );
+ if(err < 0)
+ goto out;
+
+ /* Read them back */
+ err = H5PTread_packets(table, 0, 4, &(readBuffer[0]));
+ if( err < 0)
+ goto out;
+ err = H5PTread_packets(table, 4, 1, &(readBuffer[4]));
+ if( err < 0)
+ goto out;
+ err = H5PTread_packets(table, 5, (NRECORDS - 5 ), &(readBuffer[5]));
+ if( err < 0)
+ goto out;
+
+ /* Ensure that packets were read correctly */
+ for(x=0; x<NRECORDS; x++)
+ {
+ if( readBuffer[x].len != writeBuffer[x%4].len)
+ goto out;
+ switch(x%4)
+ {
+ case 0:
+ case 2:
+ if( *((long*)(readBuffer[x].p)) != *((long*)(writeBuffer[x].p)))
+ goto out;
+ break;
+ case 1:
+ if( *((short*)(readBuffer[x].p)) != *((short*)(writeBuffer[x].p)))
+ goto out;
+ break;
+ case 3:
+ if( cmp_par(0, 0, readBuffer[x].p, writeBuffer[x].p) < 0)
+ goto out;
+ break;
+ default:
+ goto out;
+ }
+ }
+
+ /* Free memory used by read buffer */
+ if(H5PTfree_vlen_readbuff(table, NRECORDS, readBuffer) <0)
+ goto out;
+
+ /* Read packets back using get_next */
+ for(x=0; x < NRECORDS; x++)
+ {
+ err = H5PTget_next(table, 1, &readBuffer[x]);
+ if(err < 0)
+ goto out;
+ }
+
+ /* Ensure that packets were read correctly */
+ for(x=0; x<NRECORDS; x++)
+ {
+ if( readBuffer[x].len != writeBuffer[x%4].len)
+ goto out;
+ switch(x%4)
+ {
+ case 0:
+ case 2:
+ if( *((long*)(readBuffer[x].p)) != *((long*)(writeBuffer[x].p)))
+ goto out;
+ break;
+ case 1:
+ if( *((short*)(readBuffer[x].p)) != *((short*)(writeBuffer[x].p)))
+ goto out;
+ break;
+ case 3:
+ if( cmp_par(0, 0, readBuffer[x].p, writeBuffer[x].p) < 0)
+ goto out;
+ break;
+ default:
+ goto out;
+ }
+ }
+
+ /* Free memory used by read buffer */
+ if(H5PTfree_vlen_readbuff(table, NRECORDS, readBuffer) <0)
+ goto out;
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ H5E_BEGIN_TRY
+ H5PTclose(table);
+ H5E_END_TRY
+ return -1;
+}
+/*-------------------------------------------------------------------------
+ * test_opaque
+ *
+ * Tests that the packet table works with an opaque datatype.
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_opaque(hid_t fid)
+{
+ herr_t err;
+ hid_t table;
+ hid_t part_t;
+ int c;
+ particle_t readBuf[NRECORDS];
+
+ TESTING("opaque data");
+
+ /* Create an opaque datatype for the particle struct */
+ if ((part_t = H5Tcreate (H5T_OPAQUE, sizeof(particle_t) )) < 0 )
+ return -1;
+
+ assert(part_t != -1);
+
+ /* Tag the opaque datatype */
+ if ( H5Tset_tag(part_t, "Opaque Particle" ) < 0)
+ return -1;
+
+ /* Create a new table */
+ table = H5PTcreate_fl(fid, "Packet Test Dataset3", part_t, 1);
+ H5Tclose(part_t);
+ if( H5PTis_valid(table) < 0)
+ goto out;
+
+ /* Append several particles, starting at particle 1 */
+ err = H5PTappend(table, NRECORDS - 1, &(testPart[1]));
+ if( err < 0)
+ goto out;
+
+ /* Read the particles back */
+ err = H5PTread_packets(table, 0, 7, &(readBuf[0]));
+ if( err < 0)
+ goto out;
+
+ /* Ensure that particles were read correctly */
+ for(c=0; c<NRECORDS - 1; c++)
+ {
+ if( cmp_par(c+1, c, testPart, readBuf) != 0)
+ goto out;
+ }
+
+ /* Close the table */
+ err = H5PTclose(table);
+ if( err < 0)
+ goto out;
+
+ PASSED();
+ return 0;
+
+ out:
+ H5_FAILED();
+ if( H5PTis_valid(table) < 0)
+ H5PTclose(table);
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * test_error
+ *
+ * ensures that the packet table API throws the correct errors used on
+ * objects that are not packet tables.
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_error(hid_t fid)
+{
+ hid_t id = H5I_BADID;
+ int id_open=0;
+ particle_t readBuf[1];
+
+ TESTING("error conditions");
+
+ /* Create a HL table */
+ if(create_hl_table(fid) < 0)
+ goto out;
+
+ /* Try to open things that are not packet tables */
+ H5E_BEGIN_TRY
+ if(H5PTopen(fid, "Bogus_name") >= 0)
+ goto out;
+ if(H5PTopen(fid, "group1") >= 0)
+ goto out;
+ H5E_END_TRY
+
+ /* Try to execute packet table commands on an invalid ID */
+ H5E_BEGIN_TRY
+ if(H5PTis_valid(id) >= 0)
+ goto out;
+ if(H5PTis_varlen(id) >= 0)
+ goto out;
+ if(H5PTclose(id) >= 0)
+ goto out;
+ if(H5PTappend(id, 1, testPart) >= 0)
+ goto out;
+ if(H5PTread_packets(id, 0, 1, readBuf) >= 0)
+ goto out;
+ if(H5PTcreate_index(id) >= 0)
+ goto out;
+ H5E_END_TRY
+
+ /* Open a high-level non-packet (H5TB) table and try to */
+ /* execute commands on it. */
+ if((id=H5Dopen(fid, H5TB_TABLE_NAME)) <0)
+ goto out;
+ id_open = 1;
+
+ H5E_BEGIN_TRY
+ if(H5PTis_valid(id) >= 0)
+ goto out;
+ if(H5PTis_varlen(id) >= 0)
+ goto out;
+ if(H5PTclose(id) >= 0)
+ goto out;
+ if(H5PTappend(id, 1, testPart) >= 0)
+ goto out;
+ if(H5PTread_packets(id, 0, 1, readBuf) >= 0)
+ goto out;
+ if(H5PTcreate_index(id) >= 0)
+ goto out;
+ H5E_END_TRY
+
+ id_open=0;
+ if(H5Dclose(id) <0)
+ goto out;
+
+ /* Open and close a packet table. Try to execute */
+ /* commands on the closed ID. */
+ if((id=H5PTopen(fid, PT_NAME))<0)
+ goto out;
+ if(H5PTclose(id) <0)
+ goto out;
+
+ H5E_BEGIN_TRY
+ if(H5PTis_valid(id) >= 0)
+ goto out;
+ if(H5PTis_varlen(id) >= 0)
+ goto out;
+ if(H5PTclose(id) >= 0)
+ goto out;
+ if(H5PTappend(id, 1, testPart) >= 0)
+ goto out;
+ if(H5PTread_packets(id, 0, 1, readBuf) >= 0)
+ goto out;
+ if(H5PTcreate_index(id) >= 0)
+ goto out;
+ H5E_END_TRY
+
+ PASSED();
+ return 0;
+
+out:
+ H5_FAILED();
+ if(id_open)
+ H5Dclose(id);
+ return -1;
+}
+
+
+int test_packet_table(hid_t fid)
+{
+
+ if( test_create_close(fid) < 0 )
+ return -1;
+
+ if( test_open(fid) < 0 )
+ return -1;
+
+ /* test_append must be run before test_count and test_read, as it */
+ /* creates the packet table they use. */
+ if( test_append(fid) < 0 )
+ return -1;
+
+ /* These tests will not necessarily cause failures in each other,
+ so we don't abort the other tests if one fails. */
+ test_read(fid);
+ test_get_next(fid);
+ test_big_table(fid);
+ test_varlen(fid);
+ test_opaque(fid);
+ test_error(fid);
+
+ return 0;
+}
+
+int main(void)
+{
+ /* identifier for the file */
+ hid_t fid;
+ int status = 0;
+
+/*-------------------------------------------------------------------------
+ * Packet test: test each function of the packet table
+ *-------------------------------------------------------------------------
+ */
+
+ /* create a file using default properties */
+ fid=H5Fcreate(TEST_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ puts("Testing packet table");
+
+ /* run tests */
+ if ( test_packet_table(fid) < 0)
+ status = 1;
+
+ /* close */
+ H5Fclose(fid);
+
+ return status;
+}