Generic hardware access library
|
00001 #include "hal/DOMToVMEMapConverter.hh" 00002 #include <sstream> 00003 #include <iomanip> 00004 00005 using namespace XERCES_CPP_NAMESPACE; 00006 00007 void HAL::DOMToVMEMapConverter::convert( DOMDocument* doc, 00008 std::list<HAL::AddressTableItem*>& itemPointerList ) 00009 throw ( HAL::XMLProcessingException ) { 00010 00011 DOMNodeList* l = doc->getElementsByTagName(XMLString::transcode("CARD_TYPE")); 00012 if ( l->getLength() != 1 ) { 00013 std::string text = "There is not exactly one CARD_TYPE node in the DOM\n (HAL::DOMToVMEMapConverter::convert)"; 00014 throw( HAL::XMLProcessingException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00015 } 00016 DOMNodeList* itemList = doc->getElementsByTagName( XMLString::transcode("VME_ADDRESS") ); 00017 if ( itemList->getLength() == 0 ) { 00018 itemList = doc->getElementsByTagName( XMLString::transcode("VME64X_ADDRESS") ); 00019 } 00020 DOMNode* item; 00021 for (uint32_t i=0; i<itemList->getLength(); i++) { 00022 item = itemList->item(i); 00023 processNode(item, itemPointerList); 00024 00025 } 00026 } 00027 00028 void HAL::DOMToVMEMapConverter::processNode(DOMNode* item, 00029 std::list<HAL::AddressTableItem*>& itemPointerList) 00030 throw (HAL::XMLProcessingException) { 00031 uint32_t address, mask, am, width, windowId; 00032 std::string description(""), access, key, spaceStr; 00033 enum AddressSpace space; 00034 // Frank wants the keys as attributes:: 00035 DOMNamedNodeMap* attributes = item->getAttributes(); 00036 const XMLCh* valPtr = attributes->getNamedItem(XMLString::transcode("ITEM_NAME"))->getNodeValue(); 00037 char* xmlChar = XMLString::transcode(valPtr); 00038 key = std::string( xmlChar ); 00039 XMLString::release( &xmlChar ); 00040 00041 // all other column as subelements: 00042 findNamedChild( item, "ADDRESS", address); 00043 findNamedChild( item, "MASK", mask); 00044 00045 // separate VME from VME64x 00046 // VME64x: configuration space items do not need the MAP entry (it is ignored) 00047 // but they myst have a width item. 00048 // memory items must have a map item. The width item is not needed (ignored) 00049 // there is no AM item since the AM is determined by the host. 00050 // VME : there are no space and map entries 00051 // there must be AM and width entries 00052 bool isVme64x; 00053 if ( findNamedChild( item, "SPACE", spaceStr ) ) { 00054 isVme64x = true; 00055 if ( strcasecmp( spaceStr.c_str(), "MEMORY") == 0 ) { 00056 findNamedChild( item, "MAP", windowId); 00057 space = HAL::MEMORY; 00058 width = 4; // not used 00059 } else if ( strcasecmp( spaceStr.c_str(), "CONFIGURATION" ) == 0 ) { 00060 space = HAL::CONFIGURATION; 00061 findNamedChild( item, "WIDTH", width); 00062 windowId = 0; 00063 } else { 00064 std::string text = "Illegal Address Space: " + spaceStr + 00065 "\n (HAL::DOMToVMEMapConverter::processNode)"; 00066 throw( HAL::XMLProcessingException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00067 } 00068 am = 0; 00069 } else { 00070 isVme64x = false; 00071 windowId = 0; 00072 space = HAL::MEMORY; 00073 findNamedChild( item, "ADDRESS_MODIFIER", am); 00074 findNamedChild( item, "WIDTH", width); 00075 } 00076 00077 findNamedChild( item, "DESCRIPTION", description); 00078 findNamedChild( item, "READ_OR_WRITE", access); 00079 00080 bool isReadable, isWritable; 00081 if (access == "r") { 00082 isReadable = true; 00083 isWritable = false; 00084 } else if ( access == "w" ) { 00085 isReadable = false; 00086 isWritable = true; 00087 } else if ( access == "rw" ) { 00088 isReadable = true; 00089 isWritable = true; 00090 } else { 00091 std::string text = access + " is not an allowed access modifier\n (HAL::DOMToVMEMapConverter::processNode)"; 00092 throw( HAL::XMLProcessingException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00093 } 00094 // load the list : 00095 HAL::GeneralHardwareAddress* addressPointer; 00096 if ( isVme64x ) { 00097 addressPointer = new HAL::VME64xHardwareAddress(address, space, windowId, width); 00098 } else { 00099 addressPointer = new HAL::VMEHardwareAddress(address, am, width); 00100 } 00101 HAL::AddressTableItem* itemPointer = 00102 new HAL::AddressTableItem(key, description, *addressPointer, 00103 mask, isWritable, isReadable); 00104 itemPointerList.push_back(itemPointer); 00105 } 00106 00107 00108 void HAL::DOMToVMEMapConverter::getString( const DOMNode* node, std::string& text ) { 00109 text = ""; 00110 if ( node->hasChildNodes() ) { 00111 const XMLCh *xmlChar = node->getFirstChild()->getNodeValue(); 00112 char *textChar = XMLString::transcode(xmlChar); 00113 text = std::string(textChar); 00114 XMLString::release( &textChar ); 00115 } 00116 } 00117 00118 void HAL::DOMToVMEMapConverter::getUnsignedLong( const DOMNode* node, uint32_t& number ) { 00119 number = 0; 00120 if ( node->hasChildNodes() ) { 00121 const XMLCh* xmlChar = node->getFirstChild()->getNodeValue(); 00122 char *textChar = XMLString::transcode(xmlChar); 00123 std::istringstream text(textChar); 00124 XMLString::release( &textChar ); 00125 std::string str; 00126 text >> std::ws >> str; 00127 std::istringstream textCopy(str); 00128 if ( str[0] == '0' && ( str[1] == 'x' || str[1] == 'X' )) { 00129 textCopy.get(); 00130 textCopy.get(); 00131 textCopy >> std::hex >> number; 00132 } else { 00133 textCopy >> number; 00134 } 00135 } 00136 } 00137 00138 bool HAL::DOMToVMEMapConverter::findNamedChild( const DOMNode* node, std::string nodeName, uint32_t& value) { 00139 bool result = false; 00140 DOMNodeList* children = node->getChildNodes(); 00141 for ( uint32_t i=0; ( i<children->getLength()) && (result == false); i++ ) { 00142 XMLCh* compXmlCh = XMLString::transcode(nodeName.c_str()); 00143 if ( XMLString::equals( children->item(i)->getNodeName(), compXmlCh ) ) { 00144 result = true; 00145 getUnsignedLong( children->item(i), value ); 00146 } 00147 XMLString::release( &compXmlCh ); 00148 } 00149 return result; 00150 } 00151 00152 bool HAL::DOMToVMEMapConverter::findNamedChild( const DOMNode* node, std::string nodeName, std::string& value) { 00153 bool result = false; 00154 DOMNodeList* children = node->getChildNodes(); 00155 for ( uint32_t i=0; ( i<children->getLength()) && (result == false); i++ ) { 00156 XMLCh* compXmlCh = XMLString::transcode(nodeName.c_str()); 00157 if ( XMLString::equals( children->item(i)->getNodeName(),compXmlCh ) ) { 00158 result = true; 00159 getString( children->item(i), value ); 00160 } 00161 XMLString::release( &compXmlCh ); 00162 } 00163 return result; 00164 }