Changeset 3945 for trunk/psLib/src/collections/psMetadataIO.c
- Timestamp:
- May 16, 2005, 9:43:53 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/collections/psMetadataIO.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/collections/psMetadataIO.c
r3769 r3945 8 8 * 9 9 * @author Ross Harman, MHPCC 10 * @author Eric Van Alst, MHPCC 10 11 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2005-0 4-26 19:53:30$12 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 13 14 * 14 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 33 34 #include "psConstants.h" 34 35 #include "psAstronomyErrors.h" 35 36 36 37 37 /******************************************************************************/ … … 53 53 return NULL; 54 54 55 /** Free and null temporary variables used by config file parser */56 #define CLEAR_TEMPS() \57 if(strName) { \58 psFree(strName); \59 strName = NULL; \60 } \61 if(strType) { \62 psFree(strType); \63 strType = NULL; \64 } \65 if(strValue) { \66 psFree(strValue); \67 strValue = NULL; \68 } \69 if(strComment) { \70 psFree(strComment); \71 strComment = NULL; \72 }73 74 55 /** Maximum size of a FITS line */ 75 56 #define FITS_LINE_SIZE 80 … … 105 86 static void initMetadataItemXml(void *ctx, char *tagName); 106 87 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts); 107 108 /** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 109 * must be null terminated. */ 88 static psMetadata* getMetadataType(char *linePtr); 89 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 90 ; 91 static void parseLevelInfoFree(p_psParseLevelInfo* info); 92 static psBool parseLine(psS32* level, psArray* levelArray, 93 char* linePtr, psS32 lineCount, char* fileName, psBool overwrite); 94 static psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 95 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags); 96 97 static void parseLevelInfoFree(p_psParseLevelInfo* info) 98 { 99 psFree(info->nonUniqueKeyArray); 100 psFree(info->typeArray); 101 psFree(info->templateArray); 102 psFree(info->name); 103 psFree(info->metadata); 104 } 105 106 // Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 107 // must be null terminated. 110 108 psBool ignoreLine(char *inString) 111 109 { … … 121 119 122 120 123 / **Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null124 * terminated copy of the original input string. */ 125 char *cleanString(char *inString, psS32 sLen )121 // Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 122 // terminated copy of the original input string. 123 char *cleanString(char *inString, psS32 sLen, psBool ignoreComment) 126 124 { 127 125 char *ptrB = NULL; … … 129 127 char *cleaned = NULL; 130 128 131 129 // Initialize begining of string pointer 132 130 ptrB = inString; 133 131 134 /* Skip over leading # or whitespace */ 135 while (isspace(*ptrB) || *ptrB=='#') { 136 ptrB++; 137 } 138 139 /* Skip over trailing whitespace, null terminators, and # characters */ 132 // Skip over leading # or whitespace 133 if(ignoreComment) { 134 while (isspace(*ptrB) || *ptrB=='#') { 135 ptrB++; 136 } 137 } else { 138 while (isspace(*ptrB)) { 139 ptrB++; 140 } 141 } 142 143 // Skip over trailing whitespace, null terminators, and # characters 140 144 ptrE = inString + sLen; 141 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 142 ptrE--; 145 if(ignoreComment) { 146 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 147 ptrE--; 148 } 149 } else { 150 while(isspace(*ptrE) || *ptrE=='\0') { 151 ptrE--; 152 } 143 153 } 144 154 … … 152 162 } 153 163 154 / ** Count repeat occurances of a single character within a line. The input string must be null terminated. */164 // Count repeat occurances of a single character within a line. The input string must be null terminated. 155 165 psS32 repeatedChars(char *inString, char ch) 156 166 { 157 167 psS32 count = 0; 158 159 168 160 169 while(*inString!='\0') { … … 168 177 } 169 178 170 / **Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location171 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 172 char* getToken(char **inString, char *delimiter, psS32 *status )179 // Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 180 // the beginning of the string. Tokens are newly allocated null terminated strings. 181 char* getToken(char **inString, char *delimiter, psS32 *status, psBool ignoreComment) 173 182 { 174 183 char *cleanToken = NULL; 184 char *convertChar = NULL; 175 185 psS32 sLen = 0; 176 186 187 // Convert tab characters to white space 188 while((convertChar=strchr(*inString,'\t')) != NULL ) { 189 *convertChar = ' '; 190 } 177 191 178 192 // Skip over leading whitespace … … 186 200 187 201 // Create new, cleaned, and null terminated token 188 cleanToken = cleanString(*inString, sLen );202 cleanToken = cleanString(*inString, sLen,ignoreComment); 189 203 190 204 // Move to end of token … … 197 211 } 198 212 199 / **Returns single parsed value as a double precision number. The input string must be cleaned and null200 * terminated. */ 213 // Returns single parsed value as a double precision number. The input string must be cleaned and null 214 // terminated. 201 215 double parseValue(char *inString, psS32 *status) 202 216 { 203 217 char *end = NULL; 204 218 double value = 0.0; 205 206 219 207 220 value = strtod(inString, &end); … … 235 248 psVector* parseVector(char *inString, psElemType elemType, psS32 *status) 236 249 { 237 char *end = NULL; 238 char *saveValue = NULL; 239 psS32 i = 0; 240 psS32 numValues = 0; 241 double value = 0.0; 242 psVector *vec = NULL; 243 250 char* end = NULL; 251 char* saveValue = NULL; 252 psS32 i = 0; 253 psS32 numValues = 0; 254 double value = 0.0; 255 psVector* vec = NULL; 244 256 245 257 // Cycle through string and count entries … … 274 286 vec->data.U8[i++] = (psU8)value; 275 287 break; 288 case PS_TYPE_U16: 289 vec->data.U16[i++] = (psU16)value; 290 break; 291 case PS_TYPE_U32: 292 vec->data.U32[i++] = (psU32)value; 293 break; 294 case PS_TYPE_U64: 295 vec->data.U64[i++] = (psU64)value; 296 break; 297 case PS_TYPE_S8: 298 vec->data.S8[i++] = (psS8)value; 299 break; 300 case PS_TYPE_S16: 301 vec->data.S16[i++] = (psS16)value; 302 break; 276 303 case PS_TYPE_S32: 277 304 vec->data.S32[i++] = (psS32)value; 305 break; 306 case PS_TYPE_S64: 307 vec->data.S64[i++] = (psS64)value; 278 308 break; 279 309 case PS_TYPE_F32: … … 303 333 /* FUNCTION IMPLEMENTATION - PUBLIC */ 304 334 /*****************************************************************************/ 335 336 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void) 337 { 338 339 p_psParseLevelInfo* info = NULL; 340 341 // Allocate memory for parse level info 342 info = (p_psParseLevelInfo*)psAlloc(sizeof(p_psParseLevelInfo)); 343 344 // If allocation successful then initialize members 345 if(info != NULL) { 346 347 info->nonUniqueKeyArray = psArrayAlloc(10); 348 info->nonUniqueKeyArray->n = 0; 349 350 info->typeArray = psArrayAlloc(10); 351 info->typeArray->n = 0; 352 353 info->templateArray = psArrayAlloc(10); 354 info->templateArray->n = 0; 355 356 info->metadata = NULL; 357 info->name = NULL; 358 359 // Set memory deallocator 360 psMemSetDeallocator(info,(psFreeFcn)parseLevelInfoFree); 361 } 362 return info; 363 } 305 364 306 365 bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem) … … 500 559 } 501 560 561 static psMetadata* getMetadataType(char* linePtr) 562 { 563 psMetadata* metadataTemplate = NULL; 564 psS32 status = 0; 565 char* token = NULL; 566 psMetadataItem* tempItem = NULL; 567 568 // Loop through line and generate metadata items for each token found 569 while((token = getToken(&linePtr," ",&status,false)) != NULL ) { 570 571 // If not allocated then allocate new metadata 572 if(metadataTemplate == NULL) { 573 metadataTemplate = psMetadataAlloc(); 574 } 575 576 // Look for comment indicator # 577 if(strstr(token,"#") != 0) { 578 psFree(token); 579 break; 580 } 581 582 // Create metadata item to represent token read 583 tempItem = psMetadataItemAllocStr(token,"",""); 584 if(tempItem == NULL) { 585 psFree(metadataTemplate); 586 psFree(token); 587 metadataTemplate = NULL; 588 break; 589 } 590 591 // Add item to template 592 if(!psMetadataAddItem(metadataTemplate, tempItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 593 psFree(metadataTemplate); 594 psFree(tempItem); 595 psFree(token); 596 metadataTemplate = NULL; 597 break; 598 } 599 psFree(tempItem); 600 psFree(token); 601 } 602 603 return metadataTemplate; 604 } 605 606 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 607 { 608 psMetadata* md = NULL; 609 psS32 items = 0; 610 char* token = NULL; 611 psS32 status = 0; 612 psMetadataItem* mdItem = NULL; 613 psMetadataItem* templateItem = NULL; 614 psListIterator* iter = NULL; 615 616 // Determine the number of items in template 617 items = template->list->size; 618 if(items > 0 ) { 619 620 // Allocate metadata 621 md = psMetadataAlloc() 622 ; 623 624 // Point to first item in template 625 iter = psListIteratorAlloc(template-> 626 list,PS_LIST_HEAD,true); 627 628 // For each item in template parse line string for values 629 for(psS32 i = 0; 630 i < items; 631 i++) { 632 633 // Get template item 634 templateItem = psListGetAndIncrement(iter) 635 ; 636 if(templateItem == NULL) { 637 psFree(md); 638 md = NULL; 639 break; 640 } 641 642 // Get the next token on the line 643 token = getToken(&linePtr," ",&status,false); 644 if(token != NULL) { 645 // Allocate metadata item 646 mdItem = psMetadataItemAllocStr(templateItem->name,templateItem->comment,token); 647 if(mdItem == NULL) { 648 psFree(md); 649 md = NULL; 650 psFree(token); 651 break; 652 } 653 // Add item to metadata 654 if(!psMetadataAddItem(md, mdItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 655 psFree(md); 656 md = NULL; 657 psFree(mdItem); 658 psFree(token); 659 break; 660 } 661 psFree(mdItem); 662 } else { 663 // Missing items 664 psFree(md); 665 md = NULL; 666 break; 667 } 668 669 psFree(token); 670 } 671 psFree(iter); 672 } 673 return md; 674 } 675 676 psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 677 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags) 678 { 679 psBool returnValue = true; 680 psBool addStatus = false; 681 psMetadataType mdType = PS_META_UNKNOWN; 682 psElemType vectorType = PS_TYPE_S8; 683 char* strType = NULL; 684 char* strValue = NULL; 685 char* strComment = NULL; 686 psS32 status = 0; 687 psMetadata* md = NULL; 688 psF64 tempDbl = 0.0; 689 psBool tempBool = false; 690 psS32 tempInt = 0; 691 psVector* tempVec = NULL; 692 char* tempStr = NULL; 693 psArray* nonUniqueKeys = NULL; 694 psBool typeFound = false; 695 psArray* typeArray = NULL; 696 psArray* templateArray = NULL; 697 psMetadata* tempMeta = NULL; 698 p_psParseLevelInfo* nextLevelInfo = NULL; 699 700 // Get the metadata item type 701 strType = getToken(&linePtr, " ", &status,true); 702 703 // Check for no type 704 if(strType==NULL) { 705 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 706 fileName); 707 returnValue = false; 708 } else { 709 710 // Set metadata type based on type token 711 712 // Check if the keyName specifies a vector and if so use strType token to find vector type 713 if(*keyName == '@') { 714 mdType = PS_META_VEC; 715 // Get the type of vector 716 if(!strncmp(strType, "U8", 2)) { 717 vectorType = PS_TYPE_U8; 718 } else if (!strncmp(strType,"U16",3)) { 719 vectorType = PS_TYPE_U16; 720 } else if (!strncmp(strType,"U32",3)) { 721 vectorType = PS_TYPE_U32; 722 } else if (!strncmp(strType,"U64",3)) { 723 vectorType = PS_TYPE_U64; 724 } else if (!strncmp(strType,"S8",2)) { 725 vectorType = PS_TYPE_S8; 726 } else if (!strncmp(strType,"S16",3)) { 727 vectorType = PS_TYPE_S16; 728 } else if (!strncmp(strType,"S32",3)) { 729 vectorType = PS_TYPE_S32; 730 } else if (!strncmp(strType,"S64",3)) { 731 vectorType = PS_TYPE_S64; 732 } else if (!strncmp(strType,"F32",3)) { 733 vectorType = PS_TYPE_F32; 734 } else if (!strncmp(strType,"F64",3)) { 735 vectorType = PS_TYPE_F64; 736 } else { 737 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, "", keyName, 738 strType, lineCount, fileName); 739 psFree(strType); 740 return false; 741 } 742 } else if(!strncmp(strType, "STR", 3)) { 743 mdType = PS_META_STR; 744 } else if(!strncmp(strType, "BOOL", 4)) { 745 mdType = PS_META_BOOL; 746 } else if(!strncmp(strType, "S32", 3)) { 747 mdType = PS_META_S32; 748 } else if(!strncmp(strType, "F32", 3)) { 749 mdType = PS_META_F32; 750 } else if(!strncmp(strType, "F64", 3)) { 751 mdType = PS_META_F64; 752 } else if(!strncmp(strType, "MULTI", 5)) { 753 mdType = PS_META_MULTI; 754 } else if(!strncmp(strType, "METADATA", 8)) { 755 mdType = PS_META_META; 756 } else { 757 // Search through user types 758 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 759 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 760 for(psS32 k = 0; k < typeArray->n; k++) { 761 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 762 tempMeta = setMetadataItem((psMetadata*)templateArray->data[k],linePtr); 763 if(tempMeta != NULL) { 764 // Add metadata item 765 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 766 addStatus = psMetadataAdd(md,PS_LIST_TAIL,keyName,PS_META_META | flags,"",tempMeta); 767 // Check for add failure 768 if (! addStatus) { 769 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, 770 keyName, lineCount, fileName); 771 psFree(strType); 772 psFree(tempMeta); 773 return false; 774 } 775 psFree(tempMeta); 776 } else { 777 // Metadata type read error 778 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, 779 keyName,lineCount,fileName); 780 psFree(strType); 781 return false; 782 } 783 typeFound = true; 784 break; 785 } 786 } 787 if(!typeFound) { 788 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 789 strType, lineCount,fileName); 790 psFree(strType); 791 return false; 792 } else { 793 psFree(strType); 794 return true; 795 } 796 } 797 } 798 799 // If type is not MULTI or META then get the value and comment 800 if((mdType != PS_META_MULTI) && (mdType != PS_META_META)) { 801 // Get the metadata item value if there is one. 802 status = 0; 803 strValue = getToken(&linePtr, "#", &status,true); 804 if(status) { 805 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 806 fileName); 807 psFree(strType); 808 psFree(strValue); 809 return false; 810 } 811 if(strValue==NULL) { 812 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 813 fileName); 814 psFree(strType); 815 psFree(strValue); 816 return false; 817 } 818 // Not all lines will have comments, so NULL is ok. 819 status = 0; 820 strComment = getToken(&linePtr,"~", &status,true); 821 if(status) { 822 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 823 fileName); 824 psFree(strType); 825 psFree(strValue); 826 psFree(strComment); 827 } 828 } 829 830 // Need to add item to metadata so get pointer to metadata 831 status = 0; 832 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 833 nonUniqueKeys = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray; 834 switch(mdType) { 835 case PS_META_STR: 836 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 837 mdType | flags, 838 strComment, strValue); 839 break; 840 case PS_META_BOOL: 841 tempBool = parseBool(strValue, &status); 842 if(!status) { 843 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 844 mdType | flags, 845 strComment, tempBool); 846 } else { 847 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 848 strType, lineCount, fileName); 849 returnValue = false; 850 } 851 break; 852 case PS_META_F32: 853 case PS_META_F64: 854 tempDbl = parseValue(strValue, &status); 855 if(!status) { 856 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 857 mdType | flags, 858 strComment, tempDbl); 859 } else { 860 psError(PS_ERR_IO, true, 861 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, strType, lineCount, 862 fileName); 863 returnValue = false; 864 } 865 break; 866 case PS_META_S32: 867 tempInt = (psS32)parseValue(strValue, &status); 868 if(!status) { 869 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 870 mdType | flags, 871 strComment, tempInt); 872 } else { 873 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 874 strType, lineCount, fileName); 875 returnValue = false; 876 } 877 break; 878 case PS_META_VEC: 879 tempVec = parseVector(strValue, vectorType, &status); 880 if(!status) { 881 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName+1, 882 mdType | flags, 883 strComment, tempVec); 884 } else { 885 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 886 strType, lineCount, fileName); 887 returnValue = false; 888 } 889 psFree(tempVec); 890 break; 891 case PS_META_MULTI: 892 // Add key to non-unique array of keys 893 // Check for duplicate MULTI lines 894 addStatus = true; 895 for(psS32 k=0; k < nonUniqueKeys->n; k++) { 896 if(strcmp(keyName,(char*)nonUniqueKeys->data[k]) == 0) { 897 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_DUPLICATE_MULTI, 898 lineCount,fileName); 899 psFree(strType); 900 return false; 901 } 902 } 903 tempStr = psStringCopy(keyName); 904 nonUniqueKeys = psArrayAdd(nonUniqueKeys,0,tempStr); 905 addStatus = true; 906 psFree(tempStr); 907 break; 908 case PS_META_META: 909 // Create next level info 910 nextLevelInfo = p_psParseLevelInfoAlloc(); 911 // Create new metadata 912 nextLevelInfo->metadata = psMetadataAlloc(); 913 // Save name of metadata 914 nextLevelInfo->name = psStringCopy(keyName); 915 // Add next level to levelArray 916 levelArray = psArrayAdd(levelArray,1,nextLevelInfo); 917 psFree(nextLevelInfo); 918 // Increment level counter 919 (*level)++; 920 addStatus = true; 921 break; 922 default: 923 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 924 lineCount,fileName); 925 break; 926 } 927 928 // Check if the add status was successful 929 if (! addStatus) { 930 // psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, keyName, lineCount, 931 // fileName); 932 returnValue = false; 933 } 934 935 psFree(strComment); 936 psFree(strValue); 937 psFree(strType); 938 939 return returnValue; 940 } 941 942 psBool parseLine(psS32* level, psArray* levelArray, char* linePtr, 943 psS32 lineCount, char* fileName, psBool overwrite) 944 { 945 psBool returnValue = true; 946 psMetadataFlags flags = PS_META_DEFAULT; 947 char* keyName = NULL; 948 psS32 status = 0; 949 psS32 limit = 0; 950 psMetadata* tempTemplate = NULL; 951 char* strType = NULL; 952 psArray* typeArray = NULL; 953 psArray* templateArray = NULL; 954 p_psParseLevelInfo* upperLevelInfo = NULL; 955 p_psParseLevelInfo* lowerLevelInfo = NULL; 956 psBool addStatus = 0; 957 958 // Set flags if overwrite specified 959 if(overwrite) { 960 flags = PS_META_REPLACE; 961 } 962 963 // If line is not a comment or blank, then extract data 964 if(!ignoreLine(linePtr)) { 965 966 // Check for more than one '@' in a line 967 if(repeatedChars(linePtr, '@') > 1) { 968 psError(PS_ERR_IO, true, 969 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 970 return false; 971 } 972 973 // Get metadata item name 974 keyName = getToken(&linePtr, " ", &status,true); 975 if(status) { 976 psError(PS_ERR_IO, true, 977 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "keyName", lineCount, fileName); 978 psFree(keyName); 979 return false; 980 } 981 982 // Check for special keyName values "TYPE", "END" 983 if(strcmp(keyName,"TYPE") == 0 ) { 984 // Get the type name 985 strType = getToken(&linePtr," ",&status,true); 986 if(strType == NULL) { 987 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL,"type",lineCount, 988 fileName); 989 psFree(keyName); 990 return false; 991 } 992 tempTemplate = getMetadataType(linePtr); 993 // Check if type was parsed succesfully 994 if(tempTemplate != NULL) { 995 // Access type array 996 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 997 // Check if type already exists in array 998 for(psS32 k=0; k < typeArray->n; k++) { 999 // Compare type name with the list of current types 1000 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 1001 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_TYPE_DUPLICATE, 1002 strType,lineCount,fileName); 1003 psFree(tempTemplate); 1004 psFree(keyName); 1005 psFree(strType); 1006 return false; 1007 } 1008 } 1009 // Add key name to array of type 1010 typeArray = psArrayAdd(typeArray,1,strType); 1011 // Add template to array of templates 1012 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 1013 templateArray = psArrayAdd(templateArray,1,tempTemplate); 1014 psFree(tempTemplate); 1015 } else { 1016 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 1017 strType,lineCount,fileName); 1018 psFree(keyName); 1019 psFree(strType); 1020 return false; 1021 } 1022 psFree(strType); 1023 } else if (strcmp(keyName,"END") == 0 ) { 1024 if(*level > 0) { 1025 upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1])); 1026 lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level])); 1027 // Check name in nonunique list 1028 for(psS32 k=0; k < upperLevelInfo->nonUniqueKeyArray->n; k++) { 1029 if(strcmp(upperLevelInfo->nonUniqueKeyArray->data[k],lowerLevelInfo->name) == 0) { 1030 flags = PS_META_DUPLICATE_OK; 1031 break; 1032 } 1033 } 1034 // Add metadata to upper level metadata 1035 addStatus = psMetadataAdd(upperLevelInfo->metadata, 1036 PS_LIST_TAIL,lowerLevelInfo->name, 1037 PS_META_META | flags, 1038 "", 1039 lowerLevelInfo->metadata); 1040 if(!addStatus) { 1041 psFree(keyName); 1042 return false; 1043 } else { 1044 // Remove lower info level 1045 if(!psArrayRemove(levelArray,levelArray->data[*level])) { 1046 psFree(keyName); 1047 return false; 1048 } 1049 psFree(lowerLevelInfo); 1050 (*level)--; 1051 } 1052 } else { 1053 psFree(keyName); 1054 return false; 1055 } 1056 } else { 1057 // Check if key name present in array of non-unique key names 1058 limit = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray->n; 1059 for(psS32 k=0; k < limit; k++) { 1060 char* name = (char*)((p_psParseLevelInfo*) 1061 (levelArray->data[*level]))->nonUniqueKeyArray->data[k]; 1062 if(strcmp(name,keyName) == 0) { 1063 flags = PS_META_DUPLICATE_OK; 1064 } 1065 } 1066 // Parse metadataItem 1067 if(!parseMetadataItem(keyName,level, levelArray, linePtr, lineCount, fileName, flags)) { 1068 psFree(keyName); 1069 return false; 1070 } 1071 } 1072 psFree(keyName); 1073 } 1074 return returnValue; 1075 } 1076 502 1077 psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite) 503 1078 { 504 psBool tempBool; 505 char *line = NULL; 506 char *strName = NULL; 507 char *strType = NULL; 508 char *strValue = NULL; 509 char *strComment = NULL; 510 char *linePtr = NULL; 511 psElemType vecType = 0; 512 psS32 status = 0; 513 psU32 lineCount = 0; 514 psF64 tempDbl = 0.0; 515 psS32 tempInt = 0.0; 516 psVector *tempVec = NULL; 517 FILE *fp = NULL; 518 psMetadataType mdType; 519 psMetadataFlags flags; 520 psBool addStatus; 521 522 // Check for nulls 1079 FILE* fp = NULL; 1080 char* line = NULL; 1081 char* linePtr = NULL; 1082 psArray* parseLevelInfoArray = NULL; 1083 psS32 lineCount = 0; 1084 psS32 nestingLevel = 0; 1085 p_psParseLevelInfo* topLevelInfo = NULL; 1086 1087 // Check for NULL file name 523 1088 PS_PTR_CHECK_NULL(fileName,NULL); 1089 1090 // Check for NULL nFail 1091 PS_PTR_CHECK_NULL(nFail,NULL); 1092 1093 // Attempt to open specified file 524 1094 if((fp=fopen(fileName, "r")) == NULL) { 525 1095 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName); … … 532 1102 } 533 1103 1104 // Allocate array to store parse level information 1105 parseLevelInfoArray = psArrayAlloc(10); 1106 parseLevelInfoArray->n = 0; 1107 1108 // Set parse level info for the top level 1109 topLevelInfo = p_psParseLevelInfoAlloc(); 1110 topLevelInfo->metadata = psMemIncrRefCounter(md); 1111 parseLevelInfoArray = psArrayAdd(parseLevelInfoArray,1,topLevelInfo); 1112 psFree(topLevelInfo); 1113 534 1114 // Create reusable line for continuous read 535 1115 line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char)); … … 541 1121 linePtr = line; 542 1122 lineCount++; 543 CLEAR_TEMPS(); 544 545 // If line is not a comment or blank, then extract data 546 if(!ignoreLine(linePtr)) { 547 548 // Check for more than one '*' or '@' in a line 549 if(repeatedChars(linePtr, '@') > 1) { 550 (*nFail)++; 551 psError(PS_ERR_IO, true, 552 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 553 continue; 554 } else if(repeatedChars(linePtr, '*') > 1) { 555 (*nFail)++; 556 psError(PS_ERR_IO, true, 557 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName); 558 continue; 559 } else if(repeatedChars(linePtr, '~') > 0) { 560 (*nFail)++; 561 psError(PS_ERR_IO, true, 562 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName); 563 continue; 564 } 565 566 // Get metadata item name 567 strName = getToken(&linePtr, " ", &status); 568 if(strName==NULL || status) { 569 (*nFail)++; 570 status = 0; 571 psError(PS_ERR_IO, true, 572 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName); 573 continue; 574 } 575 576 flags = (overwrite) ? PS_META_REPLACE : PS_META_DEFAULT; 577 578 // Get the metadata item type 579 strType = getToken(&linePtr, " ", &status); 580 if(strType==NULL) { 581 (*nFail)++; 582 status = 0; 583 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 584 fileName); 585 continue; 586 } else { 587 char* tempStrType = strType; 588 if(*strType == '*') { 589 flags = PS_META_DUPLICATE_OK; 590 tempStrType = strType+1; 591 } 592 593 if(!strncmp(tempStrType, "STR", 3)) { 594 mdType = PS_META_STR; 595 } else if(!strncmp(tempStrType, "BOOL", 4)) { 596 mdType = PS_META_BOOL; 597 } else if(!strncmp(tempStrType, "S32", 3)) { 598 mdType = PS_META_S32; 599 } else if(!strncmp(tempStrType, "F32", 3)) { 600 mdType = PS_META_F32; 601 } else if(!strncmp(tempStrType, "F64", 3)) { 602 mdType = PS_META_F64; 603 } else { 604 (*nFail)++; 605 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount, 606 fileName); 607 continue; 608 } 609 } 610 611 if(*strName == '@') { 612 vecType = PS_META_PRIMITIVE_TYPE(mdType); 613 mdType = PS_META_VEC; 614 } 615 616 // Get the metadata item value if there is one. 617 strValue = getToken(&linePtr, "#", &status); 618 if(status) { 619 (*nFail)++; 620 status = 0; 621 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 622 fileName); 623 continue; 624 } 625 if(strValue==NULL) { 626 (*nFail)++; 627 status = 0; 628 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 629 fileName); 630 continue; 631 } 632 633 // Not all lines will have comments, so NULL is ok. 634 strComment = getToken(&linePtr,"~", &status); 635 if(status) { 636 (*nFail)++; 637 status = 0; 638 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 639 fileName); 640 continue; 641 } 642 643 // Create and add metadata item to metadata and parse values 644 switch (mdType) { 645 case PS_META_STR: 646 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 647 mdType | flags, 648 strComment, strValue); 649 break; 650 case PS_META_VEC: 651 tempVec = parseVector(strValue, vecType, &status); 652 if(!status) { 653 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName+1, 654 mdType | flags, 655 strComment, tempVec); 656 } else { 657 status = 0; 658 (*nFail)++; 659 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 660 strType, lineCount, fileName); 661 continue; 662 } 663 psFree(tempVec); 664 break; 665 case PS_META_BOOL: 666 tempBool = parseBool(strValue, &status); 667 if(!status) { 668 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 669 mdType | flags, 670 strComment, tempBool); 671 } else { 672 status = 0; 673 (*nFail)++; 674 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 675 strType, lineCount, fileName); 676 continue; 677 } 678 break; 679 case PS_META_S32: 680 tempInt = (psS32)parseValue(strValue, &status); 681 if(!status) { 682 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 683 mdType | flags, 684 strComment, tempInt); 685 } else { 686 status = 0; 687 (*nFail)++; 688 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 689 strType, lineCount, fileName); 690 continue; 691 } 692 break; 693 case PS_META_F32: 694 case PS_META_F64: 695 tempDbl = parseValue(strValue, &status); 696 if(!status) { 697 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 698 mdType | flags, 699 strComment, tempDbl); 700 } else { 701 status = 0; 702 (*nFail)++; 703 psError(PS_ERR_IO, true, 704 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount, 705 fileName); 706 continue; 707 } 708 break; 709 default: 710 (*nFail)++; 711 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount, 712 fileName); 713 continue; 714 } // switch 715 if (! addStatus) { 716 (*nFail)++; 717 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount, 718 fileName); 719 } 720 721 } // if ignoreLine 722 } // while loop 723 1123 1124 if(!parseLine(&nestingLevel,parseLevelInfoArray,linePtr,lineCount,(char*)fileName,overwrite)) { 1125 (*nFail)++; 1126 } 1127 } 1128 1129 // Free parse array and line buffer 1130 psFree(parseLevelInfoArray); 724 1131 psFree(line); 725 1132 1133 // Check if any failed lined detected 1134 if( (*nFail) != 0) { 1135 psFree(md); 1136 md = NULL; 1137 } 726 1138 return md; 727 1139 } 1140 728 1141 729 1142 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts) … … 750 1163 751 1164 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 752 psTagName = psStringCopy( (const char*)tagName);1165 psTagName = psStringCopy(tagName); 753 1166 754 1167 // Metadata containter for housing element attributes used by other SAX events … … 774 1187 775 1188 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 776 psAttName = psStringCopy( (const char*)attName);777 psAttValue = psStringCopy( (const char*)attValue);1189 psAttName = psStringCopy(attName); 1190 psAttValue = psStringCopy(attValue); 778 1191 psHashAdd(htAtts, psAttName, psAttValue); 779 1192 psFree(psAttName); … … 1082 1495 1083 1496 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 1084 psEndTagName = psStringCopy( (const char*)tagName);1497 psEndTagName = psStringCopy(tagName); 1085 1498 1086 1499 // Compare start and end tag names
Note:
See TracChangeset
for help on using the changeset viewer.
