1#!/usr/bin/python 2 3import sys 4from struct import * 5from xml.dom import minidom 6#s2x Runtime Error Class Definition: 7class s2xErr(Exception): 8 def __init__(self,msg): 9 self.msg=msg 10#constants start: 11#------------------------------------------------------------# 12NUMBER='\x00' 13BOOLEAN='\x01' 14STRING='\x02' 15OBJOBJ='\x03' 16NULL='\x05' 17UNDEF='\x06' 18OBJARR='\x08' 19#RAWARR='\x0A' 20OBJDATE='\x0B' 21OBJM='\x0D' 22OBJXML='\x0F' 23OBJCC='\x10' 24#constants end. 25#------------------------------------------------------------# 26argv=sys.argv 27if len(argv)<3: 28 print 's2x v 0.75 by iceeLyne, Dec., 2003.' 29 print 'usage:' 30 print 'python s2x.py -x foo.sol [foo.xml]' 31 print 'python s2x.py -s foo.xml [foo.sol]' 32else: 33 argvSw=argv[1] 34 argvInpFile=argv[2] 35 if len(argv)>3: 36 argvOutFile=argv[3] 37 else: 38 argvOutFile='' 39 if argvSw=='-x': 40 # parse sol to xml 41 try: 42 f=open(argvInpFile,'rb') 43 except IOError: 44 print 'Could Not Open The Input File: '+argvInpFile 45 else: 46 def num2x(): 47 global cparent,sVname 48 s=f.read(8) 49 if s=='\x7F\xF0\x00\x00\x00\x00\x00\x00': 50 sValue='Infinity' 51 elif s=='\xFF\xF0\x00\x00\x00\x00\x00\x00': 52 sValue='-Infinity' 53 elif s=='\x7F\xF8\x00\x00\x00\x00\x00\x00': 54 sValue='NaN' 55 else: 56 nValue,=unpack('>d',s)#Double,Big-endian 57 sValue=str(nValue) 58 c=cparent.appendChild(d.createElement('data')) 59 c.setAttribute('type','number') 60 c.setAttribute('name',sVname) 61 c.setAttribute('value',sValue) 62 def bol2x(): 63 global cparent,sVname 64 b=f.read(1) 65 if b=='\x00': 66 sValue='false' 67 elif b=='\x01': 68 sValue='true' 69 else: 70 print 'Warning: Boolean Value Error.' 71 sValue='true' 72 c=cparent.appendChild(d.createElement('data')) 73 c.setAttribute('type','boolean') 74 c.setAttribute('name',sVname) 75 c.setAttribute('value',sValue) 76 def str2x(): 77 global cparent,sVname 78 nLenStr,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 79 s=f.read(nLenStr) 80 s=s.decode('utf-8')# 81 c=cparent.appendChild(d.createElement('data')) 82 c.setAttribute('type','string') 83 c.setAttribute('name',sVname) 84 c.appendChild(d.createCDATASection(s)) 85 def obj2x(): 86 global cparent,sVname,nLenVname#is necessary 87 c=cparent.appendChild(d.createElement('data')) 88 c.setAttribute('type','object') 89 c.setAttribute('name',sVname) 90 cparent=cparent.lastChild 91 nLenVname,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 92 while nLenVname!=0: 93 sVname=f.read(nLenVname) 94 sVname=sVname.decode('utf-8')# 95 type=f.read(1) 96 if type==NUMBER: 97 num2x() 98 elif type==BOOLEAN: 99 bol2x() 100 elif type==STRING: 101 str2x() 102 elif type==OBJARR: 103 arr2x() 104 elif type==OBJOBJ: 105 obj2x() 106 elif type==OBJDATE: 107 dat2x() 108 elif type==OBJXML: 109 xml2x() 110 elif type==OBJCC: 111 occ2x() 112 elif type==OBJM: 113 ojm2x() 114 elif type==NULL: 115 nul2x() 116 elif type==UNDEF: 117 und2x() 118 else: 119 raise s2xErr('Unexpected Data Type: '+hex(ord(type))) 120 nLenVname,=unpack('>H',f.read(2)) 121 objend=f.read(1)#=='\x09' 122 cparent=cparent.parentNode 123 def arr2x(): 124 global cparent,sVname,nLenVname#is necessary 125 nArrLength,=unpack('>L',f.read(4))#Unsigned Long,Big-endian 126 c=cparent.appendChild(d.createElement('data')) 127 c.setAttribute('type','array') 128 c.setAttribute('name',sVname) 129 c.setAttribute('length',str(nArrLength)) 130 cparent=cparent.lastChild 131 nLenVname,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 132 while nLenVname!=0: 133 sVname=f.read(nLenVname) 134 sVname=sVname.decode('utf-8')# 135 type=f.read(1) 136 if type==NUMBER: 137 num2x() 138 elif type==BOOLEAN: 139 bol2x() 140 elif type==STRING: 141 str2x() 142 elif type==OBJOBJ: 143 obj2x() 144 elif type==OBJARR: 145 arr2x() 146 elif type==OBJDATE: 147 dat2x() 148 elif type==OBJXML: 149 xml2x() 150 elif type==OBJCC: 151 occ2x() 152 elif type==OBJM: 153 ojm2x() 154 elif type==NULL: 155 nul2x() 156 elif type==UNDEF: 157 und2x() 158 else: 159 raise s2xErr('Unexpected Data Type: '+hex(ord(type))) 160 nLenVname,=unpack('>H',f.read(2)) 161 objend=f.read(1)#=='\x09' 162 cparent=cparent.parentNode 163 def dat2x(): 164 global cparent,sVname 165 nMsec,=unpack('>d',f.read(8))#Double,Big-endian 166 nMinOffset,=unpack('>h',f.read(2))#Short,Big-endian 167 nOffset=nMinOffset/60 168 c=cparent.appendChild(d.createComment('DateObject:Milliseconds Count From Dec. 1, 1969; Timezone UTC + Offset.')) 169 c=cparent.appendChild(d.createElement('data')) 170 c.setAttribute('type','date') 171 c.setAttribute('name',sVname) 172 c.setAttribute('msec',str(nMsec)) 173 c.setAttribute('utcoffset',str(-nOffset)) 174 def xml2x(): 175 global cparent,sVname 176 nLenCData,=unpack('>L',f.read(4))#Unsigned Long,Big-endian 177 sCData=f.read(nLenCData) 178 sCData=sCData.decode('utf-8')# 179 c=cparent.appendChild(d.createElement('data')) 180 c.setAttribute('type','xml') 181 c.setAttribute('name',sVname) 182 c.appendChild(d.createCDATASection(sCData)) 183 def occ2x(): 184 global cparent,sVname,nLenVname#is necessary 185 nLenCname,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 186 sCname=f.read(nLenCname) 187 sCname=sCname.decode('utf-8')# 188 c=cparent.appendChild(d.createElement('data')) 189 c.setAttribute('type','c_object') 190 c.setAttribute('name',sVname) 191 c.setAttribute('class_name',sCname) 192 cparent=cparent.lastChild 193 nLenVname,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 194 while nLenVname!=0: 195 sVname=f.read(nLenVname) 196 sVname=sVname.decode('utf-8')# 197 type=f.read(1) 198 if type==NUMBER: 199 num2x() 200 elif type==BOOLEAN: 201 bol2x() 202 elif type==STRING: 203 str2x() 204 elif type==OBJARR: 205 arr2x() 206 elif type==OBJOBJ: 207 obj2x() 208 elif type==OBJDATE: 209 dat2x() 210 elif type==OBJXML: 211 xml2x() 212 elif type==OBJCC: 213 occ2x() 214 elif type==OBJM: 215 ojm2x() 216 elif type==NULL: 217 nul2x() 218 elif type==UNDEF: 219 und2x() 220 else: 221 raise s2xErr('Unexpected Data Type: '+hex(ord(type))) 222 nLenVname,=unpack('>H',f.read(2)) 223 objend=f.read(1)#=='\x09' 224 cparent=cparent.parentNode 225 def ojm2x(): 226 global cparent,sVname 227 c=cparent.appendChild(d.createElement('data')) 228 c.setAttribute('type','m_object') 229 c.setAttribute('name',sVname) 230 def nul2x(): 231 global cparent,sVname 232 c=cparent.appendChild(d.createElement('data')) 233 c.setAttribute('type','null') 234 c.setAttribute('name',sVname) 235 def und2x(): 236 global cparent,sVname 237 c=cparent.appendChild(d.createElement('data')) 238 c.setAttribute('type','undefined') 239 c.setAttribute('name',sVname) 240 d=minidom.parseString('<solx/>') 241 try: 242 f.seek(0,2) 243 nLenFile=f.tell() 244 f.seek(0) 245 sHeader=f.read(2) 246 sLenData=f.read(4) 247 nLenData,=unpack('>L',sLenData)#Unsigned Long,Big-endian 248 if nLenFile!=nLenData+6: 249 print 'Warning: Data Length Mismatch.' 250 sFileType=f.read(4)#=='TCSO' 251 sth1=f.read(6) 252 nLenSoln,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 253 solname=f.read(nLenSoln) 254 solname=solname.decode('utf-8')# 255 sth2=f.read(4) 256 solxroot=d.firstChild 257 solxroot.setAttribute('std_version','0.75') 258 solxroot.setAttribute('std_author','iceeLyne') 259 solxroot.setAttribute('sol_name',solname) 260 cparent=solxroot 261 while f.tell()<nLenFile: 262 nLenVname,=unpack('>H',f.read(2))#Unsigned Short,Big-endian 263 sVname=f.read(nLenVname) 264 sVname=sVname.decode('utf-8')# 265 type=f.read(1) 266 if type==NUMBER: 267 num2x() 268 elif type==BOOLEAN: 269 bol2x() 270 elif type==STRING: 271 str2x() 272 elif type==OBJOBJ: 273 obj2x() 274 elif type==OBJARR: 275 arr2x() 276 elif type==OBJDATE: 277 dat2x() 278 elif type==OBJXML: 279 xml2x() 280 elif type==OBJCC: 281 occ2x() 282 elif type==OBJM: 283 ojm2x() 284 elif type==NULL: 285 nul2x() 286 elif type==UNDEF: 287 und2x() 288 else: 289 raise s2xErr('Unexpected Data Type: '+hex(ord(type))) 290 end=f.read(1)#=='\x00' 291 sxmloutput=d.toprettyxml('\t','\n','utf-8') 292 if argvOutFile=='': 293 argvOutFile=argvInpFile[:argvInpFile.rfind('.')]+'.xml' 294 foutput=open(argvOutFile,'w') 295 foutput.write(sxmloutput) 296 foutput.close() 297 print 'Converted File: '+argvOutFile+' Was Successfully Created.' 298 except s2xErr,e: 299 print e.msg 300 except: 301 print 'Unexpected Error.' 302 d.unlink()# 303 f.close()# 304 elif argvSw=='-s': 305 # parse xml to sol 306 try: 307 d=minidom.parse(argvInpFile) 308 except IOError: 309 print 'Could Not Open The Input File: '+argvInpFile 310 except: 311 print 'Error At Parsing XML File Input.' 312 else: 313 def x2num(): 314 global sData,sLenVname,sVname,c 315 sData+=sLenVname+sVname+NUMBER 316 sValue=c.getAttribute('value') 317 if sValue=='Infinity': 318 sData+='\x7F\xF0\x00\x00\x00\x00\x00\x00' 319 elif sValue=='-Infinity': 320 sData+='\xFF\xF0\x00\x00\x00\x00\x00\x00' 321 elif sValue=='NaN': 322 sData+='\x7F\xF8\x00\x00\x00\x00\x00\x00' 323 else: 324 nValue=float(sValue) 325 sData+=pack('>d',nValue) 326 def x2bol(): 327 global sData,sLenVname,sVname,c 328 sData+=sLenVname+sVname+BOOLEAN 329 sValue=c.getAttribute('value') 330 if sValue=='true': 331 sData+='\x01' 332 elif sValue=='false': 333 sData+='\x00' 334 else: 335 raise s2xErr('Unexpected Boolean Value: '+sValue) 336 def x2str(): 337 global sData,sLenVname,sVname,c 338 sData+=sLenVname+sVname+STRING 339 sCData='' 340 for cData in c.childNodes: 341 if cData.nodeType==4:#CDATA_SECTION_NODE 342 sCData=cData.nodeValue 343 break 344 sCData=sCData.encode('utf-8')# 345 nLenCData=len(sCData) 346 sLenCData=pack('>H',nLenCData) 347 sData+=sLenCData+sCData 348 def x2obj(): 349 global sData,sLenVname,sVname,c 350 sData+=sLenVname+sVname+OBJOBJ 351 temp=c 352 c=c.firstChild 353 while c: 354 if c.nodeType==1:#ELEMENT_NODE 355 sVname=c.getAttribute('name') 356 sVname=sVname.encode('utf-8')# 357 nLenVname=len(sVname) 358 sLenVname=pack('>H',nLenVname) 359 type=c.getAttribute('type') 360 if type=='number': 361 x2num() 362 elif type=='boolean': 363 x2bol() 364 elif type=='string': 365 x2str() 366 elif type=='object': 367 x2obj() 368 elif type=='array': 369 x2arr() 370 elif type=='date': 371 x2dat() 372 elif type=='xml': 373 x2xml() 374 elif type=='c_object': 375 x2occ() 376 elif type=='m_object': 377 x2ojm() 378 elif type=='null': 379 x2nul() 380 elif type=='undefined': 381 x2und() 382 else: 383 raise s2xErr('Unexpected Data Type: '+type) 384 c=c.nextSibling 385 sData+='\x00\x00\x09' 386 c=temp 387 def x2arr(): 388 global sData,sLenVname,sVname,c 389 sData+=sLenVname+sVname+OBJARR 390 nArrLength=float(c.getAttribute('length')) 391 sArrLength=pack('>L',nArrLength) 392 sData+=sArrLength 393 temp=c 394 c=c.firstChild 395 while c: 396 if c.nodeType==1:#ELEMENT_NODE 397 sVname=c.getAttribute('name') 398 sVname=sVname.encode('utf-8')# 399 nLenVname=len(sVname) 400 sLenVname=pack('>H',nLenVname) 401 type=c.getAttribute('type') 402 if type=='number': 403 x2num() 404 elif type=='boolean': 405 x2bol() 406 elif type=='string': 407 x2str() 408 elif type=='object': 409 x2obj() 410 elif type=='array': 411 x2arr() 412 elif type=='date': 413 x2dat() 414 elif type=='xml': 415 x2xml() 416 elif type=='c_object': 417 x2occ() 418 elif type=='m_object': 419 x2ojm() 420 elif type=='null': 421 x2nul() 422 elif type=='undefined': 423 x2und() 424 else: 425 raise s2xErr('Unexpected Data Type: '+type) 426 c=c.nextSibling 427 sData+='\x00\x00\x09' 428 c=temp 429 def x2dat(): 430 global sData,sLenVname,sVname,c 431 sData+=sLenVname+sVname+OBJDATE 432 nMsec=float(c.getAttribute('msec')) 433 nMinOffset=-60*int(c.getAttribute('utcoffset')) 434 sData+=pack('>dh',nMsec,nMinOffset) 435 def x2xml(): 436 global sData,sLenVname,sVname,c 437 sData+=sLenVname+sVname+OBJXML 438 sCData='' 439 for cData in c.childNodes: 440 if cData.nodeType==4:#CDATA_SECTION_NODE 441 sCData=cData.nodeValue 442 break 443 sCData=sCData.encode('utf-8')# 444 nLenCData=len(sCData) 445 sLenCData=pack('>L',nLenCData) 446 sData+=sLenCData+sCData 447 def x2occ(): 448 global sData,sLenVname,sVname,c 449 sData+=sLenVname+sVname+OBJCC 450 sCname=c.getAttribute('class_name') 451 sCname=sCname.encode('utf-8')# 452 nLenCname=len(sCname) 453 sLenCname=pack('>H',nLenCname) 454 sData+=sLenCname+sCname 455 temp=c 456 c=c.firstChild 457 while c: 458 if c.nodeType==1:#ELEMENT_NODE 459 sVname=c.getAttribute('name') 460 sVname=sVname.encode('utf-8')# 461 nLenVname=len(sVname) 462 sLenVname=pack('>H',nLenVname) 463 type=c.getAttribute('type') 464 if type=='number': 465 x2num() 466 elif type=='boolean': 467 x2bol() 468 elif type=='string': 469 x2str() 470 elif type=='object': 471 x2obj() 472 elif type=='array': 473 x2arr() 474 elif type=='date': 475 x2dat() 476 elif type=='xml': 477 x2xml() 478 elif type=='c_object': 479 x2occ() 480 elif type=='m_object': 481 x2ojm() 482 elif type=='null': 483 x2nul() 484 elif type=='undefined': 485 x2und() 486 else: 487 raise s2xErr('Unexpected Data Type: '+type) 488 c=c.nextSibling 489 sData+='\x00\x00\x09' 490 c=temp 491 def x2ojm(): 492 global sData,sLenVname,sVname,c 493 sData+=sLenVname+sVname+OBJM 494 def x2nul(): 495 global sData,sLenVname,sVname,c 496 sData+=sLenVname+sVname+NULL 497 def x2und(): 498 global sData,sLenVname,sVname,c 499 sData+=sLenVname+sVname+UNDEF 500 try: 501 solxroot=d.firstChild 502 if solxroot.tagName!='solx' or float(solxroot.getAttribute('std_version'))>0.75: 503 raise s2xErr('Not Solx File Or Incorrect File Version.') 504 sHeader='\x00\xBF' 505 sLenData='\x00\x00\x00\x00' 506 sFileType='TCSO' 507 sth1='\x00\x04\x00\x00\x00\x00' 508 solname=solxroot.getAttribute('sol_name') 509 solname=solname.encode('utf-8')# 510 nLenSoln=len(solname) 511 sLenSoln=pack('>H',nLenSoln)#2 bytes 512 sth2='\x00\x00\x00\x00' 513 sData=sFileType+sth1+sLenSoln+solname+sth2 514 c=solxroot.firstChild 515 while c: 516 if c.nodeType==1:#ELEMENT_NODE 517 sVname=c.getAttribute('name') 518 sVname=sVname.encode('utf-8')# 519 nLenVname=len(sVname) 520 sLenVname=pack('>H',nLenVname) 521 type=c.getAttribute('type') 522 if type=='number': 523 x2num() 524 elif type=='boolean': 525 x2bol() 526 elif type=='string': 527 x2str() 528 elif type=='object': 529 x2obj() 530 elif type=='array': 531 x2arr() 532 elif type=='date': 533 x2dat() 534 elif type=='xml': 535 x2xml() 536 elif type=='c_object': 537 x2occ() 538 elif type=='m_object': 539 x2ojm() 540 elif type=='null': 541 x2nul() 542 elif type=='undefined': 543 x2und() 544 else: 545 raise s2xErr('Unexpected Data Type: '+type) 546 sData+='\x00' 547 c=c.nextSibling 548 if argvOutFile=='': 549 argvOutFile=argvInpFile[:argvInpFile.rfind('.')]+'.sol' 550 f=open(argvOutFile,'wb') 551 sLenData=pack('>L',len(sData)) 552 f.write(sHeader+sLenData+sData) 553 f.close() 554 print 'Converted File: '+argvOutFile+' Was Successfully Created.' 555 except s2xErr,e: 556 print e.msg 557## except: 558## print 'Unexpected Error.' 559 d.unlink()# 560 else: 561 print 'Invalid Switch: '+argvSw 562