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

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# 

19 

20from xml.dom import minidom, Node 

21import struct 

22import sys 

23import string 

24from sm.core import util 

25 

26HDR_STRING = "XSSM" 

27STRUCT_FMT = "%dsIHH" % len(HDR_STRING) 

28STRUCT_SIZE = struct.calcsize(STRUCT_FMT) 

29MD_MAJOR = 1 

30MD_MINOR = 2 

31XML_TAG = "SRMetadata" 

32 

33 

34def buildHeader(len): 

35 output = struct.pack(STRUCT_FMT, \ 

36 HDR_STRING, \ 

37 len, \ 

38 MD_MAJOR, \ 

39 MD_MINOR) 

40 return output 

41 

42 

43def unpackHeader(input): 

44 return struct.unpack(STRUCT_FMT, input) 

45 

46 

47def _testHdr(hdr): 

48 assert(hdr[0] == HDR_STRING) 

49 assert(hdr[2] <= MD_MAJOR) 

50 assert(hdr[3] <= MD_MINOR) 

51 

52 

53def unpackBody(input, len): 

54 return struct.unpack("%ds" % len, input) 

55 

56 

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) 

66 

67 

68def _generateXML(Dict): 

69 dom = minidom.Document() 

70 md = dom.createElement(XML_TAG) 

71 dom.appendChild(md) 

72 

73 _generateXMLloop(Dict, md, dom) 

74 return dom.toprettyxml() 

75 

76 

77def _walkXML(parent): 

78 Dict = {} 

79 

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 '' 

83 

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)] = "" 

88 

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) 

101 

102 return Dict 

103 

104 

105def _parseXML(str): 

106 dom = minidom.parseString(str) 

107 objectlist = dom.getElementsByTagName(XML_TAG)[0] 

108 Dict = _walkXML(objectlist) 

109 return Dict 

110 

111 

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 

117 

118 

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] 

131 

132 finally: 

133 f.close() 

134 

135 

136def writeXMLtoFile(path, dict): 

137 f = open(path, "wb") 

138 f.write(buildOutput(dict)) 

139 f.close() 

140 

141 

142def main(): 

143 path = sys.argv[1] 

144 xml = retrieveXMLfromFile(path) 

145 print(xml) 

146 print(_parseXML(xml)) 

147 

148if __name__ == '__main__': 148 ↛ 149line 148 didn't jump to line 149, because the condition on line 148 was never true

149 main()