diff options
author | Picca Frédéric-Emmanuel <picca@debian.org> | 2022-02-02 14:19:58 +0100 |
---|---|---|
committer | Picca Frédéric-Emmanuel <picca@debian.org> | 2022-02-02 14:19:58 +0100 |
commit | 4e774db12d5ebe7a20eded6dd434a289e27999e5 (patch) | |
tree | a9822974ba45196f1e3740995ab157d6eb214a04 /src/silx/io/specfile/src/sftools.c | |
parent | d3194b1a9c4404ba93afac43d97172ab24c57098 (diff) |
New upstream version 1.0.0+dfsg
Diffstat (limited to 'src/silx/io/specfile/src/sftools.c')
-rw-r--r-- | src/silx/io/specfile/src/sftools.c | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/src/silx/io/specfile/src/sftools.c b/src/silx/io/specfile/src/sftools.c new file mode 100644 index 0000000..9b78b67 --- /dev/null +++ b/src/silx/io/specfile/src/sftools.c @@ -0,0 +1,554 @@ +# /*########################################################################## +# Copyright (C) 1995-2017 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ############################################################################*/ +/************************************************************************ + * + * File: sftools.c + * + * Project: SpecFile library + * + * Description: General library tools + * + * Author: V.Rey + * + * Date: $Date: 2004/05/12 16:57:02 $ + * + ************************************************************************/ +/* + * Log: $Log: sftools.c,v $ + * Log: Revision 1.2 2004/05/12 16:57:02 sole + * Log: Windows support + * Log: + * Log: Revision 1.1 2003/09/12 10:34:11 sole + * Log: Initial revision + * Log: + * Log: Revision 3.0 2000/12/20 14:17:19 rey + * Log: Python version available + * Log: + * Log: Revision 2.2 2000/12/20 12:12:08 rey + * Log: bug corrected with SfAllMotors + * Log: + * Revision 2.1 2000/07/31 19:05:07 19:05:07 rey (Vicente Rey-Bakaikoa) + * SfUpdate and bug corrected in ReadIndex + * + * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa) + * New version of the library. Complete rewrite + * Adds support for MCA + */ +#include <SpecFile.h> +#include <SpecFileP.h> + +#ifdef WIN32 +#include <stdio.h> +#include <stdlib.h> +#else +#include <unistd.h> +#endif + +/* + * Library Functions + */ +DllExport void freePtr ( void *ptr ); +DllExport void freeArrNZ ( void ***ptr, long lines ); +DllExport void SfShow (SpecFile *sf); +DllExport void SfShowScan (SpecFile *sf, long index); + +/* + * Function declaration + */ +void freeArr ( void ***ptr, long lines ); + +int sfSetCurrent ( SpecFile *sf, long index, int *error ); +int sfSameFile ( SpecFile *sf, ObjectList *list ); +int sfSameScan ( SpecFile *sf, long index ); + +int findIndex ( void *scan, void *number ); +int findNoAndOr ( void *scan, void *number ); +int findFirst ( void *scan, void *file_offset ); +ObjectList *findScanByIndex ( ListHeader *list, long index ); +ObjectList *findFirstInFile ( ListHeader *list, long file_offset ); +ObjectList *findScanByNo ( ListHeader *list, long scan_no, long order ); + +long mulstrtod ( char *str, double **arr, int *error ); +void freeAllData ( SpecFile *sf ); + +/* + * Globals + */ + + +/********************************************************************* + * Function: void sfSetCurrent( sf, list ) + * + * Description: Sets 'list' to current scan. + * Updates SpecFile structure. + * Parameters: + * Input : (1) SpecFile pointer + * (2) New scan + * + *********************************************************************/ +int +sfSetCurrent( SpecFile *sf, long index,int *error ) +{ + ObjectList *list, + *flist; + SpecScan *scan, + *fscan; + long nbytes; + long fileheadsize,start; + + /* + * If same scan nothing to do + */ + if (sfSameScan(sf,index)) return(0); + + /* + * It is a new scan. Free memory allocated for previous one. + */ + freeAllData(sf); + + /* + * Find scan + */ + list = findScanByIndex(&(sf->list),index); + + if (list == (ObjectList *)NULL) { + *error = SF_ERR_SCAN_NOT_FOUND; + return(-1); + } + + /* + * Read full scan into buffer + */ + scan = list->contents; + + if (sf->scanbuffer != ( char * ) NULL) free(sf->scanbuffer); + + sf->scanbuffer = ( char *) malloc(scan->size); + + if (sf->scanbuffer == (char *)NULL) { + *error = SF_ERR_MEMORY_ALLOC; + return(-1); + } + + lseek(sf->fd,scan->offset,SEEK_SET); + nbytes = read(sf->fd,sf->scanbuffer,scan->size); + if ( nbytes == -1) { + *error = SF_ERR_FILE_READ; + return(-1); + } + if ( sf->scanbuffer[0] != '#' || sf->scanbuffer[1] != 'S') { + *error = SF_ERR_FILE_READ; + return(-1); + } + sf->scanheadersize = scan->data_offset - scan->offset; + + /* + * if different file read fileheader also + */ + if (!sfSameFile(sf,list)) { + if (sf->filebuffer != ( char * ) NULL) free(sf->filebuffer); + + start = scan->file_header; + flist = findFirstInFile(&(sf->list),scan->file_header); + if (flist == (ObjectList *) NULL) { + fileheadsize = 0; + sf->filebuffersize = fileheadsize; + } + else + { + fscan = flist->contents; + fileheadsize = fscan->offset - start; + } + + if (fileheadsize > 0) { + sf->filebuffer = ( char *) malloc(fileheadsize); + if (sf->filebuffer == (char *)NULL) { + *error = SF_ERR_MEMORY_ALLOC; + return(-1); + } + lseek(sf->fd,start,SEEK_SET); + nbytes = read(sf->fd,sf->filebuffer,fileheadsize); + if ( nbytes == -1) { + *error = SF_ERR_FILE_READ; + return(-1); + } + sf->filebuffersize = fileheadsize; + } + } + sf->scansize = scan->size; + sf->current = list; + + return(1); +} + + +/********************************************************************* + * Function: int sfSameFile( sf, list ) + * + * Description: Checks if the current scan file header and + * the new scan file header are the same. + * Parameters: + * Input : (1) SpecFile pointer + * (2) New scan + * Returns: + * 1 - the same + * 0 - not the same + * + *********************************************************************/ +int +sfSameFile( SpecFile *sf, ObjectList *list ) +{ + if (sf->current) { + return ( ((SpecScan *)sf->current->contents)->file_header == + ((SpecScan *)list->contents)->file_header ); + } else return(0); +} + + +/********************************************************************* + * Function: int sfSameScan( sf, index ) + * + * Description: Checks if the current scan and + * the new scan are the same. + * Parameters: + * Input : (1) SpecFile pointer + * (2) New scan index + * Returns: + * 1 - the same + * 0 - not the same + * + *********************************************************************/ +int +sfSameScan( SpecFile *sf, long index ) +{ + if ( sf->current == (ObjectList *)NULL) return(0); + + return ( ((SpecScan *)sf->current->contents)->index == index ); +} + + +/********************************************************************* + * Function: freePtr( ptr ); + * + * Description: Frees memory pointed to by 'ptr'. + * + * Parameters: + * Input : (1) Pointer + * + *********************************************************************/ +void +freePtr( void *ptr ) +{ + free( ptr ); +} + + +/********************************************************************* + * Function: freeArrNZ( ptr, lines ); + * + * Description: Frees an array if 'lines' > zero. + * + * Parameters: + * Input : (1) Array pointer + * (2) No. of lines + * + *********************************************************************/ +void +freeArrNZ( void ***ptr, long lines ) +{ + if ( *ptr != (void **)NULL && lines > 0 ) { + for ( ; lines ; lines-- ) { + free( (*ptr)[lines-1] ); + } + free( *ptr ); + *ptr = ( void **)NULL ; + } +} + + +/********************************************************************* + * Function: freeArr( ptr, lines ); + * + * Description: Frees an array. + * 'ptr' will be always freed !!! + * + * Parameters: + * Input : (1) Array pointer + * (2) No. of lines + * + *********************************************************************/ +void +freeArr( void ***ptr, long lines ) +{ + if ( *ptr != (void **)NULL ) { + if ( lines > 0 ) { + for ( ; lines ; lines-- ) { + free( (*ptr)[lines-1] ); + } + } + free( *ptr ); + *ptr = ( void **)NULL ; + } +} + + +/********************************************************************* + * Function: int findIndex( scan, number ) + * + * Description: Compares if number == scan index . + * + * Parameters: + * Input : (1) SpecScan pointer + * (2) number + * Returns: + * 0 : not found + * 1 : found + * + *********************************************************************/ +int +findIndex( void *scan, void *number ) +{ + return( ((SpecScan *)scan)->index == *(long *)number ); +} + + +/********************************************************************* + * Function: int findFirst( scan, file_offset ) + * + * Description: Compares if scan offset > file_offset + * + * Parameters: + * Input : (1) SpecScan pointer + * (2) number + * Returns: + * 0 : not found + * 1 : found + * + *********************************************************************/ +int +findFirst( void *scan, void *file_offset ) +{ + return( ((SpecScan *)scan)->offset > *(long *)file_offset ); +} + + +/********************************************************************* + * Function: int findNoAndOr( scan, number ) + * ( Number + * Order ) + * + * Description: Compares if number1 = scan number and + * number2 = scan order + * Parameters: + * Input: (1) SpecScan pointer + * (2) number[1] + * Returns: + * 0 : not found + * 1 : found + * + *********************************************************************/ +int +findNoAndOr( void *scan, void *number ) +{ + + long *n = (long *)number; + + return( ( ((SpecScan *)scan)->scan_no == *n++ ) && ( ((SpecScan *)scan)->order == *n )); +} + + +/********************************************************************* + * Function: ObjectList *findScanByIndex( list, index ) + * + * Description: Looks for a scan . + * + * Parameters: + * Input: (1) List pointer + * (2) scan index + * Returns: + * ObjectList pointer if found , + * NULL if not. + * + *********************************************************************/ +ObjectList * +findScanByIndex( ListHeader *list, long index ) +{ + return findInList( list, findIndex, (void *)&index ); +} + + +/********************************************************************* + * Function: ObjectList findScanByNo( list, scan_no, order ) + * + * Description: Looks for a scan . + * + * Parameters: + * Input: (1) List pointer + * (2) scan number + * (3) scan order + * Returns: + * ObjectList pointer if found , + * NULL if not. + * + *********************************************************************/ +ObjectList * +findScanByNo( ListHeader *list, long scan_no, long order ) +{ + long value[2]; + + value[0] = scan_no; + value[1] = order; + + return( findInList( (void *)list, findNoAndOr, (void *)value) ); +} + + + +/********************************************************************* + * Function: ObjectList *findFirstInFile( list, file_offset ) + * + * Description: Looks for a scan . + * + * Parameters: + * Input: (1) List pointer + * (2) scan index + * Returns: + * ObjectList pointer if found , + * NULL if not. + * + *********************************************************************/ +ObjectList * +findFirstInFile( ListHeader *list, long file_offset ) +{ + return findInList( list, findFirst, (void *)&file_offset ); +} + + +/********************************************************************* + * Function: long mulstrtod( str, arr, error ) + * + * Description: Converts string to data array.( double array ) + * + * Parameters: + * Input : (1) String + * + * Output: + * (2) Data array + * (3) error number + * Returns: + * Number of values. + * ( -1 ) in case of errors. + * Possible errors: + * SF_ERR_MEMORY_ALLOC + * + * Remark: The memory allocated should be freed by the application + * + *********************************************************************/ +long +mulstrtod( char *str, double **arr, int *error ) +{ + int count,q,i=0; + double *ret; + char *str2; + static double tmpret[200]; + + *arr = (double *)NULL; + + str2 = str; + + while( (q = sscanf(str2, "%lf%n", &(tmpret[i]), &count)) > 0 ) { + i++; + str2 += count; + } + str2++; + + if ( !i ) { + return( i ); + } + + ret = (double *)malloc( sizeof(double) * i ); + + if ( ret == (double *)NULL ) { + *error = SF_ERR_MEMORY_ALLOC; + return( -1 ); + } + memcpy(ret, tmpret, i * sizeof(double) ); + + *arr = ret; + return( i ); +} + +void +freeAllData(SpecFile *sf) +{ + if (sf->motor_pos != (double *)NULL) { + free(sf->motor_pos); + sf->motor_pos = (double *)NULL; + sf->no_motor_pos = -1; + } + if (sf->motor_names != (char **)NULL) { + freeArrNZ((void ***)&(sf->motor_names),sf->no_motor_names); + sf->motor_names = (char **)NULL; + sf->no_motor_names = -1; + } + if (sf->labels != (char **)NULL) { + freeArrNZ((void ***)&(sf->labels),sf->no_labels); + sf->labels = (char **)NULL; + sf->no_labels = -1; + } + if (sf->data_info != (long *)NULL) { + freeArrNZ((void ***)&(sf->data),sf->data_info[ROW]); + free(sf->data_info); + sf->data = (double **)NULL; + sf->data_info = (long *)NULL; + } +} + +DllExport void +SfShow (SpecFile *sf) { + printf("<Showing Info> - specfile: %s\n",sf->sfname); + printf(" - no_scans: %ld\n",sf->no_scans); + printf(" - current: %ld\n",((SpecScan*)sf->current->contents)->scan_no); + printf(" Cursor:\n"); + printf(" - no_scans: %ld\n",sf->cursor.scanno); + printf(" - bytecnt: %ld\n",sf->cursor.bytecnt); +} + +DllExport void +SfShowScan (SpecFile *sf, long index) { + int error; + SpecScan *scan; + + printf("<Showing Info> - specfile: %s / idx %ld\n",sf->sfname,index); + + if (sfSetCurrent(sf,index,&error) == -1) { + printf("Cannot get scan index %ld\n",index); + } + + scan = (SpecScan *) sf->current->contents; + + printf(" - index: %ld\n",scan->index); + printf(" - scan_no: %ld\n",scan->scan_no); + printf(" - offset: %ld\n",scan->offset); + printf(" - data_offset: %ld\n",scan->data_offset); +} |