Changeset 2521 for trunk/psLib/src/xml/psXML.c
- Timestamp:
- Nov 29, 2004, 2:29:06 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/xml/psXML.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/xml/psXML.c
r2318 r2521 9 9 * @author Ross Harman, MHPCC 10 10 * 11 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-11- 10 18:26:46$11 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-11-30 00:27:40 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 15 */ 16 16 17 #include <libxml/parser.h> 17 18 #include <fitsio.h> 18 19 #include <string.h> … … 32 33 #include "psAstronomyErrors.h" 33 34 35 36 typedef struct 37 { 38 int y; 39 } 40 myStruct; 34 41 35 42 /******************************************************************************/ … … 103 110 /*****************************************************************************/ 104 111 112 void p_saxEndElement(void *ctx, const xmlChar *tagName); 113 void p_psInitVectorXml(void *ctx, char *tagName); 114 void p_psInitMetadataItemXml(void *ctx, char *tagName); 115 void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts); 105 116 106 117 /** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string … … 329 340 break; 330 341 default: 331 psError(PS_ERR_BAD_PARAMETER_TYPE,true, 332 PS_ERRORTEXT_psMetadata_METATYPE_INVALID, 333 (int)type); 342 psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)type); 334 343 } 335 344 } … … 680 689 return failedLines; 681 690 } 691 692 void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts) 693 { 694 psU64 i = 0; 695 psU64 lineNumber = 0; 696 char* psTagName = NULL; 697 char *psAttName = NULL; 698 char *psAttValue = NULL; 699 const xmlChar *attName = NULL; 700 const xmlChar *attValue = NULL; 701 psMetadata* md = NULL; 702 psHash* htAtts = NULL; 703 xmlParserCtxtPtr ctxt = NULL; 704 xmlParserInputPtr input = NULL; 705 706 707 // Get and check initial data pointers 708 ctxt = (xmlParserCtxtPtr)ctx; 709 PS_PTR_CHECK_NULL_GENERAL(ctxt, return); 710 md = (psMetadata*)ctxt->sax->_private; 711 PS_PTR_CHECK_NULL_GENERAL(md, return); 712 input = (xmlParserInputPtr)ctxt->input; 713 PS_PTR_CHECK_NULL_GENERAL(input, return); 714 715 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 716 psTagName = psStringCopy(tagName); 717 718 // Metadata containter for housing element attributes used by other SAX events 719 htAtts = psHashAlloc(10); 720 721 // Get tag name 722 if(psTagName != NULL) { 723 psHashAdd(htAtts, "tagName", psTagName); 724 } else { 725 PS_PTR_CHECK_NULL_GENERAL(psTagName, return); 726 psFree(htAtts); 727 psFree(psTagName); 728 return; 729 } 730 731 // Get all attribute names and attribute values 732 if(atts != NULL) { 733 attName = atts[i++]; 734 attValue = atts[i++]; 735 while(attName != NULL) { 736 if(attValue != NULL) { 737 738 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 739 psAttName = psStringCopy(attName); 740 psAttValue = psStringCopy(attValue); 741 psHashAdd(htAtts, psAttName, psAttValue); 742 psFree(psAttName); 743 psFree(psAttValue); 744 } else { 745 PS_PTR_CHECK_NULL_GENERAL(psAttValue, return); 746 psFree(htAtts); 747 psFree(psTagName); 748 return; 749 } 750 attName = atts[i++]; 751 attValue = atts[i++]; 752 } 753 } 754 755 // Add attributes to metadata 756 psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_META_HASH, NULL, htAtts); 757 758 psFree(psTagName); 759 760 return; 761 } 762 763 void p_psInitMetadataItemXml(void *ctx, char *tagName) 764 { 765 psBool overwrite = false; 766 psBool tempBool = false; 767 psS32 status = 0; 768 psU64 lineNumber = 0; 769 psF64 tempDbl = 0.0; 770 psS32 tempInt = 0.0; 771 psElemType elemType; 772 psMetadataType mdType; 773 char *fileName = NULL; 774 char *strName = NULL; 775 char *strType = NULL; 776 char *strValue = NULL; 777 psMetadata* md = NULL; 778 psHash* htAtts = NULL; 779 psMetadataItem *metadataItem = NULL; 780 xmlParserCtxtPtr ctxt = NULL; 781 xmlParserInputPtr input = NULL; 782 783 784 // Get and check initial data pointers 785 ctxt = (xmlParserCtxtPtr)ctx; 786 PS_PTR_CHECK_NULL_GENERAL(ctxt, return); 787 md = (psMetadata*)ctxt->sax->_private; 788 PS_PTR_CHECK_NULL_GENERAL(md, return); 789 input = (xmlParserInputPtr)ctxt->input; 790 PS_PTR_CHECK_NULL_GENERAL(input, return); 791 metadataItem = psMetadataLookup(md, "htAtts"); 792 PS_PTR_CHECK_NULL_GENERAL(metadataItem, return); 793 PS_PTR_CHECK_NULL_GENERAL(metadataItem->items, return); 794 psListSetIterator(metadataItem->items, PS_LIST_TAIL); 795 metadataItem = (psMetadataItem*)psListGetCurrent(metadataItem->items); 796 htAtts = (psHash*)metadataItem->data.V; 797 PS_PTR_CHECK_NULL_GENERAL(htAtts, return); 798 fileName = (char*)input->filename; 799 PS_PTR_CHECK_NULL_GENERAL(fileName, return); 800 lineNumber = input->line; 801 802 // Get attribute name 803 strName = psHashLookup(htAtts, "name"); 804 if(strName == NULL) { 805 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName); 806 return; 807 } 808 809 // Get attribute type, if there is one 810 strType = psHashLookup(htAtts, "psType"); 811 if(strType!= NULL) { 812 if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) { 813 mdType = PS_META_STR; 814 elemType = PS_TYPE_PTR; 815 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) { 816 mdType = PS_META_BOOL; 817 elemType = PS_TYPE_U8; 818 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) { 819 mdType = PS_META_S32; 820 elemType = PS_TYPE_S32; 821 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) { 822 mdType = PS_META_F32; 823 elemType = PS_TYPE_F32; 824 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) { 825 mdType = PS_META_F64; 826 elemType = PS_TYPE_F64; 827 } else { 828 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber, 829 fileName); 830 return; 831 } 832 } 833 834 // Get attribute value, if there is one 835 strValue = psHashLookup(htAtts, "value"); 836 837 /* If metadata item is found, and is not a folder node, and overwrite is allowed, then remove 838 existing and allow switch/case below to add new item. If overwrite is false, then report error. If 839 found item is folder node, then psMetadataAdd will automatically add a new child. */ 840 metadataItem = psMetadataLookup(md, "overwrite"); 841 if(metadataItem != NULL) { 842 overwrite = parseBool((char*)strValue, &status); 843 if(status) { 844 status = 0; 845 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 846 lineNumber, fileName); 847 } 848 metadataItem = psMetadataLookup(md, strName); 849 if(metadataItem != NULL) { 850 if(metadataItem->type != PS_META_ITEM_SET) { 851 if(overwrite) { 852 psMetadataRemove(md, PS_LIST_UNKNOWN, strName); 853 } else { 854 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber, 855 fileName); 856 return; 857 } 858 } 859 } 860 } 861 862 // Create metadata item and add to metadata 863 switch(mdType) { 864 case PS_META_ITEM_SET: 865 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, NULL); 866 break; 867 case PS_META_BOOL: 868 tempBool = parseBool((char*)strValue, &status); 869 if(!status) { 870 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempBool); 871 } else { 872 status = 0; 873 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 874 lineNumber, fileName); 875 } 876 break; 877 case PS_META_S32: 878 tempInt = (psS32)parseValue((char*)strValue, &status); 879 if(!status) { 880 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempInt); 881 } else { 882 status = 0; 883 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 884 lineNumber, fileName); 885 } 886 break; 887 case PS_META_F32: 888 case PS_META_F64: 889 tempDbl = parseValue((char*)strValue, &status); 890 if(!status) { 891 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, tempDbl); 892 } else { 893 status = 0; 894 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 895 lineNumber, fileName); 896 } 897 break; 898 case PS_META_STR: 899 psMetadataAdd(md, PS_LIST_TAIL, strName, mdType, NULL, strValue); 900 break; 901 default: 902 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName); 903 } // End switch 904 905 return; 906 } 907 908 909 void p_psInitVectorXml(void *ctx, char *tagName) 910 { 911 bool overwrite = false; 912 psS32 status = 0; 913 psU64 lineNumber = 0; 914 psElemType elemType; 915 psMetadataType mdType; 916 char *strName = NULL; 917 char *strType = NULL; 918 char *strValue = NULL; 919 char *fileName = NULL; 920 psMetadataItem *table = NULL; 921 psMetadataItem *tables = NULL; 922 psMetadataItem *metadataItem = NULL; 923 psVector *vec = NULL; 924 psMetadata* md = NULL; 925 psHash* htAtts = NULL; 926 xmlParserCtxtPtr ctxt = NULL; 927 xmlParserInputPtr input = NULL; 928 929 930 // Get and check initial data pointers 931 ctxt = (xmlParserCtxtPtr)ctx; 932 PS_PTR_CHECK_NULL_GENERAL(ctxt, return); 933 md = (psMetadata*)ctxt->sax->_private; 934 PS_PTR_CHECK_NULL_GENERAL(md, return); 935 input = (xmlParserInputPtr)ctxt->input; 936 PS_PTR_CHECK_NULL_GENERAL(input, return); 937 tables = psMetadataLookup(md, "htAtts"); 938 PS_PTR_CHECK_NULL_GENERAL(tables, return); 939 PS_PTR_CHECK_NULL_GENERAL(tables->items, return); 940 psListSetIterator(tables->items, PS_LIST_TAIL); 941 table = (psMetadataItem*)psListGetCurrent(tables->items); 942 htAtts = (psHash*)table->data.V; 943 PS_PTR_CHECK_NULL_GENERAL(htAtts, return); 944 fileName = (char*)input->filename; 945 PS_PTR_CHECK_NULL_GENERAL(fileName, return); 946 lineNumber = input->line; 947 948 // Get attribute name 949 strName = psHashLookup(htAtts, "name"); 950 if(strName == NULL) { 951 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName); 952 return; 953 } 954 955 // Get attribute type, if there is one 956 strType = psHashLookup(htAtts, "psType"); 957 if(strType!= NULL) { 958 if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) { 959 mdType = PS_META_STR; 960 elemType = PS_TYPE_PTR; 961 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) { 962 mdType = PS_META_BOOL; 963 elemType = PS_TYPE_U8; 964 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) { 965 mdType = PS_META_S32; 966 elemType = PS_TYPE_S32; 967 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) { 968 mdType = PS_META_F32; 969 elemType = PS_TYPE_F32; 970 } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) { 971 mdType = PS_META_F64; 972 elemType = PS_TYPE_F64; 973 } else { 974 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber, 975 fileName); 976 return; 977 } 978 } 979 980 strValue = psHashLookup(htAtts, "value"); 981 PS_PTR_CHECK_NULL_GENERAL(strValue, return); 982 983 984 /* If metadata item is found, and is not a folder node, and overwrite is allowed, then remove 985 existing and allow switch/case below to add new item. If overwrite is false, then report error. If 986 found item is folder node, then psMetadataAdd will automatically add a new child. */ 987 metadataItem = psMetadataLookup(md, "overwrite"); 988 if(metadataItem != NULL) { 989 overwrite = parseBool((char*)strValue, &status); 990 if(status) { 991 status = 0; 992 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 993 input->line, input->filename); 994 } 995 metadataItem = psMetadataLookup(md, strName); 996 if(metadataItem != NULL) { 997 if(metadataItem->type != PS_META_ITEM_SET) { 998 if(overwrite) { 999 psMetadataRemove(md, PS_LIST_UNKNOWN, strName); 1000 } else { 1001 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber, 1002 fileName); 1003 return; 1004 } 1005 } 1006 } 1007 } 1008 1009 // Get value 1010 vec = parseVector((char*)strValue, elemType, &status); 1011 if(!status) { 1012 psMetadataAdd(md, PS_LIST_TAIL, strName+1, mdType, NULL, vec); 1013 } else { 1014 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, 1015 lineNumber, fileName); 1016 } 1017 psFree(vec); 1018 } 1019 1020 void saxEndElement(void *ctx, const xmlChar *tagName) 1021 { 1022 psU64 lineNumber = 0; 1023 char *psStartTagName = NULL; 1024 char *psEndTagName = NULL; 1025 psMetadataType mdType; 1026 psMetadata* md = NULL; 1027 psHash* htAtts = NULL; 1028 psMetadataItem *table = NULL; 1029 psMetadataItem *tables = NULL; 1030 xmlParserCtxtPtr ctxt = NULL; 1031 xmlParserInputPtr input = NULL; 1032 1033 1034 // Get and check initial data pointers 1035 ctxt = (xmlParserCtxtPtr)ctx; 1036 PS_PTR_CHECK_NULL_GENERAL(ctxt, return); 1037 md = (psMetadata*)ctxt->sax->_private; 1038 PS_PTR_CHECK_NULL_GENERAL(md, return); 1039 input = (xmlParserInputPtr)ctxt->input; 1040 PS_PTR_CHECK_NULL_GENERAL(input, return); 1041 tables = psMetadataLookup(md, "htAtts"); 1042 PS_PTR_CHECK_NULL_GENERAL(tables, return); 1043 PS_PTR_CHECK_NULL_GENERAL(tables->items, return); 1044 psListSetIterator(tables->items, PS_LIST_TAIL); 1045 table = (psMetadataItem*)psListGetCurrent(tables->items); 1046 htAtts = (psHash*)table->data.V; 1047 PS_PTR_CHECK_NULL_GENERAL(htAtts, return); 1048 1049 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 1050 psEndTagName = psStringCopy(tagName); 1051 1052 // Compare start and end tag names 1053 psStartTagName = psHashLookup(htAtts, "tagName"); 1054 PS_PTR_CHECK_NULL_GENERAL(psStartTagName, return); 1055 if(strcmp(psEndTagName, psStartTagName)) { 1056 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName); 1057 } 1058 1059 // Initialize psLib structs 1060 if(!strcmp(psEndTagName, "psMetadataItem")) { 1061 p_psInitMetadataItemXml(ctx, psEndTagName); 1062 } else if(!strcmp(psEndTagName, "psVector")) { 1063 p_psInitVectorXml(ctx, psEndTagName); 1064 } else if(strcmp(psEndTagName, "psRoot")) { 1065 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName); 1066 } 1067 1068 // Free temporary metadata item and its hash table 1069 psListRemove(tables->items, PS_LIST_TAIL, table); 1070 1071 psFree(psEndTagName); 1072 1073 return; 1074 } 1075 1076 psS32 psMetadataParseConfigXml(psMetadata** md, const char *fileName) 1077 { 1078 psS32 status = 0; 1079 FILE *fp = NULL; 1080 xmlSAXHandler saxHandler; 1081 1082 1083 // Error checks 1084 PS_PTR_CHECK_NULL(fileName,-1); 1085 1086 // Allocate metadata if necessary 1087 if (*md == NULL) { 1088 *md = psMetadataAlloc(); 1089 } 1090 1091 // Sax handler initializations 1092 saxHandler.internalSubset = NULL; 1093 saxHandler.isStandalone = NULL; 1094 saxHandler.hasInternalSubset = NULL; 1095 saxHandler.hasExternalSubset = NULL; 1096 saxHandler.resolveEntity = NULL; 1097 saxHandler.getEntity = NULL; 1098 saxHandler.entityDecl = NULL; 1099 saxHandler.notationDecl = NULL; 1100 saxHandler.attributeDecl = NULL; 1101 saxHandler.elementDecl = NULL; 1102 saxHandler.unparsedEntityDecl = NULL; 1103 saxHandler.setDocumentLocator = NULL; 1104 saxHandler.startDocument = NULL; 1105 saxHandler.endDocument = NULL; 1106 saxHandler.startElement = saxStartElement; 1107 saxHandler.endElement = saxEndElement; 1108 saxHandler.reference = NULL; 1109 saxHandler.characters = NULL; 1110 saxHandler.ignorableWhitespace = NULL; 1111 saxHandler.processingInstruction = NULL; 1112 saxHandler.comment = NULL; 1113 saxHandler.warning = xmlParserError; 1114 saxHandler.error = xmlParserError; 1115 saxHandler.fatalError = xmlParserError; 1116 saxHandler.getParameterEntity = NULL; 1117 saxHandler.cdataBlock = NULL; 1118 saxHandler.externalSubset = NULL; 1119 saxHandler.initialized = 1; 1120 saxHandler._private = *md; 1121 saxHandler.startElementNs = NULL; 1122 saxHandler.endElementNs = NULL; 1123 saxHandler.serror = NULL; 1124 1125 // Parse XML file 1126 if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) { 1127 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName); 1128 return -1; 1129 } 1130 1131 // Parser and memory cleanups for libxml2 1132 xmlCleanupParser(); 1133 xmlMemoryDump(); 1134 1135 return 0; 1136 }
Note:
See TracChangeset
for help on using the changeset viewer.
