void idlprimfill( HDSLoc *cloc, IDL_VPTR datav, void *datptr, int *status ) { int j; /* loop counters */ UCHAR idltype; /* The IDL type */ char type[DAT__SZTYP+1]; /* Type in which to to map HDS data */ int bpix; /* Number of bytes/value */ int defined; /* If HDS value defined */ void *cpntr; /* True C pointer to mapped data */ size_t nels; /* Number of mapped elements */ int nels_i; size_t nbytes; /* Number of bytes in array */ int flen; /* length of HDS strings */ int clen; /* length of corresponding C string */ char *chars; /* pointer to imported characters */ IDL_STRING *strings; /* pointer to array of string structures */ IDL_VPTR chptr; /* Scratch variable pointer */ if ( *status != SAI__OK ) return; /* check type compatibility */ /* Get the number of bytes per element */ /* and the HDS type in which to map the data */ idltype = datav->type; switch (idltype) { case IDL_TYP_FLOAT: strcpy( type, "_REAL" ); bpix = 4; break; case IDL_TYP_LONG: strcpy( type, "_INTEGER" ); bpix = 4; break; case IDL_TYP_INT: strcpy( type, "_WORD" ); bpix = 2; break; case IDL_TYP_DOUBLE: strcpy( type, "_DOUBLE" ); bpix = 8; break; case IDL_TYP_BYTE: strcpy( type, "_UBYTE" ); bpix = 1; break; case IDL_TYP_STRING: datType( cloc, type, status); bpix = 1; break; default: /* flag no data to copy */ bpix = 0; *status = SAI__ERROR; emsSeti( "TYPE", idltype ); emsRep( " ", "Illegal IDL type ^TYPE", status ); break; } /* end of case */ if ( (*status == SAI__OK ) && bpix ) { /* Map the data as if a vector - provided it is defined */ datState( cloc, &defined, status ); if ( defined ) { datMapV( cloc, type, "READ", &cpntr, &nels, status ); if ( *status != SAI__OK ) { emsRep(" ", "Failed to map HDS component", status ); } else { if ( idltype == IDL_TYP_STRING ) { flen = atoi( type + 6 ); clen = flen + 1; /* Import the Fortran strings to C */ nels_i = (int)nels; chars = IDL_GetScratch( &chptr, nels_i, clen ); cnfImprta( cpntr, flen, chars, clen, 1, &nels_i ); /* set strings to be a pointer to the IDL_STRING structure(s) */ strings = (IDL_STRING *)datptr; /* store the imported strings into the STRING structures */ for ( j=0; j<nels; j++ ) IDL_StrStore( strings+j, &chars[j*clen] ); IDL_Deltmp( chptr ); } else { /* Type other than string */ if ( datav->flags & IDL_V_ARR ) { /* Number Array */ /* copy the data to the array */ nbytes = bpix * nels; memcpy( datptr, cpntr, nbytes ); } else { /* Number Scalar */ switch (idltype) { case IDL_TYP_FLOAT: ((IDL_ALLTYPES *)datptr)->f = *(float *)cpntr; break; case IDL_TYP_LONG: ((IDL_ALLTYPES *)datptr)->l = *(int *)cpntr; break; case IDL_TYP_INT: ((IDL_ALLTYPES *)datptr)->i = *(short *)cpntr; break; case IDL_TYP_DOUBLE: ((IDL_ALLTYPES *)datptr)->d = *(double *)cpntr; break; case IDL_TYP_BYTE: ((IDL_ALLTYPES *)datptr)->c = *(UCHAR *)cpntr; break; } /* end of case */ } /* end of if array */ } /* end if string */ datUnmap( cloc, status ); } /* end of mapped data */ } /* end of if defined */ } /* end of bpix non-zero */ return; }
void atlKy2hd( AstKeyMap *keymap, HDSLoc *loc, int *status ) { /* * Name: * atlKy2hd * Purpose: * Copies values from an AST KeyMap to a primitive HDS object. * Language: * C. * Invocation: * void atlKy2hd( AstKeyMap *keymap, HDSLoc *loc, int *status ) * Description: * This routine copies the contents of an AST KeyMap into a supplied * HDS structure. * Arguments: * keymap * An AST pointer to the KeyMap. * loc * A locator for the HDS object into which the KeyMap contents * are to be copied. A new component is added to the HDS object for * each entry in the KeyMap. * status * The inherited status. * Copyright: * Copyright (C) 2008, 2010, 2012 Science & Technology Facilities Council. * All Rights Reserved. * 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: * DSB: David S. Berry * TIMJ: Tim Jenness (JAC, Hawaii) * {enter_new_authors_here} * History: * 29-APR-2008 (DSB): * Original version. * 2010-09-23 (TIMJ): * Fix arrays of strings. * 2010-09-30 (TIMJ): * Make sure that we are using the correct status pointer in AST. * 2010-10-01 (TIMJ): * Sort the keys when writing to HDS structured. * 2010-10-04 (TIMJ): * Support Short ints in keymap * 14-SEP-2012 (DSB): * Moved from kaplibs to atl. * 17-SEP-2012 (DSB): * Add support for undefined values. * {enter_further_changes_here} * Bugs: * {note_any_bugs_here} */ /* Local Varianles: */ AstObject **objArray = NULL; AstObject *obj = NULL; HDSLoc *cloc = NULL; HDSLoc *dloc = NULL; const char *cval = NULL; const char *key; double dval; float fval; int i; int ival; int j; int lenc; int nval; char *oldsortby; int *oldstat = NULL; int size; int type; int veclen; size_t el; void *pntr = NULL; /* Check inherited status */ if( *status != SAI__OK ) return; /* Make sure that we are checking AST status */ oldstat = astWatch( status ); /* If set, save the old SortBy value and then ensure alphabetical sorting. We need to take a copy of the original string since the buffer in which the string is stored may be re-used by subsequent incocations of astGetC. */ if( astTest( keymap, "SortBy" ) ) { int nc = 0; oldsortby = astAppendString( NULL, &nc, astGetC( keymap, "SortBy" ) ); } else { oldsortby = NULL; } astSet( keymap, "SortBy=KeyUp" ); /* Loop round each entry in the KeyMap. */ size = astMapSize( keymap ); for( i = 0; i < size; i++ ) { if (*status != SAI__OK) break; /* Get the key. the data type and the vector length for the current KeyMap entry. */ key = astMapKey( keymap, i ); type = astMapType( keymap, key ); veclen = astMapLength( keymap, key ); /* If the current entry holds one or more nested KeyMaps, then we call this function recursively to add them into a new HDS component. */ if( type == AST__OBJECTTYPE ) { /* First deal with scalar entries holding a single KeyMap. */ if( veclen == 1 ) { datNew( loc, key, "KEYMAP_ENTRY", 0, NULL, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0A( keymap, key, &obj ); if( astIsAKeyMap( obj ) ) { atlKy2hd( (AstKeyMap *) obj, cloc, status ); } else if( *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "atlKy2hd: Supplied KeyMap contains unusable AST " "objects (programming error).", status ); } datAnnul( &cloc, status ); /* Now deal with vector entries holding multiple KeyMaps. */ } else { datNew( loc, key, "KEYMAP_ENTRY", 1, &veclen, status ); datFind( loc, key, &cloc, status ); objArray = astMalloc( sizeof( AstObject *) * (size_t)veclen ); if( objArray ) { (void) astMapGet1A( keymap, key, veclen, &nval, objArray ); for( j = 1; j <= veclen; j++ ) { datCell( cloc, 1, &j, &dloc, status ); if( astIsAKeyMap( objArray[ j - 1 ] ) ) { atlKy2hd( (AstKeyMap *) objArray[ j - 1 ], dloc, status ); } else if( *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "atlKy2hd: Supplied KeyMap contains unusable AST " "objects (programming error).", status ); } datAnnul( &dloc, status ); } objArray = astFree( objArray ); } datAnnul( &cloc, status ); } /* For primitive types... */ } else if( type == AST__INTTYPE ) { if( veclen == 1 ) { datNew0I( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0I( keymap, key, &ival ); datPut0I( cloc, ival, status ); datAnnul( &cloc, status ); } else { datNew1I( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_INTEGER", "WRITE", &pntr, &el, status ); (void) astMapGet1I( keymap, key, veclen, &nval, (int *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__SINTTYPE ) { short sval = 0; if( veclen == 1 ) { datNew0W( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0S( keymap, key, &sval ); datPut0W( cloc, sval, status ); datAnnul( &cloc, status ); } else { datNew1W( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_WORD", "WRITE", &pntr, &el, status ); (void) astMapGet1S( keymap, key, veclen, &nval, (short *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__DOUBLETYPE ) { if( veclen == 1 ) { datNew0D( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0D( keymap, key, &dval ); datPut0D( cloc, dval, status ); datAnnul( &cloc, status ); } else { datNew1D( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_DOUBLE", "WRITE", &pntr, &el, status ); (void) astMapGet1D( keymap, key, veclen, &nval, (double *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__FLOATTYPE ) { if( veclen == 1 ) { datNew0R( loc, key, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0F( keymap, key, &fval ); datPut0R( cloc, fval, status ); datAnnul( &cloc, status ); } else { datNew1R( loc, key, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_REAL", "WRITE", &pntr, &el, status ); (void) astMapGet1F( keymap, key, veclen, &nval, (float *) pntr ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } } else if( type == AST__STRINGTYPE ) { lenc = astMapLenC( keymap, key ); if( veclen == 1 ) { datNew0C( loc, key, lenc, status ); datFind( loc, key, &cloc, status ); (void) astMapGet0C( keymap, key, &cval ); datPut0C( cloc, cval, status ); datAnnul( &cloc, status ); } else { datNew1C( loc, key, lenc, veclen, status ); datFind( loc, key, &cloc, status ); datMapV( cloc, "_CHAR", "WRITE", &pntr, &el, status ); (void) atlMapGet1C( keymap, key, veclen*lenc, lenc, &nval, (char *) pntr, status ); datUnmap( cloc, status ); datAnnul( &cloc, status ); } /* KeyMap "UNDEF" values are always scalar and have no corresponding HDS data type. So arbitrarily use an "_INTEGER" primitive with no defined value to represent a KeyMap UNDEF value. */ } else if( type == AST__UNDEFTYPE ) { datNew0L( loc, key, status ); /* Unknown or unsupported data types. */ } else if( *status == SAI__OK ) { *status = SAI__ERROR; msgSeti( "T", type ); errRep( "", "atlKy2hd: Supplied KeyMap contains entries with " "unusable data type (^T) (programming error).", status ); } } /* If it was originally set, re-instate the old SortBy value in the KeyMap, then free the memory. Otherwise, clear the SortBy attribute. */ if( oldsortby ) { astSetC( keymap, "SortBy", oldsortby ); oldsortby = astFree( oldsortby ); } else { astClear( keymap, "SortBy" ); } /* Reset AST status */ astWatch( oldstat ); }
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; } }