IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 7, 2005, 10:58:51 AM (21 years ago)
Author:
desonia
Message:

modified psMetadata to use a special psMetadataType to signify duplicate
entries and added a flag to signify that duplicate entries are OK.

Location:
trunk/psLib/src/collections
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/collections/psList.h

    r3264 r3381  
    1010 *  @ingroup LinkedList
    1111 *
    12  *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2005-02-17 19:26:23 $
     12 *  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2005-03-07 20:58:50 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    174174/** Position the specified iterator to the next item in list.
    175175 *
    176  *  @return psPtr       the data item at the new iterator position or NULL if the
    177  *                      iterator goes past the end of the list.
     176 *  @return psPtr       the data item at the original iterator position or NULL if the
     177 *                      iterator went past the end of the list.
    178178 */
    179179psPtr psListGetAndIncrement(
     
    183183/** Position the specified iterator to the previous item in list.
    184184 *
    185  *  @return psPtr       the data item at the new iterator position or NULL if the
    186  *                      iterator goes past the beginning of the list.
     185 *  @return psPtr       the data item at the original iterator position or NULL if the
     186 *                      iterator went past the beginning of the list.
    187187 */
    188188psPtr psListGetAndDecrement(
  • trunk/psLib/src/collections/psMetadata.c

    r3341 r3381  
    1212*  @author Ross Harman, MHPCC
    1313*
    14 *  @version $Revision: 1.53 $ $Name: not supported by cvs2svn $
    15 *  @date $Date: 2005-02-28 23:34:10 $
     14*  @version $Revision: 1.54 $ $Name: not supported by cvs2svn $
     15*  @date $Date: 2005-03-07 20:58:50 $
    1616*
    1717*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    8585}
    8686
     87static void metadataIteratorFree(psMetadataIterator* iter)
     88{
     89    if (iter == NULL) {
     90        return;
     91    }
     92    psFree(iter->iter);
     93    regfree(iter->preg);
     94}
     95
    8796static void metadataFree(psMetadata* metadata)
    8897{
     
    158167
    159168    // Set metadata item type
    160     metadataItem->type = type;
     169    metadataItem->type = type & PS_METADATA_TYPE_MASK;
    161170
    162171    // Allocate and set metadata item name
     
    165174
    166175    // Set metadata item value
    167     switch(type) {
     176    switch(metadataItem->type) {
    168177    case PS_META_BOOL:
    169178        metadataItem->data.B = (psBool)va_arg(argPtr, psS32);
     
    190199    case PS_META_ASTROM:
    191200    case PS_META_UNKNOWN:
     201    case PS_META_MULTI:
    192202        // Copy of input data not performed due to variability of data types
    193203        metadataItem->data.V = psMemIncrRefCounter(va_arg(argPtr, psPtr));
     
    223233}
    224234
    225 psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location)
     235psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location, psS32 flags)
    226236{
    227237    char * key = NULL;
     
    229239    psList *mdList = NULL;
    230240    psMetadataItem *existingEntry = NULL;
    231     psMetadataItem *newFolderEntry = NULL;
    232     psMetadataType newType;
    233241
    234242    PS_PTR_CHECK_NULL(md,NULL);
     
    238246    PS_PTR_CHECK_NULL(metadataItem->name,NULL);
    239247
    240     newType = metadataItem->type;
    241248    mdTable = md->table;
    242249    mdList = md->list;
     
    245252    // See if key is already in table
    246253    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
     254
     255    // how the item is added to the hash depends on flags & prior existence
    247256    if(existingEntry != NULL) {
    248 
    249         if(existingEntry->type == PS_META_LIST) {
    250 
    251             if(existingEntry->data.list == NULL) {
    252                 existingEntry->data.list = psListAlloc(NULL);
     257        if ((flags & PS_META_DUPLICATE_OK) != 0) {
     258            // duplicate entries allowed - add another entry.
     259            if (existingEntry->type != PS_META_MULTI) {
     260                // first duplicate, transfer the hash's old entry into a
     261                // list of entries with the type PS_META_MULTI.
     262
     263                // add entry to a list and dereference the local pointer
     264                psList* newList = psListAlloc(existingEntry);
     265
     266                existingEntry = psMetadataItemAlloc(key,
     267                                                    PS_META_MULTI,
     268                                                    "",
     269                                                    newList);
     270                psHashRemove(mdTable,key); // take out the old entry
     271                psHashAdd(mdTable, key, existingEntry); // put in the new entry
     272
     273                // free local references of newly allocated items.
     274                psFree(newList);
     275                psFree(existingEntry);
     276
    253277            }
    254278
    255             // Add leaf node to existing folder node
    256             if(!psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem)) {
    257                 psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED, metadataItem->name);
     279            // add to the hash's list of duplicate entries
     280            if (! psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem) ) {
     281                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
    258282                return false;
    259283            }
    260         } else if(existingEntry->type != PS_META_LIST && newType!= PS_META_LIST) {
    261 
    262             // Leaf node replaces another leaf. Make new folder node and add leaves.
    263             newFolderEntry = psMetadataItemAlloc(key, PS_META_LIST, NULL, NULL);
    264             newFolderEntry->data.list = psListAlloc(NULL);
    265 
    266             if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, existingEntry)) {
    267                 psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
    268                 psFree(newFolderEntry);
    269                 return false;
    270             }
    271 
    272             if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, metadataItem)) {
    273                 psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
    274                 psFree(newFolderEntry);
    275                 return false;
    276             }
    277 
    278             if(!psHashRemove(mdTable, key)) {
    279                 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
    280                 psFree(newFolderEntry);
    281                 return false;
    282             }
    283 
    284             if(!psHashAdd(mdTable, key, newFolderEntry)) {
    285                 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
    286                 psFree(newFolderEntry);
    287                 return false;
    288             }
    289 
    290             // Remove local reference to new folder node
    291             psMemDecrRefCounter(newFolderEntry);
    292         } else {
    293 
    294             // Folder node replaces leaf or folder node - Put old node into new folder and remove from table
    295             if(metadataItem->data.list == NULL) {
    296                 metadataItem->data.list = psListAlloc(NULL);
    297             }
    298 
    299             if(!psListAdd(metadataItem->data.list, PS_LIST_TAIL, existingEntry)) {
    300                 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
    301                 return false;
    302             }
    303 
    304             if(!psHashRemove(mdTable, key)) {
    305                 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
    306                 return false;
    307             }
    308 
     284            // (added to list below)
     285
     286        } else if ((flags & PS_META_REPLACE) != 0) {
     287            // replace entry instead of creating a duplicate entry.
     288
     289            // remove the existing entry from metadata
     290            psListRemoveData(mdList, existingEntry);
     291            psHashRemove(mdTable, key);
     292
     293            // treat as if new (added to list below)
    309294            if(!psHashAdd(mdTable, key, metadataItem)) {
    310295                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
    311296                return false;
    312297            }
     298        } else {
     299            // default is to error on duplicate entry.
     300            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     301                    PS_ERRORTEXT_psMetadata_DUPLICATE_NOT_ALLOWED);
     302            return false;
    313303        }
    314304    } else {
     305        // OK, this is a new item.
    315306
    316307        // Node doesn't exist - Add new metadata item to metadata collection's hash
     
    321312    }
    322313
    323     // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
    324     // (PS_META_LIST metadata items) are not added, since the metadata list is flat.
    325     if(metadataItem->type != PS_META_LIST) {
    326         if(!psListAdd(mdList, location, metadataItem)) {
    327             psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
    328             return false;
    329         }
     314    if(!psListAdd(mdList, location, metadataItem)) {
     315        psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
     316        return false;
    330317    }
    331318
     
    333320}
    334321
    335 psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name,
    336                      psMetadataType type, const char *comment, ...)
     322psBool psMetadataAdd(psMetadata *md, psS32 location, const char *name,
     323                     psS32 type, const char *comment, ...)
    337324{
    338325    va_list argPtr;
     326
     327    va_start(argPtr, comment);
     328    psBool result = psMetadataAddV(md,location,name,type,comment,argPtr);
     329    va_end(argPtr);
     330
     331    return result;
     332}
     333
     334psBool psMetadataAddV(psMetadata *md, psS32 location, const char *name,
     335                      psS32 type, const char *comment, va_list list)
     336{
    339337    psMetadataItem* metadataItem = NULL;
    340338
    341     va_start(argPtr, comment);
    342     metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
    343     va_end(argPtr);
    344 
    345     if (!psMetadataAddItem(md, metadataItem, where)) {
     339    metadataItem = psMetadataItemAllocV(name, type & PS_METADATA_TYPE_MASK, comment, list);
     340
     341    if (!psMetadataAddItem(md, metadataItem, location, type & PS_METADATA_FLAGS_MASK)) {
    346342        psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_FAILED);
    347343        psFree(metadataItem);
     
    373369psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key)
    374370{
    375     psList* mdList = NULL;
    376     psHash* mdTable = NULL;
    377     psMetadataItem* entry = NULL;
    378 
    379 
    380371    PS_PTR_CHECK_NULL(md,NULL);
     372
     373    PS_PTR_CHECK_NULL(md->list,NULL);
     374    psList* mdList = md->list;
     375
    381376    PS_PTR_CHECK_NULL(md->table,NULL);
    382     PS_PTR_CHECK_NULL(md->list,NULL);
    383 
    384     mdList = md->list;
    385     mdTable = md->table;
     377    psHash* mdTable = md->table;
    386378
    387379    // Select removal by key or index
    388380    if (key != NULL) {
    389 
    390381        // Remove by key name
    391         entry = (psMetadataItem*)psHashLookup(mdTable, key);
     382        psMetadataItem* entry = psHashLookup(mdTable,key);
    392383        if (entry == NULL) {
    393             psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_FAILED, key);
     384            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
    394385            return false;
    395386        }
    396 
     387        if (entry->type == PS_META_MULTI) {
     388            psMetadataItem* listItem;
     389            psListIterator* iter = psListIteratorAlloc(
     390                                       entry->data.list,
     391                                       PS_LIST_HEAD,true);
     392            while ((listItem=psListGetAndIncrement(iter)) != NULL) {
     393                psListRemoveData(mdList, listItem);
     394            }
     395            psFree(iter);
     396            psHashRemove(mdTable,key);
     397
     398        } else {
     399            psListRemoveData(mdList, entry);
     400            psHashRemove(mdTable, key);
     401        }
    397402    } else {
    398 
    399403        // Remove by index
    400         entry = psListGet(mdList, where);
     404        psMetadataItem* entry = psListGet(mdList, where);
    401405        if (entry == NULL) {
    402406            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
    403407            return false;
    404408        }
    405 
    406409        key = entry->name;
    407         if(key == NULL) {
     410
     411        if (key == NULL) {
    408412            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED, where);
    409413            return false;
    410414        }
    411     }
    412 
    413     if (!psListRemoveData(mdList, entry)) {
    414         psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
    415         return false;
    416     }
    417 
    418     // Remove entry from metadata collection's table
    419     if (!psHashRemove(mdTable, key)) {
    420         psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
    421         return false;
     415
     416        psMetadataItem* tableItem = psHashLookup(mdTable, key);
     417        if (tableItem == NULL) {
     418            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
     419            return false;
     420        }
     421
     422        if (tableItem->type == PS_META_MULTI) {
     423            // multiple entries with same key, remove just the specified one
     424            psListRemoveData(tableItem->data.list, entry);
     425            if (psListGet(tableItem->data.list,PS_LIST_HEAD) == NULL) {
     426                // list is empty, so let's clear the whole entry now.
     427                if (!psHashRemove(mdTable, key)) {
     428                    psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
     429                    return false;
     430                }
     431            }
     432        } else {
     433            if (!psHashRemove(mdTable, key)) {
     434                psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
     435                return false;
     436            }
     437        }
     438        psListRemove(mdList, where);
    422439    }
    423440
     
    455472        }
    456473        return NULL;
     474    }
     475    if (metadataItem->type == PS_META_MULTI) {
     476        // if multiple keys found, use the first.
     477        metadataItem = (psMetadataItem*)((metadataItem->data.list)->head);
    457478    }
    458479
     
    486507        } \
    487508        return 0; \
     509    } \
     510    if (metadataItem->type == PS_META_MULTI) { \
     511        /* if multiple keys found, use the first. */ \
     512        metadataItem = (psMetadataItem*)((metadataItem->data.list)->head); \
    488513    } \
    489514    \
     
    535560    return entry;
    536561}
     562
     563psMetadataIterator* psMetadataIteratorAlloc(psMetadata* md,
     564        int location,
     565        const char* regex)
     566{
     567    PS_PTR_CHECK_NULL(md,NULL);
     568    PS_PTR_CHECK_NULL(md->list,NULL);
     569
     570    psMetadataIterator* newIter = psAlloc(sizeof(psMetadataIterator));
     571    newIter->preg = NULL;
     572    newIter->iter = NULL;
     573
     574    // Set deallocator
     575    p_psMemSetDeallocator(newIter, (psFreeFcn) metadataIteratorFree);
     576
     577    if (regex == NULL) {
     578        newIter->iter = psListIteratorAlloc(md->list, location, false);
     579        return newIter;
     580    } else {
     581        int regRtn = regcomp(newIter->preg,regex,0);
     582        if (regRtn != 0) {
     583            char errMsg[256];
     584            regerror(regRtn, newIter->preg, errMsg, 256);
     585            regfree(newIter->preg);
     586            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     587                    PS_ERRORTEXT_psMetadata_REGEX_INVALID,
     588                    errMsg);
     589            psFree(newIter);
     590            return NULL;
     591        }
     592    }
     593
     594    psMetadataIteratorSet(newIter, location); // XXX: do we error if no match is found?
     595
     596    return newIter;
     597}
     598
     599psBool psMetadataIteratorSet(psMetadataIterator* iterator,
     600                             int location)
     601{
     602    int match;
     603    psMetadataItem* cursor;
     604
     605    PS_PTR_CHECK_NULL(iterator,NULL);
     606
     607    psListIterator* iter = iterator->iter;
     608    PS_PTR_CHECK_NULL(iterator->iter,NULL);
     609
     610    regex_t* preg = iterator->preg;
     611
     612    // handle trivial case where no regex subsetting is required.
     613    if (preg == NULL) {
     614        return psListIteratorSet(iter,location);
     615    }
     616
     617    if (location < 0) {
     618        // match from the tail
     619        match = 0;
     620        psListIteratorSet(iter,PS_LIST_TAIL);
     621        while ( (cursor=(psMetadataItem*)iter->cursor) != NULL) {
     622            if (regexec(preg, cursor->name, 0, NULL, 0) == 0) {
     623                // this key is a match
     624                match--;
     625                if (match == location) {
     626                    break;
     627                }
     628            }
     629            (void)psListGetAndDecrement(iter);
     630        }
     631        return (match == location);
     632    }
     633
     634    // find the n-th match from the head
     635    match = -1;
     636    psListIteratorSet(iter,PS_LIST_HEAD);
     637    while ( (cursor=(psMetadataItem*)iter->cursor) != NULL) {
     638        if (regexec(preg, cursor->name, 0, NULL, 0) == 0) {
     639            // this key is a match
     640            match++;
     641            if (match == location) {
     642                break;
     643            }
     644        }
     645        (void)psListGetAndIncrement(iter);
     646    }
     647    return (match == location);
     648}
     649
     650psMetadataItem* psMetadataGetAndIncrement(psMetadataIterator* iterator)
     651{
     652    psMetadataItem* oldValue;
     653
     654    PS_PTR_CHECK_NULL(iterator,NULL);
     655
     656    psListIterator* iter = iterator->iter;
     657    PS_PTR_CHECK_NULL(iterator->iter,NULL);
     658
     659    regex_t* preg = iterator->preg;
     660
     661    // handle trivial case where no regex subsetting is required.
     662    if (preg == NULL) {
     663        return (psMetadataItem*)psListGetAndIncrement(iter);
     664    }
     665
     666    oldValue = (psMetadataItem*)iter->cursor;
     667
     668    while (psListGetAndIncrement(iter) != NULL) {
     669        if (iter->cursor != NULL &&
     670                regexec(preg, ((psMetadataItem*)iter->cursor)->name, 0, NULL, 0) == 0) {
     671            // this key is a match
     672            break;
     673        }
     674    }
     675    return oldValue;
     676}
     677
     678psMetadataItem* psMetadataGetAndDecrement(psMetadataIterator* iterator)
     679{
     680    psMetadataItem* oldValue;
     681
     682    PS_PTR_CHECK_NULL(iterator,NULL);
     683
     684    psListIterator* iter = iterator->iter;
     685    PS_PTR_CHECK_NULL(iterator->iter,NULL);
     686
     687    regex_t* preg = iterator->preg;
     688
     689    // handle trivial case where no regex subsetting is required.
     690    if (preg == NULL) {
     691        return (psMetadataItem*)psListGetAndDecrement(iter);
     692    }
     693
     694    oldValue = (psMetadataItem*)iter->cursor;
     695
     696    while (psListGetAndDecrement(iter) != NULL) {
     697        if (iter->cursor != NULL &&
     698                regexec(preg, ((psMetadataItem*)iter->cursor)->name, 0, NULL, 0) == 0) {
     699            // this key is a match
     700            break;
     701        }
     702    }
     703    return oldValue;
     704}
  • trunk/psLib/src/collections/psMetadata.h

    r3341 r3381  
    1111*  @author Ross Harman, MHPCC
    1212*
    13 *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
    14 *  @date $Date: 2005-02-28 23:34:10 $
     13*  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
     14*  @date $Date: 2005-03-07 20:58:50 $
    1515*
    1616*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2121#include <stdarg.h>
    2222#include <stdio.h>
     23#include <sys/types.h>
     24#include <regex.h>
    2325
    2426#include "psHash.h"
     
    3537 */
    3638typedef enum {
    37     PS_META_S32,                       ///< Primitive data.
    38     PS_META_F32,                       ///< Primitive data.
    39     PS_META_F64,                       ///< Primitive data.
    40     PS_META_BOOL,                       ///< Primitive data.
     39    PS_META_S32,                       ///< psS32 primitive data.
     40    PS_META_F32,                       ///< psF32 primitive data.
     41    PS_META_F64,                       ///< psF64 primitive data.
     42    PS_META_BOOL,                      ///< psBool primitive data.
    4143    PS_META_LIST,                      ///< List data (Stored as item.data.list).
    4244    PS_META_STR,                       ///< String data (Stored as item.data.V).
     
    4951    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored as item.data.V).
    5052    PS_META_UNKNOWN,                   ///< Other data (Stored as item.data.V).
     53    PS_META_MULTI,                     ///< Used internally, do not create an metadata item of this type.
    5154    PS_META_NTYPE                      ///< Number of types. Must be last.
    5255} psMetadataType;
     
    7275typedef enum {
    7376    PS_META_DEFAULT = 0,               ///< default behaviour (duplicate entry is an error)
    74     PS_META_REPLACE = 0x10000          ///< allow entry to be replaced
     77    PS_META_REPLACE = 0x1000000,       ///< allow entry to be replaced
     78    PS_META_DUPLICATE_OK = 0x2000000   ///< allow duplicate entries
    7579} psMetadataFlags;
     80
     81#define PS_METADATA_FLAGS_MASK 0xFF000000
     82#define PS_METADATA_TYPE_MASK 0x00FFFFFF
    7683
    7784/** Metadata data structure.
     
    8895}
    8996psMetadata;
     97
     98/** Metadata iterator
     99 *
     100 *  Iterator for metadata.
     101 */
     102typedef struct
     103{
     104    psListIterator* iter;              ///< iterator for the psMetadata's psList
     105    regex_t* preg;                     ///< the subsetting regular expression
     106}
     107psMetadataIterator;
     108
    90109
    91110/** Metadata item data structure.
     
    134153);
    135154
     155/** Create a metadata item with specified string data.
     156 *
     157 *  Returns a fill psMetadataItem ready for insertion into the psMetadata
     158 *  struct.
     159 *
     160 * @return psMetadataItem* : Pointer metadata item.
     161 */
    136162psMetadataItem* psMetadataItemAllocStr(
    137     const char* name,
    138     const char* comment,
    139     const char* value
    140 );
    141 
     163    const char* name,                  ///< Name of metadata item.
     164    const char* comment,               ///< Comment for metadata item.
     165    const char* value                  ///< the value of the metadata item.
     166);
     167
     168/** Create a metadata item with specified psF32 data.
     169 *
     170 *  Returns a fill psMetadataItem ready for insertion into the psMetadata
     171 *  struct.
     172 *
     173 * @return psMetadataItem* : Pointer metadata item.
     174 */
    142175psMetadataItem* psMetadataItemAllocF32(
    143     const char* name,
    144     const char* comment,
    145     psF32 value
    146 );
    147 
     176    const char* name,                  ///< Name of metadata item.
     177    const char* comment,               ///< Comment for metadata item.
     178    psF32 value                        ///< the value of the metadata item.
     179);
     180
     181/** Create a metadata item with specified psF64 data.
     182 *
     183 *  Returns a fill psMetadataItem ready for insertion into the psMetadata
     184 *  struct.
     185 *
     186 * @return psMetadataItem* : Pointer metadata item.
     187 */
    148188psMetadataItem* psMetadataItemAllocF64(
    149     const char* name,
    150     const char* comment,
    151     psF64 value
    152 );
    153 
     189    const char* name,                  ///< Name of metadata item.
     190    const char* comment,               ///< Comment for metadata item.
     191    psF64 value                        ///< the value of the metadata item.
     192);
     193
     194/** Create a metadata item with specified psS32 data.
     195 *
     196 *  Returns a fill psMetadataItem ready for insertion into the psMetadata
     197 *  struct.
     198 *
     199 * @return psMetadataItem* : Pointer metadata item.
     200 */
    154201psMetadataItem* psMetadataItemAllocS32(
    155     const char* name,
    156     const char* comment,
    157     psS32 value
    158 );
    159 
     202    const char* name,                  ///< Name of metadata item.
     203    const char* comment,               ///< Comment for metadata item.
     204    psS32 value                        ///< the value of the metadata item.
     205);
     206
     207/** Create a metadata item with specified psBool data.
     208 *
     209 *  Returns a fill psMetadataItem ready for insertion into the psMetadata
     210 *  struct.
     211 *
     212 * @return psMetadataItem* : Pointer metadata item.
     213 */
    160214psMetadataItem* psMetadataItemAllocBool(
    161     const char* name,
    162     const char* comment,
    163     psBool value
     215    const char* name,                  ///< Name of metadata item.
     216    const char* comment,               ///< Comment for metadata item.
     217    psBool value                       ///< the value of the metadata item.
    164218);
    165219
     
    207261    psMetadata*  md,                   ///< Metadata collection to insert metadat item.
    208262    psMetadataItem*  item,             ///< Metadata item to be added.
    209     psS32 location                     ///< Location to be added.
     263    psS32 location,                    ///< Location to be added.
     264    psS32 flags                        ///< Options flag mask, see psMetadataFlags enum
    210265);
    211266
     
    218273psBool psMetadataAdd(
    219274    psMetadata* md,                    ///< Metadata collection to insert metadat item.
    220     psS32 where,                       ///< Location to be added.
     275    psS32 location,                    ///< Location to be added.
    221276    const char *name,                  ///< Name of metadata item.
    222     psMetadataType type,               ///< Type of metadata item.
     277    int type,                          ///< Type of metadata item (psMetadataType) and options (psMetadataFlags)
    223278    const char *comment,               ///< Comment for metadata item.
    224279    ...                                ///< Arguments for name formatting and metadata item data.
    225280);
    226281
    227 psBool psMetadataAddS32(psMetadata* md, psS32 where, const char* name,
     282#ifndef SWIG
     283/** Create and add a metadata item to metadata collection.
     284 *
     285 * Creates a new metadata item add to the metadata collection.
     286 *
     287 * @return bool: True for success, false for failure.
     288 */
     289psBool psMetadataAddV(
     290    psMetadata* md,                    ///< Metadata collection to insert metadat item.
     291    psS32 location,                    ///< Location to be added.
     292    const char *name,                  ///< Name of metadata item.
     293    int type,                          ///< Type of metadata item (psMetadataType) and options (psMetadataFlags)
     294    const char *comment,               ///< Comment for metadata item.
     295    va_list list                       ///< Arguments for name formatting and metadata item data.
     296);
     297#endif
     298
     299psBool psMetadataAddS32(psMetadata* md, psS32 location, const char* name,
    228300                        const char* comment, psS32 value);
    229 psBool psMetadataAddF32(psMetadata* md, psS32 where, const char* name,
     301psBool psMetadataAddF32(psMetadata* md, psS32 location, const char* name,
    230302                        const char* comment, psF32 value);
    231 psBool psMetadataAddF64(psMetadata* md, psS32 where, const char* name,
     303psBool psMetadataAddF64(psMetadata* md, psS32 location, const char* name,
    232304                        const char* comment, psF64 value);
    233 psBool psMetadataAddList(psMetadata* md, psS32 where, const char* name,
     305psBool psMetadataAddList(psMetadata* md, psS32 location, const char* name,
    234306                         const char* comment, psList* value);
    235 psBool psMetadataAddStr(psMetadata* md, psS32 where, const char* name,
     307psBool psMetadataAddStr(psMetadata* md, psS32 location, const char* name,
    236308                        const char* comment, const char* value);
    237 psBool psMetadataAddVector(psMetadata* md, psS32 where, const char* name,
     309psBool psMetadataAddVector(psMetadata* md, psS32 location, const char* name,
    238310                           const char* comment, psVector* value);
    239 psBool psMetadataAddImage(psMetadata* md, psS32 where, const char* name,
     311psBool psMetadataAddImage(psMetadata* md, psS32 location, const char* name,
    240312                          const char* comment, psImage* value);
    241 psBool psMetadataAddHash(psMetadata* md, psS32 where, const char* name,
     313psBool psMetadataAddHash(psMetadata* md, psS32 location, const char* name,
    242314                         const char* comment, psHash* value);
    243 psBool psMetadataAddLookupTable(psMetadata* md, psS32 where, const char* name,
     315psBool psMetadataAddLookupTable(psMetadata* md, psS32 location, const char* name,
    244316                                const char* comment, psLookupTable* value);
    245 psBool psMetadataAddUnknown(psMetadata* md, psS32 where, const char* name,
     317psBool psMetadataAddUnknown(psMetadata* md, psS32 location, const char* name,
    246318                            const char* comment, psPtr value);
    247319
     
    340412 * @return void* : Value of metadata item.
    341413 */
    342 void* psMetadataLookupPtr(
     414psPtr psMetadataLookupPtr(
    343415    psBool *status,                    ///< Status of lookup.
    344416    psMetadata* md,                    ///< Metadata collection to lookup metadata item.
     
    354426 */
    355427psMetadataItem* psMetadataGet(
    356     psMetadata*  md,           ///< Metadata collection to insert metadat item.
    357     psS32 where                ///< Location to be retrieved.
     428    psMetadata*  md,                   ///< Metadata collection to insert metadat item.
     429    psS32 location                     ///< Location to be retrieved.
     430);
     431
     432/** Creates a psMetadataIterator to iterate over the specified psMetadata.
     433 *
     434 *  Supports the subsetting of the metadata via keyword using regular
     435 *  expression.  If no regular expression is specified, iteration
     436 *  over the entire psMetadata is performed.
     437 *
     438 *  @return psMetadataIterator*        a new psMetadataIterator, of NULL if error occurred
     439 */
     440psMetadataIterator* psMetadataIteratorAlloc(
     441    psMetadata* md,                    ///< the psMetadata to iterate with
     442    int location,                      ///< the initial starting point (after subsetting).
     443    const char* regex
     444    ///< A regular expression for subsetting the psMetadata.  If NULL, no
     445    ///< subsetting is performed.
     446);
     447
     448/** Set the iterator of the psMetadat to a given position.  If location is
     449 *  invalid the iterator position is not changed.
     450 *
     451 *  @return psBool        TRUE if iterator successfully set, otherwise FALSE.
     452*/
     453psBool psMetadataIteratorSet(
     454    psMetadataIterator* iterator,      ///< psMetadata iterator
     455    int location                       ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
     456);
     457
     458/** Position the specified iterator to the next matching item in psMetadata,
     459 *  given the regular expression of the iterator
     460 *
     461 *  @return psPtr       the psMetadataItem at the original iterator position
     462 *                      or NULL if the iterator went past the end of the list.
     463 */
     464psMetadataItem* psMetadataGetAndIncrement(
     465    psMetadataIterator* iterator           ///< iterator to move
     466);
     467
     468/** Position the specified iterator to the previous matching item in psMetadata,
     469 *  given the regular expression of the iterator
     470 *
     471 *  @return psPtr       the psMetadataItem at the original iterator position
     472 *                      or NULL if the iterator went past the beginning of the
     473 *                      list.
     474 */
     475psMetadataItem* psMetadataGetAndDecrement(
     476    psMetadataIterator* iterator           ///< iterator to move
    358477);
    359478
  • trunk/psLib/src/collections/psMetadataIO.c

    r3341 r3381  
    99*  @author Ross Harman, MHPCC
    1010*
    11 *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
    12 *  @date $Date: 2005-02-28 23:34:10 $
     11*  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2005-03-07 20:58:50 $
    1313*
    1414*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    410410        switch (keyType) {
    411411        case 'I':
    412             success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_META_S32,
     412            success = psMetadataAdd(output, PS_LIST_TAIL, keyName,
     413                                    PS_META_S32 | PS_META_DUPLICATE_OK,
    413414                                    keyComment, atoi(keyValue));
    414415            break;
    415416        case 'F':
    416             success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_META_F64,
     417            success = psMetadataAdd(output, PS_LIST_TAIL, keyName,
     418                                    PS_META_F64 | PS_META_DUPLICATE_OK,
    417419                                    keyComment, atof(keyValue));
    418420            break;
    419421        case 'C':
    420             success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_META_STR,
     422            success = psMetadataAdd(output, PS_LIST_TAIL, keyName,
     423                                    PS_META_STR | PS_META_DUPLICATE_OK,
    421424                                    keyComment, keyValue);
    422425            break;
    423426        case 'L':
    424427            tempBool = (keyValue[0] == 'T') ? 1 : 0;
    425             success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_META_BOOL,
     428            success = psMetadataAdd(output, PS_LIST_TAIL, keyName,
     429                                    PS_META_BOOL | PS_META_DUPLICATE_OK,
    426430                                    keyComment, tempBool);
    427431            break;
     
    456460    psF64 tempDbl = 0.0;
    457461    psS32 tempInt = 0.0;
    458     psMetadataItem *metadataItem = NULL;
    459462    psVector *tempVec = NULL;
    460463    FILE *fp = NULL;
    461464    psMetadataType mdType;
    462 
     465    psMetadataFlags flags;
     466    psBool addStatus;
    463467
    464468    // Check for nulls
     
    516520            }
    517521
     522            flags = (overwrite) ? PS_META_REPLACE : PS_META_DEFAULT;
     523
    518524            // Get the metadata item type
    519525            strType = getToken(&linePtr, " ", &status);
     
    524530                        fileName);
    525531                continue;
    526             } else if(!strncmp(strType, "*", 1)) {
    527                 mdType = PS_META_LIST;
    528             } else if(!strncmp(strType, "STR", 3)) {
    529                 mdType = PS_META_STR;
    530             } else if(!strncmp(strType, "BOOL", 4)) {
    531                 mdType = PS_META_BOOL;
    532             } else if(!strncmp(strType, "S32", 3)) {
    533                 mdType = PS_META_S32;
    534             } else if(!strncmp(strType, "F32", 3)) {
    535                 mdType = PS_META_F32;
    536             } else if(!strncmp(strType, "F64", 3)) {
    537                 mdType = PS_META_F64;
    538532            } else {
    539                 (*nFail)++;
    540                 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
    541                         fileName);
    542                 continue;
     533                char* tempStrType = strType;
     534                if(*strType == '*') {
     535                    flags = PS_META_DUPLICATE_OK;
     536                    tempStrType = strType+1;
     537                }
     538
     539                if(!strncmp(tempStrType, "STR", 3)) {
     540                    mdType = PS_META_STR;
     541                } else if(!strncmp(tempStrType, "BOOL", 4)) {
     542                    mdType = PS_META_BOOL;
     543                } else if(!strncmp(tempStrType, "S32", 3)) {
     544                    mdType = PS_META_S32;
     545                } else if(!strncmp(tempStrType, "F32", 3)) {
     546                    mdType = PS_META_F32;
     547                } else if(!strncmp(tempStrType, "F64", 3)) {
     548                    mdType = PS_META_F64;
     549                } else {
     550                    (*nFail)++;
     551                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
     552                            fileName);
     553                    continue;
     554                }
    543555            }
    544556
     
    548560            }
    549561
    550             // Get the metadata item value if there is one. Lines with * don't have values.
    551             if(mdType != PS_META_LIST) {
    552                 strValue = getToken(&linePtr, "#", &status);
    553                 if(strValue==NULL) {
    554                     (*nFail)++;
    555                     status = 0;
    556                     psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
    557                             fileName);
    558                     continue;
    559                 }
    560             }
    561 
    562             // Get the metadata item value if there is one. Not all lines will have comments, so NULL is ok.
     562            // Get the metadata item value if there is one.
     563            strValue = getToken(&linePtr, "#", &status);
     564            if(status) {
     565                (*nFail)++;
     566                status = 0;
     567                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount,
     568                        fileName);
     569                continue;
     570            }
     571            if(strValue==NULL) {
     572                (*nFail)++;
     573                status = 0;
     574                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
     575                        fileName);
     576                continue;
     577            }
     578
     579            // Not all lines will have comments, so NULL is ok.
    563580            strComment = getToken(&linePtr,"~", &status);
    564581            if(status) {
     
    570587            }
    571588
    572             /* If metadata item is found, is not a folder node, and overwrite is allowed, then remove existing
    573             and allow switch/case below to add new item. If overwrite is false, then report error. If found
    574             item is folder node, then psMetadataAdd will automatically add a new child. */
    575             metadataItem = psMetadataLookup(md, strName);
    576             if(metadataItem != NULL) {
    577                 if(metadataItem->type!=PS_META_LIST) {
    578                     if(overwrite) {
    579                         psMetadataRemove(md, INT_MIN, strName);
    580                     } else {
    581                         (*nFail)++;
    582                         psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
    583                                 fileName);
    584                         continue;
    585                     }
    586                 }
    587             }
    588 
    589589            // Create and add metadata item to metadata and parse values
    590590            switch (mdType) {
    591             case PS_META_LIST:
    592                 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
    593                 break;
    594591            case PS_META_STR:
    595                 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, strComment, strValue);
     592                addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName,
     593                                          mdType | flags,
     594                                          strComment, strValue);
    596595                break;
    597596            case PS_META_VEC:
    598597                tempVec = parseVector(strValue, vecType, &status);
    599598                if(!status) {
    600                     psMetadataAdd(md, PS_LIST_TAIL, strName+1, mdType, strComment, tempVec);
     599                    addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName+1,
     600                                              mdType | flags,
     601                                              strComment, tempVec);
    601602                } else {
    602603                    status = 0;
     
    611612                tempBool = parseBool(strValue, &status);
    612613                if(!status) {
    613                     psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, strComment, tempBool);
     614                    addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName,
     615                                              mdType | flags,
     616                                              strComment, tempBool);
    614617                } else {
    615618                    status = 0;
     
    623626                tempInt = (psS32)parseValue(strValue, &status);
    624627                if(!status) {
    625                     psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, strComment, tempInt);
     628                    addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName,
     629                                              mdType | flags,
     630                                              strComment, tempInt);
    626631                } else {
    627632                    status = 0;
     
    636641                tempDbl = parseValue(strValue, &status);
    637642                if(!status) {
    638                     psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, strComment, tempDbl);
     643                    addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName,
     644                                              mdType | flags,
     645                                              strComment, tempDbl);
    639646                } else {
    640647                    status = 0;
     
    652659                continue;
    653660            } // switch
     661            if (! addStatus) {
     662                (*nFail)++;
     663                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
     664                        fileName);
     665            }
     666
    654667        } // if ignoreLine
    655668    } // while loop
     
    725738    // Add attributes to metadata
    726739
    727     psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_META_HASH, NULL, htAtts);
     740    psMetadataAdd(md, PS_LIST_TAIL, "htAtts",
     741                  PS_META_HASH | PS_META_DUPLICATE_OK,
     742                  NULL, htAtts);
    728743
    729744    psFree(psTagName);
     
    828843    switch(mdType) {
    829844    case PS_META_LIST:
    830         psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
     845        psMetadataAdd(md, PS_LIST_TAIL, strName,
     846                      mdType | PS_META_DUPLICATE_OK,
     847                      NULL, NULL);
    831848        break;
    832849    case PS_META_STR:
    833         psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, strValue);
     850        psMetadataAdd(md, PS_LIST_TAIL, strName,
     851                      mdType | PS_META_DUPLICATE_OK,
     852                      NULL, strValue);
    834853        break;
    835854    case PS_META_BOOL:
    836855        tempBool = parseBool((char*)strValue, &status);
    837856        if(!status) {
    838             psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempBool);
     857            psMetadataAdd(md, PS_LIST_TAIL, strName,
     858                          mdType | PS_META_DUPLICATE_OK,
     859                          NULL, tempBool);
    839860        } else {
    840861            status = 0;
     
    846867        tempInt = (psS32)parseValue((char*)strValue, &status);
    847868        if(!status) {
    848             psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempInt);
     869            psMetadataAdd(md, PS_LIST_TAIL, strName,
     870                          mdType | PS_META_DUPLICATE_OK,
     871                          NULL, tempInt);
    849872        } else {
    850873            status = 0;
     
    857880        tempDbl = parseValue((char*)strValue, &status);
    858881        if(!status) {
    859             psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempDbl);
     882            psMetadataAdd(md, PS_LIST_TAIL, strName,
     883                          mdType | PS_META_DUPLICATE_OK,
     884                          NULL, tempDbl);
    860885        } else {
    861886            status = 0;
     
    966991    vec = parseVector((char*)strValue, pType, &status);
    967992    if(!status) {
    968         psMetadataAdd(md, PS_LIST_TAIL, strName+1, PS_META_VEC, NULL, vec);
     993        psMetadataAdd(md, PS_LIST_TAIL, strName+1,
     994                      PS_META_VEC | PS_META_DUPLICATE_OK,
     995                      NULL, vec);
    969996    } else {
    970997        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
  • trunk/psLib/src/collections/psMetadataIO.h

    r3264 r3381  
    11/** @file  psMetadataIO.h
    2 *
    3 *  @brief Contains metadata input/output functions.
    4 *
    5 *  This file defines functions to read and write metadata to/from an external file.
    6 *
    7 *  @ingroup Metadata
    8 *
    9 *  @author Ross Harman, MHPCC
    10 *
    11 *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    12 *  @date $Date: 2005-02-17 19:26:23 $
    13 *
    14 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    15 */
     2 *
     3 *  @brief Contains metadata input/output functions.
     4 *
     5 *  This file defines functions to read and write metadata to/from an external file.
     6 *
     7 *  @ingroup Metadata
     8 *
     9 *  @author Ross Harman, MHPCC
     10 *  @author Robert DeSonia, MHPCC
     11 *
     12 *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2005-03-07 20:58:50 $
     14 *
     15 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     16 */
    1617#ifndef PS_METADATAIO_H
    1718#define PS_METADATAIO_H
    18 
    1919
    2020/// @addtogroup Metadata
Note: See TracChangeset for help on using the changeset viewer.