Changeset 68917 in vbox
- Timestamp:
- Sep 28, 2017 4:09:25 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 118180
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ovfreader.h
r65066 r68917 23 23 #include "iprt/cpp/xml.h" 24 24 #include <map> 25 #include <vector> 25 26 26 27 namespace ovf … … 492 493 struct VirtualSystem; 493 494 494 typedef std::map<uint32_t, VirtualHardwareItem> HardwareItemsMap; 495 496 /** 497 * VirtualHardwareItem pointer vector with safe cleanup. 498 * 499 * We need to use object pointers because we also want EthernetPortItem and 500 * StorageItems to go into the container. 501 */ 502 class HardwareItemVector : public std::vector<VirtualHardwareItem *> 503 { 504 public: 505 HardwareItemVector() : std::vector<VirtualHardwareItem *>() { } 506 ~HardwareItemVector() 507 { 508 for (iterator it = begin(); it != end(); ++it) 509 delete(*it); 510 clear(); 511 } 512 513 /* There is no copying of this vector. We'd need something like shared_ptr for that. */ 514 private: 515 HardwareItemVector(const VirtualSystem &); 516 517 }; 495 518 496 519 struct HardDiskController … … 564 587 // VMware Workstation 6.5 is "vmx-07" 565 588 566 HardwareItem sMap mapHardwareItems; // map of virtual hardware items, sorted by unique instance ID589 HardwareItemVector vecHardwareItems; //< vector containing all virtual hardware items in parsing order. 567 590 568 591 uint64_t ullMemorySize; // always in bytes, copied from llHardwareItems; default = 0 (unspecified) -
trunk/src/VBox/Main/xml/ovfreader.cpp
r65088 r68917 18 18 */ 19 19 20 #define LOG_GROUP LOG_GROUP_MAIN_APPLIANCE 20 21 #include "ovfreader.h" 22 #include <VBox/log.h> 23 #include <vector> 21 24 22 25 using namespace std; 23 26 using namespace ovf; 27 28 24 29 25 30 //////////////////////////////////////////////////////////////////////////////// … … 325 330 void OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSystem) 326 331 { 327 VirtualSystem vsys; 332 /* Create a new virtual system and work directly on the list copy. */ 333 m_llVirtualSystems.push_back(VirtualSystem()); 334 VirtualSystem &vsys = m_llVirtualSystems.back(); 328 335 329 336 // peek under the <VirtualSystem> node whether we have a <vbox:Machine> node; … … 412 419 } 413 420 421 /* Parse the items into the hardware item vector. */ 414 422 { 415 xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "Item"); // all "Item" child elements 423 std::map<uint32_t, const VirtualHardwareItem *> mapHardwareItems; 424 xml::NodesLoop childrenIterator(*pelmThis); 416 425 const xml::ElementNode *pelmItem; 417 while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))426 while ((pelmItem = childrenIterator.forAllNodes()) != NULL) 418 427 { 419 VirtualHardwareItem i; 420 421 i.ulLineNumber = pelmItem->getLineNumber(); 422 i.fillItem(pelmItem); 423 try{ 424 i.checkConsistencyAndCompliance(); 428 /* Parse according to type. */ 429 VirtualHardwareItem *pItem; 430 const char *pszName = pelmItem->getName(); 431 if (RTStrCmp(pszName, "Item") == 0) 432 pItem = new VirtualHardwareItem(); 433 else if (RTStrCmp(pszName, "StorageItem") == 0) 434 pItem = new StorageItem(); 435 else if (RTStrCmp(pszName, "EthernetPortItem") == 0) 436 pItem = new EthernetPortItem(); 437 else 438 continue; 439 vsys.vecHardwareItems.push_back(pItem); 440 pItem->ulLineNumber = pelmItem->getLineNumber(); 441 pItem->fillItem(pelmItem); 442 443 /* validate */ 444 try 445 { 446 pItem->checkConsistencyAndCompliance(); 425 447 } 426 448 catch (OVFLogicError &e) 427 449 { 428 throw OVFLogicError(N_("Error reading \"%s\": \"%s\""), 429 m_strPath.c_str(), 430 e.what()); 450 throw OVFLogicError(N_("Error reading \"%s\": \"%s\""), m_strPath.c_str(), e.what()); 431 451 } 432 452 433 // store! 434 vsys.mapHardwareItems[i.ulInstanceID] = i; 435 } 436 } 437 438 { 439 xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "StorageItem");// all "StorageItem" child elements 440 const xml::ElementNode *pelmItem; 441 while ((pelmItem = loopVirtualHardwareItems.forAllNodes())) 442 { 443 StorageItem i; 444 445 i.ulLineNumber = pelmItem->getLineNumber(); 446 i.fillItem(pelmItem); 447 448 try 453 /* Add to mapping vector (for parent ID lookups) if it has a valid instance ID. */ 454 if (pItem->ulInstanceID != 0) 449 455 { 450 i.checkConsistencyAndCompliance(); 456 std::map<uint32_t, const VirtualHardwareItem *>::const_iterator itDup; 457 itDup = mapHardwareItems.find(pItem->ulInstanceID); 458 if (itDup == mapHardwareItems.end()) 459 mapHardwareItems[pItem->ulInstanceID] = pItem; 460 else 461 #if 1 462 LogRel(("OVFREADER: Warning reading '%s'! Duplicate ulInstanceID %u on line %u, previous at %u!\n", 463 m_strPath.c_str(), pItem->ulInstanceID, pItem->ulLineNumber, itDup->second->ulLineNumber)); 464 #else 465 throw OVFLogicError(N_("Error reading '%s': Duplicate ulInstanceID %u on line %u, previous at %u"), 466 m_strPath.c_str(), pItem->ulInstanceID, 467 pItem->ulLineNumber, itDup->second->ulLineNumber); 468 #endif 451 469 } 452 catch (OVFLogicError &e)453 {454 throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),455 m_strPath.c_str(),456 e.what());457 }458 459 vsys.mapHardwareItems[i.ulInstanceID] = i;460 }461 }462 463 {464 xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "EthernetPortItem");// all "EthernetPortItem" child elements465 const xml::ElementNode *pelmItem;466 while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))467 {468 EthernetPortItem i;469 470 i.ulLineNumber = pelmItem->getLineNumber();471 i.fillItem(pelmItem);472 473 try{474 i.checkConsistencyAndCompliance();475 }476 catch (OVFLogicError &e)477 {478 throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),479 m_strPath.c_str(),480 e.what());481 }482 483 vsys.mapHardwareItems[i.ulInstanceID] = i;484 470 } 485 471 } … … 490 476 // in this first loop we handle all items _except_ hard disk images, 491 477 // which we'll handle in a second loop below 492 HardwareItemsMap::const_iterator itH; 493 for (itH = vsys.mapHardwareItems.begin(); 494 itH != vsys.mapHardwareItems.end(); 495 ++itH) 478 HardwareItemVector::const_iterator itH; 479 for (itH = vsys.vecHardwareItems.begin(); itH != vsys.vecHardwareItems.end(); ++itH) 496 480 { 497 const VirtualHardwareItem &i = itH->second;481 const VirtualHardwareItem &i = **itH; 498 482 499 483 // do some analysis … … 719 703 // hard disk images; otherwise the code would fail if a hard 720 704 // disk image appears in the OVF before its hard disk controller 721 for (itH = vsys.mapHardwareItems.begin(); 722 itH != vsys.mapHardwareItems.end(); 723 ++itH) 705 for (itH = vsys.vecHardwareItems.begin(); itH != vsys.vecHardwareItems.end(); ++itH) 724 706 { 725 const VirtualHardwareItem &i = itH->second;707 const VirtualHardwareItem &i = **itH; 726 708 727 709 // do some analysis … … 817 799 } 818 800 } 819 820 // now create the virtual system821 m_llVirtualSystems.push_back(vsys);822 801 } 823 802 … … 835 814 else if (!strcmp(pcszItemChildName, "ElementName")) 836 815 strElementName = pelmItemChild->getValue(); 837 else if ((!strcmp(pcszItemChildName, "InstanceID")) 838 ||(!strcmp(pcszItemChildName, "InstanceId")) 839 ) 816 else if ( !strcmp(pcszItemChildName, "InstanceID") 817 || !strcmp(pcszItemChildName, "InstanceId") ) 840 818 pelmItemChild->copyValue(ulInstanceID); 841 819 else if (!strcmp(pcszItemChildName, "HostResource")) … … 902 880 { 903 881 RTCString name = getItemName(); 882 if (resourceType == 0) 883 throw OVFLogicError(N_("Empty element ResourceType under %s element, line %d. see DMTF Schema Documentation %s"), 884 name.c_str(), ulLineNumber, DTMF_SPECS_URI); 885 886 /* Don't be too uptight about the ulInstanceID value. There are OVAs out 887 there which have ulInstanceID="%iid% for memory for instance, which is 888 no good reason for not being able to process them. bugref:8997 */ 904 889 if (ulInstanceID == 0) 905 throw OVFLogicError(N_("Element InstanceID is absent under %s element, line %d. " 906 "see DMTF Schema Documentation %s"), 907 name.c_str(), ulLineNumber, DTMF_SPECS_URI); 908 if (resourceType == 0) 909 throw OVFLogicError(N_("Empty element ResourceType under %s element, line %d. " 910 "see DMTF Schema Documentation %s"), 911 name.c_str(), ulLineNumber, DTMF_SPECS_URI); 890 { 891 if ( resourceType == ResourceType_IDEController 892 || resourceType == ResourceType_OtherStorageDevice 893 || resourceType == ResourceType_ParallelSCSIHBA 894 || resourceType == ResourceType_iSCSIHBA //?? 895 || resourceType == ResourceType_IBHCA ) //?? 896 throw OVFLogicError(N_("Element InstanceID is absent under %s element, line %d. see DMTF Schema Documentation %s"), 897 name.c_str(), ulLineNumber, DTMF_SPECS_URI); 898 else 899 LogRel(("OVFREADER: Warning: Ignoring missing or invalid ulInstanceID under element %s, line %u\n", 900 name.c_str(), ulLineNumber)); 901 } 912 902 } 913 903
Note:
See TracChangeset
for help on using the changeset viewer.