Coverage for libs/sm/metadata.py: 54%
87 statements
« prev ^ index » next coverage.py v7.3.2, created at 2026-07-10 07:59 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2026-07-10 07:59 +0000
1#
2# Copyright (C) Citrix Systems Inc.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU Lesser General Public License as published
6# by the Free Software Foundation; version 2.1 only.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Lesser General Public License for more details.
12#
13# You should have received a copy of the GNU Lesser General Public License
14# along with this program; if not, write to the Free Software Foundation, Inc.,
15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16#
17# Metadata VDI format
18#
20from xml.dom import minidom, Node
21import struct
22import sys
23import string
24from sm.core import util
26HDR_STRING = "XSSM"
27STRUCT_FMT = "%dsIHH" % len(HDR_STRING)
28STRUCT_SIZE = struct.calcsize(STRUCT_FMT)
29MD_MAJOR = 1
30MD_MINOR = 2
31XML_TAG = "SRMetadata"
34def buildHeader(len):
35 output = struct.pack(STRUCT_FMT, \
36 HDR_STRING, \
37 len, \
38 MD_MAJOR, \
39 MD_MINOR)
40 return output
43def unpackHeader(input):
44 return struct.unpack(STRUCT_FMT, input)
47def _testHdr(hdr):
48 assert(hdr[0] == HDR_STRING)
49 assert(hdr[2] <= MD_MAJOR)
50 assert(hdr[3] <= MD_MINOR)
53def unpackBody(input, len):
54 return struct.unpack("%ds" % len, input)
57def _generateXMLloop(Dict, e, dom):
58 for key in Dict.keys():
59 entry = dom.createElement(key)
60 e.appendChild(entry)
61 if not isinstance(Dict[key], dict):
62 textnode = dom.createTextNode(str(Dict[key]))
63 entry.appendChild(textnode)
64 else:
65 _generateXMLloop(Dict[key], entry, dom)
68def _generateXML(Dict):
69 dom = minidom.Document()
70 md = dom.createElement(XML_TAG)
71 dom.appendChild(md)
73 _generateXMLloop(Dict, md, dom)
74 return dom.toprettyxml()
77def _walkXML(parent):
78 Dict = {}
80 if not parent.hasChildNodes():
81 if parent.nodeValue is None: 81 ↛ 84line 81 didn't jump to line 84, because the condition on line 81 was never false
82 return ''
84 for node in parent.childNodes:
85 if node.nodeType == Node.ELEMENT_NODE:
86 # Print the element name
87 Dict[util.to_plain_string(node.nodeName)] = ""
89 # Walk over any text nodes in the current node
90 content = []
91 for child in node.childNodes:
92 if child.nodeType == Node.TEXT_NODE and \
93 child.nodeValue.strip():
94 content.append(child.nodeValue.strip())
95 if content:
96 strContent = ''.join(content)
97 Dict[util.to_plain_string(node.nodeName)] = util.to_plain_string(strContent)
98 else:
99 # Walk the child nodes
100 Dict[util.to_plain_string(node.nodeName)] = _walkXML(node)
102 return Dict
105def _parseXML(str):
106 dom = minidom.parseString(str)
107 objectlist = dom.getElementsByTagName(XML_TAG)[0]
108 Dict = _walkXML(objectlist)
109 return Dict
112def buildOutput(Dict):
113 xmlstr = _generateXML(Dict)
114 XML = struct.pack("%ds" % len(xmlstr), xmlstr)
115 HDR = buildHeader(len(XML) + STRUCT_SIZE)
116 return HDR + XML
119def retrieveXMLfromFile(path):
120 try:
121 f = open(path, "rb")
122 s = f.read(STRUCT_SIZE)
123 assert(len(s) == STRUCT_SIZE)
124 hdr = unpackHeader(s)
125 _testHdr(hdr)
126 xmllen = hdr[1] - STRUCT_SIZE
127 s = f.read(xmllen)
128 assert(len(s) == xmllen)
129 XML = unpackBody(s, xmllen)
130 return XML[0]
132 finally:
133 f.close()
136def writeXMLtoFile(path, dict):
137 f = open(path, "wb")
138 f.write(buildOutput(dict))
139 f.close()
142def main():
143 path = sys.argv[1]
144 xml = retrieveXMLfromFile(path)
145 print(xml)
146 print(_parseXML(xml))
148if __name__ == '__main__': 148 ↛ 149line 148 didn't jump to line 149, because the condition on line 148 was never true
149 main()