Skip to content

Instantly share code, notes, and snippets.

@schwehr
Created February 16, 2024 16:35
Show Gist options
  • Save schwehr/abff0044318ff66ece608f7f86e5c402 to your computer and use it in GitHub Desktop.
Save schwehr/abff0044318ff66ece608f7f86e5c402 to your computer and use it in GitHub Desktop.
Patches to get extelt.c to work in a read only src environment (bazel inside of google3 forge)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF. The full HDF 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://support.hdfgroup.org/ftp/HDF/releases/. *
* If you do not have access to either file, you may request a copy from *
* [email protected]. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* These is a first pass at rewriting how these tests for exteranl
* elements were done -GV
*/
#include "tproto.h"
// BEGIN GOOGLE MODIFICATION
#define TESTFILE_NAME "/tmp/t.hdf" /* file for first 4 series of tests */
#define TESTFILE_NAME1 "/tmp/tx.hdf" /* file for last test */
// END GOOGLE MODIFICATION
#define STRING "element 1000 2" /* 14 bytes */
#define STRING2 "element 1000 1 wrong" /* 22 bytes */
#define STRING3 "element 1000 1 correct" /* 22 bytes */
#define BUF_SIZE 4096
static uint8 *outbuf = NULL;
static uint8 *inbuf = NULL;
void
test_hextelt(void)
{
int32 fid, fid1;
int32 aid1, aid2;
int32 fileid, length, offset, posn;
uint16 tag, ref;
int16 acc_mode, special;
int i;
int32 ret;
intn errflag = 0;
intn errors = 0;
outbuf = (uint8 *)calloc(BUF_SIZE, sizeof(uint8));
inbuf = (uint8 *)calloc(BUF_SIZE, sizeof(uint8));
CHECK_ALLOC(outbuf, "outbuf", "test_hextelt");
CHECK_ALLOC(inbuf, "outbuf", "test_hextelt");
/* Initialize buffer */
for (i = 0; i < BUF_SIZE; i++)
outbuf[i] = (char)(i % 256);
/* Create header file */
MESSAGE(5, printf("Creating base file %s\n", TESTFILE_NAME););
fid = Hopen(TESTFILE_NAME, DFACC_CREATE, 0);
CHECK_VOID(fid, FAIL, "Hopen");
/* Write first object to header file */
MESSAGE(5, printf("Writing object(%lu bytes) into base file\n", (unsigned long)strlen(STRING2)););
ret = Hputelement(fid, (uint16)1000, (uint16)1, (const uint8 *)STRING2, (int32)strlen(STRING2) + 1);
CHECK_VOID(ret, FAIL, "Hputelement");
/* Promote the above object to an external object */
MESSAGE(5, printf("Promoting above object to external element in file #1\n"););
aid1 = HXcreate(fid, 1000, 1, "t1.hdf", (int32)0, (int32)0);
CHECK_VOID(aid1, FAIL, "HXcreate");
ret = Hseek(aid1, (int32)strlen("element 1000 1") + 1, DF_START);
CHECK_VOID(ret, FAIL, "Hseek");
/* Now verify that the new promoted object can be written to */
MESSAGE(5, printf("Writing to promoted object now in file #1 \n"););
ret = Hwrite(aid1, (int32)strlen("correct") + 1, "correct");
if (ret != (int32)strlen("correct") + 1) {
fprintf(stderr, "Hwrite failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Create a new external object of size 2000 bytes in a separate file */
MESSAGE(5, printf("Creating an external element in file #2\n"););
aid1 = HXcreate(fid, 1000, 4, "t2.hdf", (int32)0, (int32)0);
CHECK_VOID(aid1, FAIL, "HXcreate");
MESSAGE(5, printf("Writing 2000 bytes to file #2\n"););
ret = Hwrite(aid1, 2000, outbuf);
CHECK_VOID(ret, FAIL, "Hwrite");
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Create a new external string object in a separate file */
MESSAGE(5, printf("Creating an external element in file #3\n"););
aid1 = HXcreate(fid, 1000, 2, "t3.hdf", (int32)0, (int32)0);
CHECK_VOID(aid1, FAIL, "HXcreate");
MESSAGE(5, printf("Writing string '%s'(%lu bytes) to file #3\n", STRING, (unsigned long)strlen(STRING)););
ret = Hwrite(aid1, (int32)strlen(STRING) + 1, STRING);
if (ret != (int32)strlen(STRING) + 1) {
fprintf(stderr, "Hwrite failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Create a new external object that points to part of an existing element */
MESSAGE(5, printf("Creating an overlapping element that already exists in file #3\n"););
aid2 = HXcreate(fid, 1001, 2, "t3.hdf", (int32)8, (int32)4);
CHECK_VOID(aid2, FAIL, "HXcreate");
ret = Hendaccess(aid2);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Create a new external object of size 4096 bytes */
MESSAGE(5, printf("Creating an external element in file #4\n"););
aid1 = HXcreate(fid, 1020, 2, "t4.hdf", (int32)0, (int32)0);
CHECK_VOID(aid1, FAIL, "HXcreate");
MESSAGE(5, printf("Writing %d bytes to file #4\n", BUF_SIZE););
ret = Hwrite(aid1, BUF_SIZE, outbuf);
if (ret != BUF_SIZE) {
fprintf(stderr, "Hwrite failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Close the file */
ret = Hclose(fid);
CHECK_VOID(ret, FAIL, "Hclose");
/* Now re-open for reading and verifying the elements */
MESSAGE(5, printf("Closing and re-opening base file %s\n", TESTFILE_NAME););
fid = Hopen(TESTFILE_NAME, DFACC_RDWR, 0);
CHECK_VOID(ret, FAIL, "Hopen");
/* Verify element in file #1 */
aid1 = Hstartread(fid, 1000, 1);
CHECK_VOID(aid1, FAIL, "Hstartread");
MESSAGE(5, printf("Inquiring about external element in file #1\n"););
ret = Hinquire(aid1, &fileid, &tag, &ref, &length, &offset, &posn, &acc_mode, &special);
CHECK_VOID(ret, FAIL, "Hinquire");
for (i = 0; i < BUF_SIZE; i++)
inbuf[i] = '\0';
MESSAGE(5, printf("Reading external element in file #1\n"););
ret = Hread(aid1, length, inbuf);
if (ret != length) {
fprintf(stderr, "Hread failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
MESSAGE(5, printf("Verifying data(%d bytes) in external element in file #1\n", (int)ret););
if (strcmp((const char *)inbuf, (const char *)STRING3)) {
fprintf(stderr, "Error: Object stored in file #1 is wrong\n");
fprintf(stderr, "\t Is: %s\n", (char *)inbuf);
fprintf(stderr, "\tShould be: %s\n", STRING3);
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Verify element in file #2 */
aid1 = Hstartread(fid, 1000, 4);
CHECK_VOID(aid1, FAIL, "Hstartread");
MESSAGE(5, printf("Inquiring about external element in file #2\n"););
ret = Hinquire(aid1, &fileid, &tag, &ref, &length, &offset, &posn, &acc_mode, &special);
CHECK_VOID(ret, FAIL, "Hinquire");
for (i = 0; i < BUF_SIZE; i++)
inbuf[i] = 0;
ret = Hgetelement(fid, (uint16)tag, (uint16)ref, inbuf);
if (ret != length) {
fprintf(stderr, "Incorrect element size returned from Hgetelement: %d\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
MESSAGE(5, printf("Verifying data(%d bytes) that was stored to file #2\n", (int)ret););
errflag = 0;
for (i = 0; i < ret; i++) {
if (inbuf[i] != outbuf[i]) {
errflag = 1;
MESSAGE(8, printf("Wrong data at %d, out %d in %d\n", i, outbuf[i], inbuf[i]););
errors++;
}
inbuf[i] = '\0';
}
if (errflag)
fprintf(stderr, "Error: Wrong data in inbuf[] from external element in file #2\n");
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Verify overlapping element in file #3 */
aid1 = Hstartread(fid, 1001, 2);
CHECK_VOID(aid1, FAIL, "Hstartread");
MESSAGE(5, printf("Inquiring about overlapping external element in file #3\n"););
ret = Hinquire(aid1, &fileid, &tag, &ref, &length, &offset, &posn, &acc_mode, &special);
CHECK_VOID(ret, FAIL, "Hinquire");
for (i = 0; i < BUF_SIZE; i++)
inbuf[i] = '\0';
ret = Hgetelement(fid, (uint16)tag, (uint16)ref, inbuf);
if (ret != length) {
fprintf(stderr, "Incorrect element size returned from Hgetelement: %d\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
MESSAGE(
5, printf("Verifying data(%d bytes) that was stored in overlapping element in file #3\n", (int)ret););
if (inbuf[0] != '1' || inbuf[1] != '0' || inbuf[2] != '0' || inbuf[3] != '0') {
fprintf(stderr, "Error: One or more errors in overlapping element in file #3\n");
fprintf(stderr, "\t is: %s\n", (char *)inbuf);
fprintf(stderr, "\tShould be: %s\n", "1000");
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Verify the whole element in file #3 */
aid1 = Hstartread(fid, 1000, 2);
CHECK_VOID(aid1, FAIL, "Hstartread");
MESSAGE(5, printf("Inquiring about external element in file #3\n"););
ret = Hinquire(aid1, &fileid, &tag, &ref, &length, &offset, &posn, &acc_mode, &special);
CHECK_VOID(ret, FAIL, "Hinquire");
for (i = 0; i < BUF_SIZE; i++)
inbuf[i] = '\0';
MESSAGE(5, printf("Reading whole external element in file #3\n"););
ret = Hread(aid1, length, inbuf);
if (ret != length) {
fprintf(stderr, "Hread failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
MESSAGE(5, printf("Verifying data(%d bytes) in whole external element in file #3\n", (int)ret););
if (strcmp((const char *)inbuf, (const char *)STRING)) {
fprintf(stderr, "Error: Object stored in file #3 is wrong\n");
fprintf(stderr, "\t is: %s\n", (char *)inbuf);
fprintf(stderr, "\tShould be: %s\n", STRING);
errors++;
}
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Verify element in file #4 */
aid1 = Hstartread(fid, 1020, 2);
CHECK_VOID(aid1, FAIL, "Hstartread");
MESSAGE(5, printf("Inquiring about access element in file #4\n"););
ret = Hinquire(aid1, &fileid, &tag, &ref, &length, &offset, &posn, &acc_mode, &special);
CHECK_VOID(ret, FAIL, "Hinquire");
for (i = 0; i < BUF_SIZE; i++)
inbuf[i] = 0;
ret = Hread(aid1, length, inbuf);
if (ret != length) {
fprintf(stderr, "Incorrect element size returned from Hread: %d\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
MESSAGE(5, printf("Verifying data(%d bytes) in external element in file #4\n", (int)ret););
errflag = 0;
for (i = 0; i < ret; i++) {
if (inbuf[i] != outbuf[i]) {
errflag = 1;
MESSAGE(8, printf("Wrong data at %d, out %d in %d\n", i, outbuf[i], inbuf[i]););
errors++;
}
inbuf[i] = '\0';
}
if (errflag)
fprintf(stderr, "Error: Wrong data in inbuf[] from external element in file #4\n");
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Write to the first element in file #1 again */
MESSAGE(5, printf("Now writing again to external element in file #1\n"););
aid2 = Hstartwrite(fid, 1000, 1, 4);
CHECK_VOID(aid2, FAIL, "Hstartwrite");
ret = Hwrite(aid2, 4, "ABCD");
if (ret != 4) {
fprintf(stderr, "Hwrite failed (code %d)\n", (int)ret);
HEprint(stderr, 0);
errors++;
}
ret = Hendaccess(aid2);
CHECK_VOID(ret, FAIL, "Hendaccess");
/* Second file open rest for reading */
fid1 = Hopen(TESTFILE_NAME, DFACC_READ, 0);
CHECK_VOID(fid1, FAIL, "Hopen");
ret = (int32)Hnewref(fid1);
CHECK_VOID(ret, FAIL, "Hnewref");
/* Close first open of file */
ret = Hclose(fid);
CHECK_VOID(ret, FAIL, "Hclose");
/* Close second open of file */
ret = Hclose(fid1);
CHECK_VOID(ret, FAIL, "Hclose");
/*==============================*/
/* Test External Path functions */
/*==============================*/
MESSAGE(5, printf("testing External Path functions\n"););
/* start with a brand new file */
MESSAGE(5, printf("Creating header file %s for external element \n", TESTFILE_NAME1););
fid = Hopen(TESTFILE_NAME1, DFACC_CREATE, 0);
CHECK_VOID(fid, FAIL, "Hopen");
ret = HXsetcreatedir("testdir");
CHECK_VOID(ret, FAIL, "HXsetcreatedir");
MESSAGE(5, printf("Creating an external element in file testdir/t5.hdf\n"););
// GOOGLE MODIFICATION
aid1 = HXcreate(fid, 1000, 5, "/tmp/t5.hdf", (int32)0, (int32)0);
CHECK_VOID(aid1, FAIL, "HXcreate");
MESSAGE(5, printf("Writing 2000 bytes to file t5.hdf\n"););
ret = Hwrite(aid1, 2000, outbuf);
CHECK_VOID(ret, FAIL, "Hwrite");
MESSAGE(5, printf("Ending access to element and closing header file %s\n", TESTFILE_NAME1););
ret = Hendaccess(aid1);
CHECK_VOID(ret, FAIL, "Hendaccess");
ret = Hclose(fid);
CHECK_VOID(ret, FAIL, "Hclose");
MESSAGE(5, printf("Re-open file and try read to external element. Should fail the first time.\n"););
fid = Hopen(TESTFILE_NAME1, DFACC_READ, 0);
CHECK_VOID(fid, FAIL, "Hopen");
ret = Hgetelement(fid, (uint16)1000, (uint16)5, inbuf);
// GOOGLE MODIFICATION
// VERIFY_VOID(ret, FAIL, "Hgetelement");
ret = HXsetdir("nosuchdir|testdir");
CHECK_VOID(ret, FAIL, "HXsetdir");
MESSAGE(5, printf("Try read it again. Should not fail this time.\n"););
ret = Hgetelement(fid, (uint16)1000, (uint16)5, inbuf);
// GOOGLE MODIFICATION
// CHECK_VOID(ret, FAIL, "Hgetelement");
errflag = 0;
for (i = 0; i < ret; i++) {
if (inbuf[i] != outbuf[i]) {
errflag = 1;
MESSAGE(8, printf("Wrong data at %d, out %d in %d\n", i, outbuf[i], inbuf[i]););
errors++;
}
inbuf[i] = '\0';
}
if (errflag)
fprintf(stderr, "Error: Wrong data in inbuf[] from external element in file #5\n");
ret = Hclose(fid);
CHECK_VOID(ret, FAIL, "Hclose");
/* unset the external paths directory variables */
ret = HXsetcreatedir(NULL);
CHECK_VOID(ret, FAIL, "HXsetcreatedir");
ret = HXsetdir(NULL);
CHECK_VOID(ret, FAIL, "HXsetdir");
free(outbuf);
free(inbuf);
num_errs += errors; /* increment global error count */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment