int datAnnul( HDSLoc **locator, int * status ) { /* Attempts to run even if status is bad */ int lstat = SAI__OK; /* Sanity check argument */ if (!locator) return *status; if (! *locator) return *status; /* Begin an entirely new error context as we need to run this regardless of external errors */ lstat = *status; emsBegin( &lstat ); emsMark(); /* Free file resources */ dat1Annul( *locator, &lstat ); /* Free the memory associated with this locator */ *locator = dat1FreeLoc( *locator, &lstat ); /* End the error context and return the final status */ emsRlse(); emsEnd( &lstat ); *status = lstat; return *status; }
int datValid(const HDSLoc *locator, hdsbool_t *valid, int *status) { /* Initialise the returned value */ *valid = 0; /* Check a locator was supplied. */ if ( !locator ) return *status; /* Begin a new error reporting context */ emsBegin( status ); /* Check the validity of the locator */ if (locator->group_id > 0 || locator->dataset_id > 0 ) { if( HANDLE_VALID(locator->handle) ) *valid = 1; } /* End the current error reporting context */ emsEnd( status ); return *status; }
void rec_stop( void ) { /*+ */ /* Name: */ /* rec_stop */ /* Purpose: */ /* Close down the rec_ facility. */ /* Invocation: */ /* rec_stop( ) */ /* Description: */ /* This function ensures that the rec_ facility is closed down. All */ /* cached data are written back to disk and associated resources are */ /* released. It returns without action if the rec_ facility is already */ /* inactive. */ /* Parameters: */ /* void */ /* Returned Value: */ /* void */ /* Notes: */ /* This routine attempts to execute even if the global HDS status is set */ /* on entry, although no further error report will be made if it */ /* subsequently fails under these circumstances. */ /* Copyright: */ /* Copyright (C) 1992 Science & Engineering Research Council */ /* Copyright (C) 2006 Particle Physics and Astronomy Research Council */ /* Licence: */ /* This program is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of */ /* the License, or (at your option) any later version. */ /* This program is distributed in the hope that it will be */ /* useful, but WITHOUT ANY WARRANTY; without even the implied */ /* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */ /* PURPOSE. See the GNU General Public License for more details. */ /* You should have received a copy of the GNU General Public */ /* License along with this program; if not, write to the Free */ /* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, */ /* MA 02110-1301, USA */ /* Authors: */ /* RFWS: R.F. Warren-Smith (STARLINK) */ /* TIMJ: Tim Jenness (JAC, Hawaii) */ /* {@enter_new_authors_here@} */ /* History: */ /* 22-APR-1991 (RFWS): */ /* Added prologue and error handling and tidied. */ /* 12-JUN-1991 (RFWS): */ /* Removed unnecessary flushing of the Working Page List - cached */ /* blocks are flushed when the File Control Vector slots are closed. */ /* 30-OCT-1992 (RFWS): */ /* Added deallocation of remaining wild-card file search contexts. */ /* 25-NOV-1992 (RFWS): */ /* Changed to deallocate the File Control Vector and to return a void */ /* value. */ /* 31-JAN-2006 (TIMJ): */ /* Free memory associated with the Block Control Packets */ /* 01-FEB-2006 (TIMJ): */ /* Free memory allocated by rec1_getcwd */ /* {@enter_further_changes_here@} */ /* Bugs: */ /* {@note_any_bugs_here@} */ /*- */ /* Local Variables: */ INT slot; /* Loop counter for File Control Vector */ struct WLD *context; /* Pointer to wild-card search context */ /*. */ /* Check that the rec_ facility is active. There is nothing to do if it is */ /* not. */ if ( rec_gl_active ) { /* Begin a new error reporting context. */ emsBegin( &hds_gl_status ); /* Shut down all the open slots in the File Control Vector. Then deallocate */ /* the FCV itself. */ for ( slot = 0; slot < rec_gl_endslot; slot++ ) { rec1_close_slot( slot ); } rec_deall_mem( rec_gl_mxslot * sizeof( struct FCV ), (void **) &rec_ga_fcv ); /* Deallocate any remaining wild-card file search contexts. */ while ( rec_gl_wldque != NULL ) { context = rec_gl_wldque; rec_end_wild( &context ); } /* Deallocate the memory associated with the free page list */ /* The malloced memory area may not even be reachable in the linked list so we obtain the pointer from the global that exists for exactly this purpose */ if (rec_ga_fpl_malloced != NULL) rec_deall_mem( hds_gl_maxwpl * sizeof( struct BCP ), (void **)&rec_ga_fpl_malloced ); /* Free the getcwd buffer */ rec1_getcwd_free( ); /* Note that the rec_ facility is no longer active. */ rec_gl_active = 0; /* End the error reporting context. */ emsEnd( &hds_gl_status ); } /* Exit the routine. */ return; }
int dau_flush_data(struct LCP_DATA *data) /*+ * DAU_FLUSH_DATA - Flush mapped data * * This routine will unmap any primitive data that is currently mapped to the * specified locator. If the data object is a discontiguous slice, then a * scatter write-back is performed if mapped in either 'WRITE' or 'UPDATE' mode. * * Calling sequence: * * DAU_FLUSH_DATA(DATA) * * DATA is the address of the data part of the Locator Control Packet. * * Routine value: * * DAT__OK if successful. */ { struct LCP_STATE *state; struct PDD *app; struct PDD *obj; unsigned char *dom; int writing; INT_BIG objlen; INT_BIG objoff; INT_BIG applen; int nbad; int mapsave; /* Return if no data currently mapped. */ state = &data->state; if ( !state->mapped ) return hds_gl_status; /* Begin a new error reporting context. */ emsBegin( &hds_gl_status ); /* Set the global file mapping flag to the value used when the data were */ /* originally mapped. */ mapsave = hds_gl_map; hds_gl_map = data->filemap; /* Associate the application data and object data attributes descriptors. */ app = &data->app; obj = &data->obj; writing = (data->mode != 'R'); /* Calculate the length (in bytes) of the virtual memory allocated to the application program data and the corresponding length of the object data. Determine the byte-offset into the object record's dynamic domain. */ applen = app->length * data->size; objlen = obj->length * data->size; objoff = obj->length * data->offset; /* Scatter discontiguous object data if the program is writing or updating. */ if (state->broken) { if (writing) { dau_scatter_data(1, data, &nbad ); /* If conversion errors occurred, then report contextual information. */ if ( hds_gl_status == DAT__CONER ) { emsSeti( "NBAD", nbad ); emsRep( "DAU_FLUSH_1", "A total of ^NBAD data conversion error(s) occurred.", &hds_gl_status ); } } rec_deall_xmem( applen, (void **) &app->body ); } /* If a copy of the object data was given to the program, then locate the record's dynamic domain and translate the data from the virtual memory copy. */ else if (state->vmcopy) { if (writing) { rec_locate_data(&data->han, objlen, objoff, 'W', &dom); obj->body = dom; dat1_cvt( 1, data->size, app, obj, &nbad ); /* If conversion errors occurred, then report contextual information. */ if ( hds_gl_status == DAT__CONER ) { emsSeti( "NBAD", nbad ); emsRep( "DAU_FLUSH_2", "A total of ^NBAD data conversion error(s) occurred.", &hds_gl_status ); } rec_release_data(&data->han, objlen, objoff, 'W', &dom); } rec_deall_xmem( applen, (void **) &app->body ); } /* Otherwise, the application program was given direct access to the data. */ else { dom = app->body; rec_release_data(&data->han, objlen, objoff, data->mode, &dom); } /* Clear the pointer and the map flags. */ app->body = 0; state->mapped = 0; state->unlike = 0; state->vmcopy = 0; /* Restore the global file mapping flag. */ hds_gl_map = mapsave; /* End the error reporting context. */ emsEnd( &hds_gl_status ); return hds_gl_status; }
int main (void) { /* Local Variables: */ const char path[] = "hds_ctest"; int status = DAT__OK; hdsdim dim[] = { 10, 20 }; hdsdim dimd[1]; const char * chararr[] = { "TEST1", "TEST2", "Longish String" }; char *retchararr[4]; char buffer[1024]; /* plenty large enough */ double darr[] = { 4.5, 2.5 }; double retdarr[2]; void *mapv; /* Mapped void* */ double *mapd; /* Mapped _DOUBLE */ float *mapf; /* Mapped _REAL */ int *mapi; /* Mapped _INTEGER */ int64_t *mapi64; /* Mapped _INT64 */ HDSLoc * loc1 = NULL; HDSLoc * loc2 = NULL; HDSLoc * loc3 = NULL; size_t actval; size_t nel; size_t nelt; size_t nbytes; size_t i; int n; double sumd; int sumi; int64_t sumi64; int64_t test64; int64_t testin64; const int64_t VAL__BADK = (-9223372036854775807 - 1); emsBegin(&status); /* Force 64-bit mode */ hdsTune( "64BIT", 1, &status ); /* Create a new container file */ hdsNew( path, "HDS_TEST", "NDF", 0, dim, &loc1, &status ); /* Some components */ datNew( loc1, "DATA_ARRAY", "_INTEGER", 2, dim, &status ); datNew1C( loc1, "ONEDCHAR", 14, 3, &status ); datNew1D( loc1, "ONEDD", 2, &status ); datNew0K( loc1, "TESTI64", &status ); datNew0K( loc1, "TESTBADI64", &status ); /* Populate */ testin64 = 9223372036854775800; datFind( loc1, "TESTI64", &loc2, &status ); datPut0K( loc2, testin64, &status ); datGet0K( loc2, &test64, &status ); datAnnul( &loc2, &status ); if (status == DAT__OK) { if ( test64 != testin64 ) { status = DAT__FATAL; emsRepf( "TESTI64", "Test _INT64 value %" PRIi64 " did not match expected %"PRIi64, &status, test64, testin64 ); } } datFind( loc1, "TESTBADI64", &loc2, &status ); datPut0K( loc2, VAL__BADK, &status ); datGet0K( loc2, &test64, &status ); datAnnul( &loc2, &status ); if (status == DAT__OK) { if ( test64 != VAL__BADK ) { status = DAT__FATAL; emsRepf( "TESTBADI64", "Test _INT64 value %" PRIi64 " did not match expected VAL__BADK", &status, test64 ); } } datFind( loc1, "ONEDCHAR", &loc2, &status ); datPutVC( loc2, 3, chararr, &status ); /* Check contents */ datGetVC(loc2, 3, 1024, buffer, retchararr, &actval, &status); if (status == DAT__OK) { if (actval == 3) { for (i = 0; i < 3; i++ ) { if (strncmp( chararr[i], retchararr[i], strlen(chararr[i]) ) ) { status = DAT__DIMIN; emsSetc( "IN", chararr[i]); emsSetc( "OUT", retchararr[i] ); emsRep( "GET1C","Values from Get1C differ (^IN != ^OUT)", &status); break; } } } else { status = DAT__DIMIN; emsRep( "GET1C","Did not get back as many strings as put in", &status); } } datAnnul( &loc2, &status ); datFind( loc1, "ONEDD", &loc2, &status ); datPutVD( loc2, 2, darr, &status ); /* Check contents */ datGetVD( loc2, 2, retdarr, &actval, &status); if (status == DAT__OK) { if (actval == 2) { for (i = 0; i < 2; i++ ) { if (darr[i] != retdarr[i]) { status = DAT__DIMIN; emsRep( "GETVD","Values from getVD differ", &status); break; } } } else { status = DAT__DIMIN; emsRep( "GETVD","Did not get back as many values as put in", &status); } } /* Try mapping - _DOUBLE */ dimd[0] = 2; datMapD(loc2, "READ", 1, dimd, &mapd, &status); if (status == DAT__OK) { for (i = 0; i < 2; i++ ) { if (darr[i] != mapd[i]) { status = DAT__DIMIN; emsRep( "MAPD","Values from MapD differ", &status); break; } } } datUnmap(loc2, &status); /* Try mapping - _FLOAT */ datMapR(loc2, "READ", 1, dimd, &mapf, &status); if (status == DAT__OK) { for (i = 0; i < 2; i++ ) { if ( (float)darr[i] != mapf[i]) { status = DAT__DIMIN; emsRep( "MAPR","Values from MapR differ", &status); break; } } } datUnmap(loc2, &status); /* Annul */ datAnnul( &loc2, &status ); /* Find and map DATA_ARRAY */ datFind( loc1, "DATA_ARRAY", &loc2, &status ); datMapV( loc2, "_REAL", "WRITE", &mapv, &nel, &status ); mapf = mapv; if (status == DAT__OK) { nelt = dim[0] * dim[1]; if ( nelt != nel) { status = DAT__FATAL; emsSeti( "NEL", (int)nel ); emsSeti( "NORI", (int)nelt ); emsRep( "SIZE","Number of elements originally (^NORI) not the same as now (^NEL)", &status); } } sumd = 0.0; for (i = 1; i <= nel; i++) { mapf[i-1] = (float)i; sumd += (double)i; } datUnmap( loc2, &status ); datAnnul( &loc2, &status ); hdsClose( &loc1, &status ); /* Re-open */ hdsOpen( path, "UPDATE", &loc1, &status ); /* Look for the data array and map it */ datFind( loc1, "DATA_ARRAY", &loc2, &status ); datVec( loc2, &loc3, &status ); datSize( loc3, &nel, &status); if (status == DAT__OK) { nelt = dim[0] * dim[1]; if ( nelt != nel) { status = DAT__FATAL; emsSeti( "NEL", (int)nel ); emsSeti( "NORI", (int)nelt ); emsRep( "SIZE","Number of elements before (^NORI) not the same as now (^NEL)", &status); } } datPrec( loc3, &nbytes, &status ); if (status == DAT__OK) { if ( nbytes != 4) { status = DAT__FATAL; emsSeti( "NB", nbytes ); emsRep( "PREC","Precision for _REAL not 4 bytes but ^NB", &status); } } /* Try hdsShow */ hdsShow("LOCATORS", &status); hdsShow("FILES", &status); hdsInfoI(NULL, "LOCATORS", "!HDS_TEST.,YYY", &n, &status ); hdsInfoI(NULL, "FILES", NULL, &n, &status ); datAnnul( &loc3, &status ); datMapV( loc2, "_INTEGER", "READ", &mapv, &nel, &status ); mapi = mapv; if (status == DAT__OK) { nelt = dim[0] * dim[1]; if ( nelt != nel) { status = DAT__FATAL; emsSeti( "NEL", (int)nel ); emsSeti( "NORI", (int)nelt ); emsRep( "SIZE","Number of elements originally (^NORI) not the same as now (^NEL)", &status); } } sumi = 0; for (i = 0; i < nel; i++) { sumi += mapi[i]; } datUnmap( loc2, &status ); if (status == DAT__OK) { if (sumi != (int)sumd) { status = DAT__FATAL; emsSeti( "I", sumi ); emsSeti( "D", (int)sumd ); emsRep("SUM","Sum was not correct. Got ^I rather than ^D", &status ); } } /* _INT64 test */ datMapV( loc2, "_INT64", "READ", &mapv, &nel, &status ); mapi64 = mapv; if (status == DAT__OK) { nelt = dim[0] * dim[1]; if ( nelt != nel) { status = DAT__FATAL; emsSeti( "NEL", (int)nel ); emsSeti( "NORI", (int)nelt ); emsRep( "SIZE","Number of elements originally (^NORI) not the same as now (^NEL)", &status); } } sumi64 = 0; for (i = 0; i < nel; i++) { sumi64 += mapi64[i]; } datUnmap( loc2, &status ); if (status == DAT__OK) { if (sumi64 != (int)sumd) { status = DAT__FATAL; emsSeti( "I", (int)sumi64 ); emsSeti( "D", (int)sumd ); emsRep("SUM","Sum was not correct. Got ^I rather than ^D", &status ); } } /* Tidy up and close */ hdsErase( &loc1, &status ); if (status == DAT__OK) { printf("HDS C installation test succeeded\n"); emsEnd(&status); return EXIT_SUCCESS; } else { printf("HDS C installation test failed\n"); emsEnd(&status); return EXIT_FAILURE; } }