IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 30, 2004, 9:37:07 AM (22 years ago)
Author:
harman
Message:

Added more functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/astronomy/psMetadata.c

    r1324 r1351  
    11/** @file  psMetadata.c
    2  *
    3  *
    4  *  @brief Contains metadata struuctures, enumerations and functions prototypes
    5  *
    6  *  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
    7  *  prototypes necessary creating psLib metadata APIs
    8  *
    9  *  @ingroup Metadata
    10  *
    11  *  @author Ross Harman, MHPCC
    12  *
    13  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    14  *  @date $Date: 2004-07-29 02:04:20 $
    15  *
    16  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    17  */
     2*
     3*
     4*  @brief Contains metadata struuctures, enumerations and functions prototypes
     5*
     6*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
     7*  prototypes necessary creating psLib metadata APIs
     8*
     9*  @ingroup Metadata
     10*
     11*  @author Ross Harman, MHPCC
     12*
     13*  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     14*  @date $Date: 2004-07-30 19:36:52 $
     15*
     16*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     17*/
    1818
    1919/******************************************************************************/
     
    2424#include<string.h>
    2525
     26#include "fitsio.h"
    2627#include "psType.h"
    2728#include "psMemory.h"
     
    3738/******************************************************************************/
    3839
    39 // None
     40// Maximum metadata length string
     41#define MAX_VAL_SIZE 1024
     42
     43// Maximum metadata error length
     44#define MAX_ERR_MESSAGE_LENGTH 1024
    4045
    4146/******************************************************************************/
     
    6065/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
    6166/*****************************************************************************/
    62 static void metadataItemFree(psMetadataItem *metadataItem)
     67static void metadataItemFree( psMetadataItem *metadataItem )
    6368{
    6469    psMetadataType type;
    65 
     70   
    6671    type = metadataItem->type;
    67 
    68     if (metadataItem == NULL) {
    69         return;
    70     }
    71 
    72     psFree(metadataItem->name);
    73     psFree(metadataItem->comment);
    74 
    75     if(type==PS_META_STR || type==PS_META_IMG || type==PS_META_JPEG || type==PS_META_PNG ||
    76             type==PS_META_ASTROM || type==PS_META_UNKNOWN) {
    77         psFree(metadataItem->data.V);
    78     }
    79 
    80     psFree(metadataItem->items);
    81 }
    82 
    83 static void metadataFree(psMetadata *metadata)
    84 {
    85     if (metadata == NULL) {
    86         return;
    87     }
    88 
    89     psFree(metadata->list);
    90     psFree(metadata->table);
     72   
     73    if ( metadataItem == NULL ) {
     74            return ;
     75        }
     76       
     77    psFree( metadataItem->name );
     78    psFree( metadataItem->comment );
     79   
     80    if ( type == PS_META_STR || type == PS_META_IMG || type == PS_META_JPEG || type == PS_META_PNG ||
     81            type == PS_META_ASTROM || type == PS_META_UNKNOWN ) {
     82            psFree( metadataItem->data.V );
     83        }
     84       
     85    psFree( metadataItem->items );
     86}
     87
     88static void metadataFree( psMetadata *metadata )
     89{
     90    if ( metadata == NULL ) {
     91            return ;
     92        }
     93       
     94    psFree( metadata->list );
     95    psFree( metadata->table );
    9196}
    9297
     
    95100/*****************************************************************************/
    96101
    97 psMetadataItem *psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...)
     102psMetadataItem *psMetadataItemAlloc( const char *name, psMetadataType type, const char *comment, ... )
    98103{
    99104    va_list argPtr;
    100105    psMetadataItem *metadataItem = NULL;
    101 
     106   
    102107    // Get the variable list parameters to pass to allocation function
    103     va_start(argPtr, comment);
    104 
     108    va_start( argPtr, comment );
     109   
    105110    // Call metadata item allocation
    106     metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
    107 
     111    metadataItem = psMetadataItemAllocV( name, type, comment, argPtr );
     112   
    108113    // Clean up stack after variable arguement has been used
    109     va_end(argPtr);
    110 
     114    va_end( argPtr );
     115   
    111116    return metadataItem;
    112117}
    113118
    114 psMetadataItem *psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment, va_list argPtr)
    115 {
    116     psMetadataItem *metadataItem = NULL;
    117 
    118     if(name == NULL) {
    119         psError(__func__, "Null value for string not allowed");
    120         return NULL;
    121     }
    122 
     119psMetadataItem *psMetadataItemAllocV( const char *name, psMetadataType type, const char *comment, va_list argPtr )
     120{
     121    psMetadataItem * metadataItem = NULL;
     122   
     123    if ( name == NULL ) {
     124            psError( __func__, "Null value for string not allowed" );
     125            return NULL;
     126        }
     127       
    123128    // Allocate metadata item
    124     metadataItem = (psMetadataItem *)psAlloc(sizeof(psMetadataItem));
    125     if(metadataItem == NULL) {
    126         psAbort(__func__,"Failed to allocate memory");
    127     }
    128 
     129    metadataItem = ( psMetadataItem * ) psAlloc( sizeof( psMetadataItem ) );
     130    if ( metadataItem == NULL ) {
     131            psAbort( __func__, "Failed to allocate memory" );
     132        }
     133       
    129134    // Set deallocator
    130     p_psMemSetDeallocator(metadataItem,(psFreeFcn)metadataItemFree);
    131 
     135    p_psMemSetDeallocator( metadataItem, ( psFreeFcn ) metadataItemFree );
     136   
    132137    // Allocate and set metadata item comment
    133     metadataItem->comment = (char *)psAlloc(sizeof(char)*MAX_STRING_LENGTH);
    134     if(comment == NULL) {
    135         // Per SDRS, null isn't allowed, must use "" instead
    136         strncpy(metadataItem->comment, "", MAX_STRING_LENGTH);
    137     } else {
    138         strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH);
    139     }
    140 
    141     // Set metadata item id
    142     *(int*)(&metadataItem->id) = ++metadataId;
    143 
     138    metadataItem->comment = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH );
     139    if ( comment == NULL ) {
     140            // Per SDRS, null isn't allowed, must use "" instead
     141            strncpy( metadataItem->comment, "", MAX_STRING_LENGTH );
     142        } else {
     143            strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH );
     144        }
     145       
     146    // Set metadata item unique id
     147    *( int* ) ( &metadataItem->id ) = ++metadataId;
     148   
    144149    // Set metadata item type
    145150    metadataItem->type = type;
    146 
     151   
    147152    // Set metadata item value
    148     switch(type) {
    149     case PS_META_S32:
    150         metadataItem->data.S32 = va_arg(argPtr, psS32);
    151         break;
    152     case PS_META_F32:
    153         metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
    154         break;
    155     case PS_META_F64:
    156         metadataItem->data.F64 = va_arg(argPtr, psF64);
    157         break;
    158     case PS_META_STR:
    159     case PS_META_IMG:
    160     case PS_META_JPEG:
    161     case PS_META_PNG:
    162     case PS_META_ASTROM:
    163     case PS_META_UNKNOWN:
    164         metadataItem->data.V = psMemIncrRefCounter(va_arg(argPtr, psPTR));
    165         break;
    166     default:
    167         psError(__func__, " Invalid psMetadataType: %d", type);
    168     }
    169 
     153    switch ( type ) {
     154            case PS_META_S32:
     155            metadataItem->data.S32 = va_arg( argPtr, psS32 );
     156            break;
     157            case PS_META_F32:
     158            metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 );
     159            break;
     160            case PS_META_F64:
     161            metadataItem->data.F64 = va_arg( argPtr, psF64 );
     162            break;
     163            case PS_META_STR:
     164            case PS_META_IMG:
     165            case PS_META_JPEG:
     166            case PS_META_PNG:
     167            case PS_META_ASTROM:
     168            case PS_META_UNKNOWN:
     169            metadataItem->data.V = psMemIncrRefCounter( va_arg( argPtr, psPTR ) );
     170            break;
     171            default:
     172            psError( __func__, " Invalid psMetadataType: %d", type );
     173        }
     174       
    170175    // Allocate and set metadata item name
    171     metadataItem->name = (char *)psAlloc(sizeof(char)*MAX_STRING_LENGTH);
    172     vsprintf(metadataItem->name, name, argPtr);
    173 
     176    metadataItem->name = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH );
     177    vsprintf( metadataItem->name, name, argPtr );
     178   
    174179    // Allocate metadata items with same name.
    175     metadataItem->items = psListAlloc(NULL);
    176 
     180    metadataItem->items = psListAlloc( NULL );
     181   
    177182    return metadataItem;
    178183}
    179184
    180 psMetadata *psMetadataAlloc(void)
    181 {
    182     psList *list = NULL;
     185psMetadata *psMetadataAlloc( void )
     186{
     187    psList * list = NULL;
    183188    psHash *table = NULL;
    184189    psMetadata *metadata = NULL;
    185 
     190   
    186191    // Allocate metadata
    187     metadata = (psMetadata *)psAlloc(sizeof(psMetadata));
    188     if(metadata == NULL) {
    189         psAbort(__func__,"Failed to allocate metadata");
    190     }
    191 
     192    metadata = ( psMetadata * ) psAlloc( sizeof( psMetadata ) );
     193    if ( metadata == NULL ) {
     194            psAbort( __func__, "Failed to allocate metadata" );
     195        }
     196       
    192197    // Set deallocator
    193     p_psMemSetDeallocator(metadata,(psFreeFcn)metadataFree);
    194 
     198    p_psMemSetDeallocator( metadata, ( psFreeFcn ) metadataFree );
     199   
    195200    // Allocate internal containers
    196     list = (psList *)psAlloc(sizeof(psList));
    197     if(list == NULL) {
    198         psAbort(__func__,"Failed to allocate list");
    199     }
    200 
    201     table = (psHash *)psAlloc(sizeof(psHash));
    202     if(table == NULL) {
    203         psAbort(__func__,"Failed to allocate table");
    204     }
    205 
     201    list = ( psList * ) psAlloc( sizeof( psList ) );
     202    if ( list == NULL ) {
     203            psAbort( __func__, "Failed to allocate list" );
     204        }
     205       
     206    table = ( psHash * ) psAlloc( sizeof( psHash ) );
     207    if ( table == NULL ) {
     208            psAbort( __func__, "Failed to allocate table" );
     209        }
     210       
    206211    return metadata;
    207212}
    208213
    209 bool psMetadataAddItem(psMetadata *restrict md, int where, psMetadataItem *restrict metadataItem)
    210 {
    211     char *key = NULL;
     214bool psMetadataAddItem( psMetadata *restrict md, int where, psMetadataItem *restrict metadataItem )
     215{
     216    char * key = NULL;
    212217    psHash *mdTable = NULL;
    213218    psList *mdList = NULL;
    214219    psMetadataItem *value = NULL;
    215220    psMetadataType type = PS_META_ITEM_SET;
    216 
    217     if(md == NULL) {
    218         psError(__func__, "Null metadata collection not allowed");
    219         return false;
    220     }
    221 
    222     if(metadataItem == NULL) {
    223         psError(__func__, "Null metadata item not allowed");
    224         return false;
    225     }
    226 
     221   
     222    if ( md == NULL ) {
     223            psError( __func__, "Null metadata collection not allowed" );
     224            return false;
     225        }
     226       
     227    if ( metadataItem == NULL ) {
     228            psError( __func__, "Null metadata item not allowed" );
     229            return false;
     230        }
     231       
    227232    type = metadataItem->type;
    228 
     233   
    229234    mdTable = md->table;
    230     if(mdTable == NULL) {
    231         psError(__func__, "Null metadata table not allowed");
    232         return false;
    233     }
    234 
    235     mdList = md->list;
    236     if(mdList == NULL) {
    237         psError(__func__, "Null metadata list not allowed");
    238         return false;
    239     }
    240 
     235    if ( mdTable == NULL ) {
     236            psError( __func__, "Null metadata table not allowed" );
     237            return false;
     238        }
     239       
     240    mdList = md->list;
     241    if ( mdList == NULL ) {
     242            psError( __func__, "Null metadata list not allowed" );
     243            return false;
     244        }
     245       
    241246    key = metadataItem->name;
    242     if(key == NULL) {
    243         psError(__func__, "Null key item not allowed");
    244         return false;
    245     }
    246 
     247    if ( key == NULL ) {
     248            psError( __func__, "Null key item not allowed" );
     249            return false;
     250        }
     251       
    247252    // Check if key is already in table
    248     value = (psMetadataItem*)psHashLookup(mdTable, key);
    249     if(value!=NULL && type!=PS_META_ITEM_SET) {
    250 
    251         // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so
    252         // add the new metadata item to hash as a child of the existing metadata item folder node.
    253         if(!psListAdd(value->items, metadataItem, where)) {
    254             psError(__func__, "Couldn't add metadata item to items list. Name: %s",
    255                     metadataItem->name);
    256             return false;
    257         }
    258     } else if(value != NULL) {
    259 
    260         // The key was found and the new metadata item is a folder node. Don't add new metadata item, since
    261         // it will wipe out existing node.
    262         psError(__func__, "Metadata already exists in metadata collection. Item not added. Name: %s",
    263                 metadataItem->name);
    264         return false;
    265     } else {
    266 
    267         // Duplicate key not found. Add new metadata item to metadata collection's hash
    268         if(!psHashAdd(mdTable, key, metadataItem)) {
    269             psError(__func__, "Couldn't add metadata item to metadata collection table. Name: %s",
    270                     metadataItem->name);
    271             return false;
    272         }
    273     }
    274 
     253    value = ( psMetadataItem* ) psHashLookup( mdTable, key );
     254    if ( value != NULL && type != PS_META_ITEM_SET ) {
     255   
     256            // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so
     257            // add the new metadata item to hash as a child of the existing metadata item folder node.
     258            if ( !psListAdd( value->items, metadataItem, where ) ) {
     259                    psError( __func__, "Couldn't add metadata item to items list. Name: %s",
     260                             metadataItem->name );
     261                    return false;
     262                }
     263        } else if ( value != NULL ) {
     264       
     265            // The key was found and the new metadata item is a folder node. Don't add new metadata item, since
     266            // it will wipe out existing node.
     267            psError( __func__, "Metadata already exists in metadata collection. Item not added. Name: %s",
     268                     metadataItem->name );
     269            return false;
     270        } else {
     271       
     272            // Duplicate key not found. Add new metadata item to metadata collection's hash
     273            if ( !psHashAdd( mdTable, key, metadataItem ) ) {
     274                    psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s",
     275                             metadataItem->name );
     276                    return false;
     277                }
     278        }
     279       
    275280    // Add all items to metadata collection's list, even if they have the same metadata item names
    276     if(!psListAdd(md->list, metadataItem, where)) {
    277         psError(__func__, "Couldn't add metadata item to metadata collection list. Name: %s",
    278                 metadataItem->name);
    279         return false;
    280     }
    281 
     281    if ( !psListAdd( md->list, metadataItem, where ) ) {
     282            psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
     283                     metadataItem->name );
     284            return false;
     285        }
     286       
    282287    return true;
    283288}
    284289
    285 bool psMetadataAdd(psMetadata *restrict md, int where, const char *name, psMetadataType type,
    286                    const char *comment, ...)
     290bool psMetadataAdd( psMetadata *restrict md, int where, const char *name, psMetadataType type,
     291                    const char *comment, ... )
    287292{
    288293    va_list argPtr;
    289294    psMetadataItem *metadataItem = NULL;
    290 
    291     va_start(argPtr, comment);
    292     metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
    293     va_end(argPtr);
    294 
    295     return psMetadataAddItem(md, where, metadataItem);
    296 }
    297 
    298 /** Remove an item from metadata collection.
    299  *
    300  * Items may be removed from metadata by specifing a key or location. If the key is null, the where argument
    301  * is used instead. If name is not null, where is set to PS_LIST_UNKNOWN. If the item is found, it is removed
    302  * from the metadata and true is returned.  If the key is not unique, then all items corresponding to it are
    303  * removed.
    304  *
    305  * @return bool: True for success, false for failure.
    306  */
    307 bool psMetadataRemove(psMetadata *restrict md, int where, const char *restrict key)
    308 {
    309     /*    int i = 0;
    310         int numChildren = 0;
    311         psList mdList = NULL;
    312         psHash mdHash = NULL;
    313         psMetadataItem *entry = NULL;
    314         psMetadataItem *entryChild = NULL;
    315      
    316         mdList = md->list
    317         if(mdList == NULL) {
    318             psError(__func__, "Null metadata list not allowed");
    319             return false;
    320         }
    321      
    322         mdTable = md->table;
    323         if(mdTable == NULL) {
    324             psError(__func__, "Null metadata table not allowed");
    325             return false;
    326         }
    327      
    328         // Select removal by key or index
    329         if(key != NULL){
    330      
     295   
     296    va_start( argPtr, comment );
     297    metadataItem = psMetadataItemAllocV( name, type, comment, argPtr );
     298    va_end( argPtr );
     299   
     300    if ( !psMetadataAddItem( md, where, metadataItem ) ) {
     301            psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
     302                     metadataItem->name );
     303            psFree( metadataItem );
     304            return false;
     305        }
     306       
     307    return true;
     308}
     309
     310bool psMetadataRemove( psMetadata *restrict md, int where, const char *restrict key )
     311{
     312    int numChildren = 0;
     313    psList *mdList = NULL;
     314    psHash *mdTable = NULL;
     315    psMetadataItem *entry = NULL;
     316    psMetadataItem *entryChild = NULL;
     317   
     318    mdList = md->list;
     319    if ( mdList == NULL ) {
     320            psError( __func__, "Null metadata list not allowed" );
     321            return false;
     322        }
     323       
     324    mdTable = md->table;
     325    if ( mdTable == NULL ) {
     326            psError( __func__, "Null metadata table not allowed" );
     327            return false;
     328        }
     329       
     330    // Select removal by key or index
     331    if ( key != NULL ) {
     332   
    331333            // Remove by key name
    332             entry = (psMetadataItem*)psHashLookup(mdTable, key);
    333             if(entry == NULL) {
    334                 psError(__func__, "Couldn't find metadata item remove. Name: %s", key);
    335                 return false;
    336             }
    337      
     334            entry = ( psMetadataItem* ) psHashLookup( mdTable, key );
     335            if ( entry == NULL ) {
     336                    psError( __func__, "Couldn't find metadata item remove. Name: %s", key );
     337                    return false;
     338                }
     339                
    338340            numChildren = entry->items->size;
    339             if(entry->type==PS_META_ITEM_SET && numChildren>0){
    340      
    341                 // Table entry has children. Entry and children must be removed from metadata collection's list
    342                 psListSetIterator(list, PS_LIST_HEAD);
    343                 entryChild = psListGetCurrent(list);
    344                 while (entryChild != NULL) {
    345                     if(!psListRemove(mdList, entry, PS_LIST_UNKNOWN)) {
    346                         psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
    347                         return false;
    348                     }
    349                 }
    350                 entryChild = psListGetNext(list);
    351             } else {
    352      
    353                 // Table entry does not have children. Entry only must be removed from metadata collection's list
    354                 if(!psListRemove(mdList, entry, PS_LIST_UNKNOWN)) {
    355                     psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
     341            if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) {
     342            
     343                    // Table entry has children. Entry and children must be removed from metadata collection's list
     344                    psListSetIterator( mdList, PS_LIST_HEAD );
     345                    entryChild = psListGetCurrent( mdList );
     346                    while ( entryChild != NULL ) {
     347                            if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) {
     348                                    psError( __func__, "Couldn't remove metadata item from list. Name: %s", key );
     349                                    return false;
     350                                }
     351                            entryChild = psListGetNext( entry->items );
     352                        }
     353                }
     354                
     355            // Remove entry from metadata collection's list
     356            if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) {
     357                    psError( __func__, "Couldn't remove metadata item from list. Name: %s", key );
    356358                    return false;
    357359                }
    358      
    359             }
    360      
    361             // Remove entry from table once duplictes have been removed from the metadata collection's list
    362             if(!psHashRemove(mdHash, key)) {
    363                 psError(__func__, "Couldn't remove metadata item from table. Name: %s", key);
    364                 return false;
    365             }
     360               
     361            // Remove entry from metadata collection's table
     362            if ( !psHashRemove( mdTable, key ) ) {
     363                    psError( __func__, "Couldn't remove metadata item from table. Name: %s", key );
     364                    return false;
     365                }
    366366        } else {
     367       
    367368            // Remove by index
    368      
    369         }*/
    370 
     369            entry = psListGet( mdList, where );
     370            if ( entry == NULL ) {
     371                    psError( __func__, "Couldn't find metadata item from list. Index: %d", where );
     372                    return false;
     373                }
     374               
     375            key = entry->name;
     376            if ( key == NULL ) {
     377                    psError( __func__, "Null key name not allowed. Index: %d", where );
     378                    return false;
     379                }
     380               
     381            // Use recursive remove, now that key is known
     382            psMetadataRemove( md, PS_LIST_UNKNOWN, key );
     383        }
     384       
    371385    return true;
    372386}
    373387
     388psMetadataItem *psMetadataLookup( psMetadata *restrict md, const char *restrict key )
     389{
     390    psHash * mdTable = NULL;
     391    psMetadataItem *entry = NULL;
     392   
     393    mdTable = md->table;
     394    if ( mdTable == NULL ) {
     395            psError( __func__, "Null metadata table not allowed" );
     396            return NULL;
     397        }
     398       
     399    if ( key == NULL ) {
     400            psError( __func__, "Null key name not allowed" );
     401            return NULL;
     402        }
     403       
     404    entry = ( psMetadataItem* ) psHashLookup( mdTable, key );
     405    if ( entry == NULL ) {
     406            psError( __func__, "Could not find metadata item with given key. Key: %s", key );
     407            return NULL;
     408        }
     409       
     410    return entry;
     411}
     412
     413psMetadataItem *psMetadataGet( psMetadata *restrict md, int where )
     414{
     415    psList * mdList = NULL;
     416    psMetadataItem *entry = NULL;
     417   
     418    mdList = md->list;
     419    if ( mdList == NULL ) {
     420            psError( __func__, "Null metadata list not allowed" );
     421            return NULL;
     422        }
     423       
     424    entry = ( psMetadataItem* ) psListGet( mdList, where );
     425    if ( entry == NULL ) {
     426            psError( __func__, "Couldn't find metadata item with given index. Index: %d", where );
     427            return NULL;
     428        }
     429       
     430    return entry;
     431}
     432
     433bool psMetadataSetIterator( psMetadata *restrict md, int where )
     434{
     435    psList * mdList = NULL;
     436   
     437    mdList = md->list;
     438    if ( mdList == NULL ) {
     439            psError( __func__, "Null metadata list not allowed" );
     440            return false;
     441        }
     442       
     443    psListSetIterator( mdList, where );
     444   
     445    return true;
     446}
     447
     448psMetadataItem *psMetadataGetNext( psMetadata *restrict md, const char *restrict match, int which )
     449{
     450    psList * mdList = NULL;
     451    psMetadataItem *entry = NULL;
     452   
     453    mdList = md->list;
     454    if ( mdList == NULL ) {
     455            psError( __func__, "Null metadata list not allowed" );
     456            return NULL;
     457        }
     458       
     459    mdList = md->list;
     460    if ( mdList == NULL ) {
     461            psError( __func__, "Null metadata list not allowed" );
     462            return NULL;
     463        }
     464       
     465    psListSetIterator( mdList, which );
     466    entry = psListGetCurrent( mdList );
     467    while ( entry != NULL ) {
     468            if ( !strncmp( match, entry->name, strlen( match ) ) ) {
     469           
     470                    // Match found
     471                    return entry;
     472                }
     473            entry = psListGetNext( mdList );
     474        }
     475       
     476    // Match not found
     477    if ( entry == NULL ) {
     478            psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );
     479        }
     480       
     481    return entry;
     482}
     483
     484psMetadataItem *psMetadataGetPrevious( psMetadata *restrict md, const char *restrict match, int which )
     485{
     486    psList * mdList = NULL;
     487    psMetadataItem *entry = NULL;
     488   
     489    mdList = md->list;
     490    if ( mdList == NULL ) {
     491            psError( __func__, "Null metadata list not allowed" );
     492            return NULL;
     493        }
     494       
     495    mdList = md->list;
     496    if ( mdList == NULL ) {
     497            psError( __func__, "Null metadata list not allowed" );
     498            return NULL;
     499        }
     500       
     501    psListSetIterator( mdList, which );
     502    entry = psListGetCurrent( mdList );
     503    while ( entry != NULL ) {
     504            if ( !strncmp( match, entry->name, strlen( match ) ) ) {
     505           
     506                    // Match found
     507                    return entry;
     508                }
     509            entry = psListGetPrevious( mdList );
     510        }
     511       
     512    // Match not found
     513    if ( entry == NULL ) {
     514            psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );
     515        }
     516       
     517    return entry;
     518}
     519
     520void psMetadataItemPrint( FILE *fd, const char *format, const psMetadataItem *restrict metadataItem )
     521{
     522    psMetadataType type;
     523   
     524    if ( fd == NULL ) {
     525            psError( __func__, "Null file descriptor not allowed" );
     526            return ;
     527        }
     528       
     529    if ( format == NULL ) {
     530            psError( __func__, "Null format not allowed" );
     531            return ;
     532        }
     533       
     534    if ( metadataItem == NULL ) {
     535            psError( __func__, "Null metadata not allowed" );
     536            return ;
     537        }
     538       
     539    type = metadataItem->type;
     540   
     541    switch ( type ) {
     542            case PS_META_S32:
     543            fprintf( fd, format, metadataItem->data.S32 );
     544            break;
     545            case PS_META_F32:
     546            fprintf( fd, format, metadataItem->data.F32 );
     547            break;
     548            case PS_META_F64:
     549            fprintf( fd, format, metadataItem->data.F64 );
     550            break;
     551            case PS_META_STR:
     552            fprintf( fd, format, metadataItem->data.V );
     553            break;
     554            case PS_META_ITEM_SET:
     555            case PS_META_IMG:
     556            case PS_META_JPEG:
     557            case PS_META_PNG:
     558            case PS_META_ASTROM:
     559            case PS_META_UNKNOWN:
     560            default:
     561            psError( __func__, " Invalid psMetadataType to print: %d", type );
     562        }
     563}
     564
     565psMetadata *psMetadataReadHeader( psMetadata *output, const char *extname, int extnum, const char *filename )
     566{
     567    return NULL;
     568   
     569}
     570
     571psMetadata *psMetadataFReadHeader( psMetadata *output, const char *extname, int extnum, fitsfile *fd )
     572{
     573    bool success;
     574    char keyType;
     575    char keyName[ MAX_VAL_SIZE ];
     576    char keyValue[ MAX_VAL_SIZE ];
     577    char keyComment[ MAX_VAL_SIZE ];
     578    char fitsErr[ MAX_ERR_MESSAGE_LENGTH ];
     579    char* tempExtname = NULL;
     580    int i;
     581    int hduType = 0;
     582    int status = 0;
     583    int numKeys = 0;
     584    psMetadataType metadataItemType;
     585   
     586    if ( fd == NULL ) {
     587            psError( __func__, "Null FITS file descriptor not allowed" );
     588            return NULL;
     589        }
     590       
     591    if ( extname == NULL && extnum == 0 ) {
     592            psError( __func__, "Null extname AND extnum = 0 not allowed" );
     593            return NULL;
     594        } else if ( extname && extnum ) {
     595            psError( __func__, "Both extname AND extnum arguments should not have valid values." );
     596            return NULL;
     597        }
     598       
     599    // Allocate metadata if user didn't
     600    if ( output == NULL ) {
     601            output = psMetadataAlloc();
     602            return NULL;
     603        }
     604       
     605    // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one.
     606    if ( extname == NULL ) {
     607            if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) {
     608                    fits_get_errstatus( status, fitsErr );
     609                    psError( __func__, "FITS error while locating header: %s", fitsErr );
     610                    status = 0;
     611                    fits_close_file( fd, &status );
     612                    return NULL;
     613                }
     614        } else if ( extnum > 0 ) {
     615            tempExtname = ( char* ) psAlloc( strlen( extname ) + 1 ); // fits_movnam_hdu doesn't like const part of extname
     616            strncpy( tempExtname, extname, MAX_VAL_SIZE );
     617            if ( fits_movnam_hdu( fd, ANY_HDU, tempExtname, 0, &status ) != 0 ) {
     618                    fits_get_errstatus( status, fitsErr );
     619                    psError( __func__, "FITS error while locating header: %s", fitsErr );
     620                    status = 0;
     621                    fits_close_file( fd, &status );
     622                    psFree( tempExtname );
     623                    return NULL;
     624                }
     625            psFree( tempExtname );
     626        }
     627       
     628    // Get number of key names
     629    if ( fits_get_hdrpos( fd, &numKeys, NULL, &status ) != 0 ) {
     630            fits_get_errstatus( status, fitsErr );
     631            psError( __func__, "FITS error while reading keys: %s", fitsErr );
     632            status = 0;
     633            fits_close_file( fd, &status );
     634            return NULL;
     635        }
     636       
     637    // Get each key name. Keywords start at one.
     638    for ( i = 1; i <= numKeys; i++ ) {
     639            if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) {
     640                    fits_get_errstatus( status, fitsErr );
     641                    psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr );
     642                    status = 0;
     643                    fits_close_file( fd, &status );
     644                    return NULL;
     645                }
     646               
     647            if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) {
     648                    fits_get_errstatus( status, fitsErr );
     649                    psError( __func__, "FITS error while determining key type: %s", fitsErr );
     650                    status = 0;
     651                    fits_close_file( fd, &status );
     652                    return NULL;
     653                }
     654               
     655            switch ( keyType ) {
     656                    case 'I':
     657                    metadataItemType = PS_META_S32;
     658                    success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) );
     659                    break;
     660                    case 'F':
     661                    metadataItemType = PS_META_F64;
     662                    success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) );
     663                    break;
     664                    case 'C':
     665                    metadataItemType = PS_META_STR;
     666                    success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue );
     667                    break;
     668                    case 'L':
     669                    case 'X':
     670                    default:
     671                    psError( __func__, "Invalid psMetadataType: %c", keyType );
     672                    return NULL;
     673                }
     674               
     675            if ( !success ) {
     676                    psError( __func__, "Failed to add metadata item. Name: %s", keyName );
     677                }
     678        }
     679       
     680    return output;
     681}
Note: See TracChangeset for help on using the changeset viewer.