Changeset 3381 for trunk/psLib/src/astronomy/psMetadata.c
- Timestamp:
- Mar 7, 2005, 10:58:51 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/astronomy/psMetadata.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astronomy/psMetadata.c
r3341 r3381 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1.5 3$ $Name: not supported by cvs2svn $15 * @date $Date: 2005-0 2-28 23:34:10 $14 * @version $Revision: 1.54 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2005-03-07 20:58:50 $ 16 16 * 17 17 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 85 85 } 86 86 87 static void metadataIteratorFree(psMetadataIterator* iter) 88 { 89 if (iter == NULL) { 90 return; 91 } 92 psFree(iter->iter); 93 regfree(iter->preg); 94 } 95 87 96 static void metadataFree(psMetadata* metadata) 88 97 { … … 158 167 159 168 // Set metadata item type 160 metadataItem->type = type ;169 metadataItem->type = type & PS_METADATA_TYPE_MASK; 161 170 162 171 // Allocate and set metadata item name … … 165 174 166 175 // Set metadata item value 167 switch( type) {176 switch(metadataItem->type) { 168 177 case PS_META_BOOL: 169 178 metadataItem->data.B = (psBool)va_arg(argPtr, psS32); … … 190 199 case PS_META_ASTROM: 191 200 case PS_META_UNKNOWN: 201 case PS_META_MULTI: 192 202 // Copy of input data not performed due to variability of data types 193 203 metadataItem->data.V = psMemIncrRefCounter(va_arg(argPtr, psPtr)); … … 223 233 } 224 234 225 psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location )235 psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location, psS32 flags) 226 236 { 227 237 char * key = NULL; … … 229 239 psList *mdList = NULL; 230 240 psMetadataItem *existingEntry = NULL; 231 psMetadataItem *newFolderEntry = NULL;232 psMetadataType newType;233 241 234 242 PS_PTR_CHECK_NULL(md,NULL); … … 238 246 PS_PTR_CHECK_NULL(metadataItem->name,NULL); 239 247 240 newType = metadataItem->type;241 248 mdTable = md->table; 242 249 mdList = md->list; … … 245 252 // See if key is already in table 246 253 existingEntry = (psMetadataItem*)psHashLookup(mdTable, key); 254 255 // how the item is added to the hash depends on flags & prior existence 247 256 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 253 277 } 254 278 255 // Add leaf node to existing folder node256 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); 258 282 return false; 259 283 } 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) 309 294 if(!psHashAdd(mdTable, key, metadataItem)) { 310 295 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 311 296 return false; 312 297 } 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; 313 303 } 314 304 } else { 305 // OK, this is a new item. 315 306 316 307 // Node doesn't exist - Add new metadata item to metadata collection's hash … … 321 312 } 322 313 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; 330 317 } 331 318 … … 333 320 } 334 321 335 psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name,336 ps MetadataTypetype, const char *comment, ...)322 psBool psMetadataAdd(psMetadata *md, psS32 location, const char *name, 323 psS32 type, const char *comment, ...) 337 324 { 338 325 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 334 psBool psMetadataAddV(psMetadata *md, psS32 location, const char *name, 335 psS32 type, const char *comment, va_list list) 336 { 339 337 psMetadataItem* metadataItem = NULL; 340 338 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)) { 346 342 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_FAILED); 347 343 psFree(metadataItem); … … 373 369 psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key) 374 370 { 375 psList* mdList = NULL;376 psHash* mdTable = NULL;377 psMetadataItem* entry = NULL;378 379 380 371 PS_PTR_CHECK_NULL(md,NULL); 372 373 PS_PTR_CHECK_NULL(md->list,NULL); 374 psList* mdList = md->list; 375 381 376 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; 386 378 387 379 // Select removal by key or index 388 380 if (key != NULL) { 389 390 381 // Remove by key name 391 entry = (psMetadataItem*)psHashLookup(mdTable,key);382 psMetadataItem* entry = psHashLookup(mdTable,key); 392 383 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); 394 385 return false; 395 386 } 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 } 397 402 } else { 398 399 403 // Remove by index 400 entry = psListGet(mdList, where);404 psMetadataItem* entry = psListGet(mdList, where); 401 405 if (entry == NULL) { 402 406 psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where); 403 407 return false; 404 408 } 405 406 409 key = entry->name; 407 if(key == NULL) { 410 411 if (key == NULL) { 408 412 psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED, where); 409 413 return false; 410 414 } 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); 422 439 } 423 440 … … 455 472 } 456 473 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); 457 478 } 458 479 … … 486 507 } \ 487 508 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); \ 488 513 } \ 489 514 \ … … 535 560 return entry; 536 561 } 562 563 psMetadataIterator* 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 599 psBool 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 650 psMetadataItem* 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 678 psMetadataItem* 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 }
Note:
See TracChangeset
for help on using the changeset viewer.
