Generic hardware access library
/home/cschwick/hal/generic/src/common/DOMToVMEMapConverter.cc
Go to the documentation of this file.
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 }