- Timestamp:
- Mar 5, 2009 4:39:39 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/xml.h
r17362 r17417 168 168 }; 169 169 170 class VBOXXML_CLASS ENodeIsNotElement : public LogicError 171 { 172 public: 173 ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {} 174 ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {} 175 }; 176 170 177 // Runtime errors 171 178 ////////////////////////////////////////////////////////////////////////////// … … 420 427 }; 421 428 422 /* 429 /** 423 430 * Node: 424 * an XML node, which represents either an element or an attribute. 431 * an XML node, which represents either an element or text content 432 * or an attribute. 425 433 * 426 434 * For elements, getName() returns the element name, and getValue() … … 435 443 * -- xml::Document::createRootElement() 436 444 * -- xml::Node::createChild() 445 * -- xml::Node::addContent() 437 446 * -- xml::Node::setAttribute() 438 447 */ … … 467 476 468 477 Node* createChild(const char *pcszElementName); 478 Node* addContent(const char *pcszContent); 469 479 Node* setAttribute(const char *pcszName, const char *pcszValue); 470 480 -
trunk/src/VBox/Main/ApplianceImpl.cpp
r17400 r17417 38 38 using namespace std; 39 39 40 // defines 40 //////////////////////////////////////////////////////////////////////////////// 41 // 42 // hardware definitions 43 // 41 44 //////////////////////////////////////////////////////////////////////////////// 42 45 … … 112 115 struct VirtualSystem; 113 116 114 // opaque private instance data of Appliance class115 struct Appliance::Data116 {117 Utf8Str strPath; // file name last given to either read() or write()118 119 DiskImagesMap mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId120 121 NetworksMap mapNetworks; // map of Network structs, sorted by Network.strNetworkName122 123 list<VirtualSystem> llVirtualSystems;124 125 list< ComObjPtr<VirtualSystemDescription> > virtualSystemDescriptions;126 };127 128 117 typedef map<uint32_t, VirtualHardwareItem> HardwareItemsMap; 129 118 … … 198 187 } 199 188 }; 189 190 //////////////////////////////////////////////////////////////////////////////// 191 // 192 // Appliance data definition 193 // 194 //////////////////////////////////////////////////////////////////////////////// 195 196 // opaque private instance data of Appliance class 197 struct Appliance::Data 198 { 199 Utf8Str strPath; // file name last given to either read() or write() 200 201 DiskImagesMap mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId 202 203 NetworksMap mapNetworks; // map of Network structs, sorted by Network.strNetworkName 204 205 list<VirtualSystem> llVirtualSystems; // list of virtual systems, created by and valid after read() 206 207 list< ComObjPtr<VirtualSystemDescription> > virtualSystemDescriptions; // 208 }; 209 210 struct VirtualSystemDescription::Data 211 { 212 list<VirtualSystemDescriptionEntry> llDescriptions; 213 list<Utf8Str> llWarnings; 214 }; 215 216 //////////////////////////////////////////////////////////////////////////////// 217 // 218 // Threads 219 // 220 //////////////////////////////////////////////////////////////////////////////// 200 221 201 222 struct Appliance::TaskImportMachines … … 2455 2476 { 2456 2477 xml::Document doc; 2457 doc.createRootElement("Envelope"); 2458 2478 xml::Node *pelmRoot = doc.createRootElement("Envelope"); 2479 2480 pelmRoot->setAttribute("ovf:version", "1.0"); 2481 pelmRoot->setAttribute("xml:lang", "en-US"); 2482 pelmRoot->setAttribute("xmlns", "http://schemas.dmtf.org/ovf/envelope/1"); 2483 pelmRoot->setAttribute("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1"); 2484 pelmRoot->setAttribute("xmlns:ovfstr", "http://schema.dmtf.org/ovf/strings/1"); 2485 pelmRoot->setAttribute("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"); 2486 pelmRoot->setAttribute("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"); 2487 pelmRoot->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 2488 pelmRoot->setAttribute("xsi:schemaLocation", "http://schemas.dmtf.org/ovf/envelope/1 ../ovf-envelope.xsd"); 2489 2490 2491 // <Envelope>/<References> 2492 xml::Node *pelmReferences = pelmRoot->createChild("References"); 2493 // @ŧodo 2494 2495 /* <Envelope>/<DiskSection>: 2496 <DiskSection> 2497 <Info>List of the virtual disks used in the package</Info> 2498 <Disk ovf:capacity="4294967296" ovf:diskId="lamp" ovf:format="http://www.vmware.com/specifications/vmdk.html#compressed" ovf:populatedSize="1924967692"/> 2499 </DiskSection> */ 2500 xml::Node *pelmDiskSection = pelmRoot->createChild("DiskSection"); 2501 xml::Node *pelmDiskSectionInfo = pelmDiskSection->createChild("Info"); 2502 pelmDiskSectionInfo->addContent("List of the virtual disks used in the package"); 2503 // @todo for each disk: 2504 // xml::Node *pelmDisk = pelmDiskSection->createChild("Disk"); 2505 2506 /* <Envelope>/<NetworkSection>: 2507 <NetworkSection> 2508 <Info>Logical networks used in the package</Info> 2509 <Network ovf:name="VM Network"> 2510 <Description>The network that the LAMP Service will be available on</Description> 2511 </Network> 2512 </NetworkSection> */ 2513 xml::Node *pelmNetworkSection = pelmRoot->createChild("NetworkSection"); 2514 xml::Node *pelmNetworkSectionInfo = pelmNetworkSection->createChild("Info"); 2515 pelmNetworkSectionInfo->addContent("Logical networks used in the package"); 2516 // @todo for each network: 2517 // xml::Node *pelmNetwork = pelmNetworkSection->createChild("Network"); 2518 2519 // and here come the virtual systems: 2520 xml::Node *pelmVirtualSystemCollection = pelmRoot->createChild("VirtualSystemCollection"); 2521 xml::Node *pattrVirtualSystemCollectionId = pelmVirtualSystemCollection->setAttribute("ovf:id", "ExportedVirtualBoxMachines"); // whatever 2522 2523 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it; 2524 /* Iterate through all virtual systems of that appliance */ 2525 for (it = pAppliance->m->virtualSystemDescriptions.begin(); 2526 it != pAppliance->m->virtualSystemDescriptions.end(); 2527 ++it) 2528 { 2529 ComObjPtr<VirtualSystemDescription> vsdescThis = (*it); 2530 2531 xml::Node *pelmVirtualSystem = pelmVirtualSystemCollection->createChild("VirtualSystem"); 2532 xml::Node *pelmVirtualSystemInfo = pelmVirtualSystem->createChild("Info"); // @todo put in description here after implementing an entry for it 2533 2534 std::list<VirtualSystemDescriptionEntry*> llName = vsdescThis->findByType(VirtualSystemDescriptionType_Name); 2535 2536 std::list<VirtualSystemDescriptionEntry*> llOS = vsdescThis->findByType(VirtualSystemDescriptionType_OS); 2537 /* <OperatingSystemSection ovf:id="82"> 2538 <Info>Guest Operating System</Info> 2539 <Description>Linux 2.6.x</Description> 2540 </OperatingSystemSection> */ 2541 xml::Node *pelmOperatingSystemSection = pelmVirtualSystem->createChild("OperatingSystemSection"); 2542 pelmOperatingSystemSection->setAttribute("ovf:id", "82"); 2543 // @todo convert vbox OS type into OVF ID 2544 pelmOperatingSystemSection->createChild("Info")->addContent("blah"); // @ŧodo 2545 pelmOperatingSystemSection->createChild("Description")->addContent("blah"); // @ŧodo 2546 2547 // <VirtualHardwareSection ovf:id="hw1" ovf:transport="iso"> 2548 xml::Node *pelmVirtualHardwareSection = pelmVirtualSystem->createChild("VirtualHardwareSection"); 2549 2550 /* <System> 2551 <vssd:Description>Description of the virtual hardware section.</vssd:Description> 2552 <vssd:ElementName>vmware</vssd:ElementName> 2553 <vssd:InstanceID>1</vssd:InstanceID> 2554 <vssd:VirtualSystemIdentifier>MyLampService</vssd:VirtualSystemIdentifier> 2555 <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType> 2556 </System> */ 2557 xml::Node *pelmSystem = pelmVirtualHardwareSection->createChild("System"); 2558 2559 // <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType> 2560 xml::Node *pelmVirtualSystemType = pelmSystem->createChild("VirtualSystemType"); 2561 pelmVirtualSystemType->addContent("virtualbox-2.2"); // instead of vmx-7? 2562 2563 uint32_t ulInstanceID = 1; 2564 2565 list<VirtualSystemDescriptionEntry>::const_iterator itD; 2566 for (itD = vsdescThis->m->llDescriptions.begin(); 2567 itD != vsdescThis->m->llDescriptions.end(); 2568 ++itD) 2569 { 2570 const VirtualSystemDescriptionEntry &desc = *itD; 2571 2572 OVFResourceType_T type = 0; // if this becomes != 0 then we do stuff 2573 Utf8Str strDescription; // must also be set then 2574 int32_t lVirtualQuantity = -1; 2575 uint64_t uTemp; 2576 2577 switch (desc.type) 2578 { 2579 case VirtualSystemDescriptionType_CPU: 2580 /* <Item> 2581 <rasd:Caption>1 virtual CPU</rasd:Caption> 2582 <rasd:Description>Number of virtual CPUs</rasd:Description> 2583 <rasd:ElementName>virtual CPU</rasd:ElementName> 2584 <rasd:InstanceID>1</rasd:InstanceID> 2585 <rasd:ResourceType>3</rasd:ResourceType> 2586 <rasd:VirtualQuantity>1</rasd:VirtualQuantity> 2587 </Item> */ 2588 strDescription = "Number of virtual CPUs"; 2589 type = OVFResourceType_Processor; // 3 2590 lVirtualQuantity = 1; 2591 break; 2592 2593 case VirtualSystemDescriptionType_Memory: 2594 /* <Item> 2595 <rasd:AllocationUnits>MegaBytes</rasd:AllocationUnits> 2596 <rasd:Caption>256 MB of memory</rasd:Caption> 2597 <rasd:Description>Memory Size</rasd:Description> 2598 <rasd:ElementName>Memory</rasd:ElementName> 2599 <rasd:InstanceID>2</rasd:InstanceID> 2600 <rasd:ResourceType>4</rasd:ResourceType> 2601 <rasd:VirtualQuantity>256</rasd:VirtualQuantity> 2602 </Item> */ 2603 strDescription = "Memory Size"; 2604 type = OVFResourceType_Memory; // 4 2605 desc.strVbox.toInt(uTemp); 2606 lVirtualQuantity = uTemp / _1M; 2607 break; 2608 2609 case VirtualSystemDescriptionType_HardDiskControllerIDE: 2610 break; 2611 case VirtualSystemDescriptionType_HardDiskControllerSATA: 2612 break; 2613 case VirtualSystemDescriptionType_HardDiskControllerSCSI: 2614 break; 2615 2616 case VirtualSystemDescriptionType_HardDiskImage: 2617 break; 2618 2619 case VirtualSystemDescriptionType_Floppy: 2620 break; 2621 2622 case VirtualSystemDescriptionType_CDROM: 2623 break; 2624 2625 case VirtualSystemDescriptionType_LogicalNetwork: 2626 break; 2627 2628 case VirtualSystemDescriptionType_NetworkAdapter: 2629 break; 2630 2631 case VirtualSystemDescriptionType_USBController: 2632 break; 2633 2634 case VirtualSystemDescriptionType_SoundCard: 2635 break; 2636 } 2637 2638 if (type) 2639 { 2640 xml::Node *pItem; 2641 pItem = pelmVirtualHardwareSection->createChild("Item"); 2642 2643 pItem->createChild("rasd:Description")->addContent(strDescription.c_str()); 2644 2645 // <rasd:InstanceID>1</rasd:InstanceID> 2646 pItem->createChild("rasd:InstanceID")->addContent(Utf8StrFmt("%d", ulInstanceID).c_str()); 2647 2648 // <rasd:ResourceType>3</rasd:ResourceType> 2649 pItem->createChild("rasd:ResourceType")->addContent(Utf8StrFmt("%d", type).c_str()); 2650 2651 // <rasd:VirtualQuantity>1</rasd:VirtualQuantity> 2652 if (lVirtualQuantity != -1) 2653 pItem->createChild("rasd:VirtualQuantity")->addContent(Utf8StrFmt("%d", lVirtualQuantity).c_str()); 2654 2655 } 2656 } 2657 } 2658 2659 // now go write the XML 2459 2660 xml::XmlFileWriter writer(doc); 2460 2661 writer.write(pAppliance->m->strPath.c_str()); … … 2481 2682 } 2482 2683 2483 #2484 2684 //////////////////////////////////////////////////////////////////////////////// 2485 2685 // … … 2490 2690 DEFINE_EMPTY_CTOR_DTOR(VirtualSystemDescription) 2491 2691 struct shutup3 {}; 2492 2493 struct VirtualSystemDescription::Data2494 {2495 list<VirtualSystemDescriptionEntry> descriptions;2496 list<Utf8Str> warnings;2497 };2498 2692 2499 2693 /** … … 2546 2740 AutoReadLock alock(this); 2547 2741 2548 *aCount = (ULONG)m-> descriptions.size();2742 *aCount = (ULONG)m->llDescriptions.size(); 2549 2743 2550 2744 return S_OK; … … 2573 2767 AutoReadLock alock(this); 2574 2768 2575 ULONG c = (ULONG)m-> descriptions.size();2769 ULONG c = (ULONG)m->llDescriptions.size(); 2576 2770 com::SafeArray<VirtualSystemDescriptionType_T> sfaTypes(c); 2577 2771 com::SafeArray<BSTR> sfaRefs(c); … … 2582 2776 list<VirtualSystemDescriptionEntry>::const_iterator it; 2583 2777 size_t i = 0; 2584 for (it = m-> descriptions.begin();2585 it != m-> descriptions.end();2778 for (it = m->llDescriptions.begin(); 2779 it != m->llDescriptions.end(); 2586 2780 ++it, ++i) 2587 2781 { … … 2631 2825 com::SafeArray<IN_BSTR> aExtraConfigValues(ComSafeArrayInArg(argExtraConfigValues)); 2632 2826 2633 if ( (aVboxValues.size() != m-> descriptions.size())2634 || (aExtraConfigValues.size() != m-> descriptions.size())2827 if ( (aVboxValues.size() != m->llDescriptions.size()) 2828 || (aExtraConfigValues.size() != m->llDescriptions.size()) 2635 2829 ) 2636 2830 return E_INVALIDARG; … … 2638 2832 list<VirtualSystemDescriptionEntry>::iterator it; 2639 2833 size_t i = 0; 2640 for (it = m-> descriptions.begin();2641 it != m-> descriptions.end();2834 for (it = m->llDescriptions.begin(); 2835 it != m->llDescriptions.end(); 2642 2836 ++it, ++i) 2643 2837 { … … 2670 2864 AutoReadLock alock(this); 2671 2865 2672 com::SafeArray<BSTR> sfaWarnings(m-> warnings.size());2866 com::SafeArray<BSTR> sfaWarnings(m->llWarnings.size()); 2673 2867 2674 2868 list<Utf8Str>::const_iterator it; 2675 2869 size_t i = 0; 2676 for (it = m-> warnings.begin();2677 it != m-> warnings.end();2870 for (it = m->llWarnings.begin(); 2871 it != m->llWarnings.end(); 2678 2872 ++it, ++i) 2679 2873 { … … 2702 2896 { 2703 2897 VirtualSystemDescriptionEntry vsde; 2704 vsde.ulIndex = (uint32_t)m-> descriptions.size(); // each entry gets an index so the client side can reference them2898 vsde.ulIndex = (uint32_t)m->llDescriptions.size(); // each entry gets an index so the client side can reference them 2705 2899 vsde.type = aType; 2706 2900 vsde.strRef = strRef; … … 2709 2903 vsde.strExtraConfig = strExtraConfig; 2710 2904 2711 m-> descriptions.push_back(vsde);2905 m->llDescriptions.push_back(vsde); 2712 2906 } 2713 2907 … … 2718 2912 Utf8StrFmtVA str(aWarning, args); 2719 2913 va_end(args); 2720 m-> warnings.push_back(str);2914 m->llWarnings.push_back(str); 2721 2915 } 2722 2916 … … 2732 2926 2733 2927 list<VirtualSystemDescriptionEntry>::iterator it; 2734 for (it = m-> descriptions.begin();2735 it != m-> descriptions.end();2928 for (it = m->llDescriptions.begin(); 2929 it != m->llDescriptions.end(); 2736 2930 ++it) 2737 2931 { … … 2754 2948 Utf8Str strRef = Utf8StrFmt("%RI32", id); 2755 2949 list<VirtualSystemDescriptionEntry>::const_iterator it; 2756 for (it = m-> descriptions.begin();2757 it != m-> descriptions.end();2950 for (it = m->llDescriptions.begin(); 2951 it != m->llDescriptions.end(); 2758 2952 ++it) 2759 2953 { … … 2877 3071 /* Memory */ 2878 3072 Utf8Str strMemory = Utf8StrFmt("%RI32", (uint64_t)ulMemSizeMB * _1M); 2879 pNewDesc->addEntry(VirtualSystemDescriptionType_ CPU,3073 pNewDesc->addEntry(VirtualSystemDescriptionType_Memory, 2880 3074 "", 2881 3075 strMemory, -
trunk/src/VBox/Main/xml/xml.cpp
r17400 r17417 411 411 struct Node::Data 412 412 { 413 xmlNode *plibNode; // != NULL if this is an element 414 xmlAttr *plibAttr; // != NULL if this is an attribute 413 xmlNode *plibNode; // != NULL if this is an element or content node 414 xmlAttr *plibAttr; // != NULL if this is an attribute node 415 415 416 416 Node *pParent; // NULL only for the root element 417 const char *pcszName; // points either into plibNode or plibAttr 417 const char *pcszName; // element or attribute name, points either into plibNode or plibAttr; 418 // NULL if this is a content node 418 419 419 420 struct compare_const_char … … 748 749 return false; 749 750 } 751 752 /** 753 * Creates a new child element node and appends it to the list 754 * of children in "this". 755 * 756 * @param pcszElementName 757 * @return 758 */ 759 Node* Node::createChild(const char *pcszElementName) 760 { 761 // we must be an element, not an attribute 762 if (!m->plibNode) 763 throw ENodeIsNotElement(RT_SRC_POS); 764 765 // libxml side: create new node 766 xmlNode *plibNode; 767 if (!(plibNode = xmlNewNode(NULL, // namespace 768 (const xmlChar*)pcszElementName))) 769 throw ENoMemory(); 770 xmlAddChild(m->plibNode, plibNode); 771 772 // now wrap this in C++ 773 Node *p = new Node; 774 boost::shared_ptr<Node> pNew(p); 775 pNew->m->plibNode = plibNode; 776 pNew->m->pcszName = (const char*)plibNode->name; 777 778 m->children.push_back(pNew); 779 780 return p; 781 } 782 783 784 /** 785 * Creates a content node and appends it to the list of children 786 * in "this". 787 * 788 * @param pcszElementName 789 * @return 790 */ 791 Node* Node::addContent(const char *pcszContent) 792 { 793 // we must be an element, not an attribute 794 if (!m->plibNode) 795 throw ENodeIsNotElement(RT_SRC_POS); 796 797 // libxml side: create new node 798 xmlNode *plibNode; 799 if (!(plibNode = xmlNewText((const xmlChar*)pcszContent))) 800 throw ENoMemory(); 801 xmlAddChild(m->plibNode, plibNode); 802 803 // now wrap this in C++ 804 Node *p = new Node; 805 boost::shared_ptr<Node> pNew(p); 806 pNew->m->plibNode = plibNode; 807 pNew->m->pcszName = NULL; 808 809 m->children.push_back(pNew); 810 811 } 812 813 /** 814 * Sets the given attribute. Assumes that "this" is an element node, 815 * otherwise ENodeIsNotElement is thrown. 816 * 817 * If an attribute with the given name exists, it is overwritten, 818 * otherwise a new attribute is created. Returns the attribute node 819 * that was either created or changed. 820 * 821 * @param pcszName 822 * @param pcszValue 823 * @return 824 */ 825 Node* Node::setAttribute(const char *pcszName, const char *pcszValue) 826 { 827 // we must be an element, not an attribute 828 if (!m->plibNode) 829 throw ENodeIsNotElement(RT_SRC_POS); 830 831 Data::AttributesMap::const_iterator it; 832 833 it = m->attribs.find(pcszName); 834 if (it == m->attribs.end()) 835 { 836 // libxml side: xmlNewProp creates an attribute 837 xmlAttr *plibAttr = xmlNewProp(m->plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue); 838 const char *pcszAttribName = (const char*)plibAttr->name; 839 840 // C++ side: create an attribute node around it 841 boost::shared_ptr<Node> pNew(new Node); 842 pNew->m->plibAttr = plibAttr; 843 pNew->m->pcszName = (const char*)plibAttr->name; 844 pNew->m->pParent = this; 845 // store 846 m->attribs[pcszAttribName] = pNew; 847 } 848 else 849 { 850 // @todo 851 throw LogicError("Attribute exists"); 852 } 853 854 return NULL; 855 856 } 857 750 858 751 859 /* … … 899 1007 Node* Document::createRootElement(const char *pcszRootElementName) 900 1008 { 901 if (m->pRootElement )1009 if (m->pRootElement || m->plibDocument) 902 1010 throw EDocumentNotEmpty(RT_SRC_POS); 903 1011 1012 // libxml side: create document, create root node 904 1013 m->plibDocument = xmlNewDoc((const xmlChar*)"1.0"); 905 if (!(m->pRootElement = new Node())) 1014 xmlNode *plibRootNode; 1015 if (!(plibRootNode = xmlNewNode(NULL, // namespace 1016 (const xmlChar*)pcszRootElementName))) 906 1017 throw ENoMemory(); 907 Node::Data *pNodeData = m->pRootElement->m; 908 if (!(pNodeData->plibNode = xmlNewNode(NULL, // namespace 909 (const xmlChar*)pcszRootElementName))) 910 throw ENoMemory(); 911 pNodeData->pcszName = (const char*)pNodeData->plibNode->name; 1018 xmlDocSetRootElement(m->plibDocument, plibRootNode); 1019 1020 // now wrap this in C++ 1021 m->pRootElement = new Node(); 1022 m->pRootElement->m->plibNode = plibRootNode; 1023 m->pRootElement->m->pcszName = (const char*)plibRootNode->name; 912 1024 913 1025 return m->pRootElement;
Note:
See TracChangeset
for help on using the changeset viewer.