diff --git a/XMLname.py b/XMLname.py new file mode 100644 index 0000000..7f88fe3 --- /dev/null +++ b/XMLname.py @@ -0,0 +1,86 @@ +"""Translate strings to and from SOAP 1.2 XML name encoding + +Implements rules for mapping application defined name to XML names +specified by the w3 SOAP working group for SOAP version 1.2 in +Appendix A of "SOAP Version 1.2 Part 2: Adjuncts", W3C Working Draft +17, December 2001, + +Also see . + +Author: Gregory R. Warnes +Date:: 2002-04-25 +Version 0.9.0 + +""" + +from re import * + + +def _NCNameChar(x): + return x.isalpha() or x.isdigit() or x=="." or x=='-' or x=="_" + + +def _NCNameStartChar(x): + return x.isalpha() or x=="_" + + +def _toUnicodeHex(x): + hexval = hex(ord(x[0]))[2:] + hexlen = len(hexval) + # Make hexval have either 4 or 8 digits by prepending 0's + if (hexlen==1): hexval = "000" + hexval + elif (hexlen==2): hexval = "00" + hexval + elif (hexlen==3): hexval = "0" + hexval + elif (hexlen==4): hexval = "" + hexval + elif (hexlen==5): hexval = "000" + hexval + elif (hexlen==6): hexval = "00" + hexval + elif (hexlen==7): hexval = "0" + hexval + elif (hexlen==8): hexval = "" + hexval + else: raise Exception, "Illegal Value returned from hex(ord(x))" + + return "_x"+ hexval + "_" + + +def _fromUnicodeHex(x): + return eval( r'u"\u'+x[2:-1]+'"' ) + + +def toXMLname(string): + """Convert string to a XML name.""" + if string.find(':') != -1 : + (prefix, localname) = string.split(':',1) + else: + prefix = None + localname = string + + T = unicode(localname) + + N = len(localname) + X = []; + for i in range(N) : + if i< N-1 and T[i]==u'_' and T[i+1]==u'x': + X.append(u'_x005F_') + elif i==0 and N >= 3 and \ + ( T[0]==u'x' or T[0]==u'X' ) and \ + ( T[1]==u'm' or T[1]==u'M' ) and \ + ( T[2]==u'l' or T[2]==u'L' ): + X.append(u'_xFFFF_' + T[0]) + elif (not _NCNameChar(T[i])) or (i==0 and not _NCNameStartChar(T[i])): + X.append(_toUnicodeHex(T[i])) + else: + X.append(T[i]) + + return u''.join(X) + + +def fromXMLname(string): + """Convert XML name to unicode string.""" + + retval = sub(r'_xFFFF_','', string ) + + def fun( matchobj ): + return _fromUnicodeHex( matchobj.group(0) ) + + retval = sub(r'_x[0-9A-Za-z]+_', fun, retval ) + + return retval diff --git a/__init__.py b/__init__.py index 67cdf25..c1d954b 100644 --- a/__init__.py +++ b/__init__.py @@ -10,3 +10,5 @@ """WSDL parsing services package for Web Services for Python.""" from ServiceProxy import ServiceProxy +import ieee754 +import XMLname diff --git a/ieee754.py b/ieee754.py new file mode 100644 index 0000000..5a2321f --- /dev/null +++ b/ieee754.py @@ -0,0 +1,114 @@ +"""Utilities for handling IEEE 754 floating point special values + +This class implements constants and functions for working with IEEE754 +double-precision special values. It provides constants for NaN (Not a +Number), NegInf (Negative Infinity), PosInf (Positive Infinity), and +Inf (also Positive Infinity), as well as functions to test for these +values. + +The code is implemented in pure python by taking advantage of the +'struct' standard module. Some efficiency could be gained by +translating the core routines into C. + +See +for a description of the IEEE 754 floating point standard. + +Author: Gregory R. Warnes +Date:: 2003-03-25 +Version 0.5.0 + +""" + +ident = "$Id$" + +__version__ = "0.5.0" + +from struct import pack, unpack + +# check endianess +_big_endian = pack('i',1)[0] != '\x01' + +# and define appropriate constants +if(_big_endian): + HW=0 + LW=1 + + NaN = unpack('d', '\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF')[0] + Inf = unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0] + PosInf = Inf + NegInf = -Inf + +else: + HW=1 + LW=0 + + NaN = unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0] + Inf = unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0] + PosInf = Inf + NegInf = -Inf + +def _double_as_longs(dval): + "Use unpack to decode a double precision float into two long integers" + tmp = unpack('ll',pack('d', dval)) + return (tmp[HW], tmp[LW] ) + + +## +## Functions to extract components of the IEEE 754 floating point format +## + +def sign(dval): + "Extract the sign bit from a double-precision floating point value" + ll = _double_as_longs(dval) + return ll[0] >> 31 & 0x01 + +def exponent(dval): + """Extract the exponentent bits from a double-precision floating + point value. + + Note that for normalized values, the exponentdent bits have an offset + of 1023. As a consequence, the actual exponentent is obtained + by subtracting 1023 for the value returned by this function + """ + ll = _double_as_longs(dval) + return ( ll[0] >> 20 ) & 0x7ff + +def mantissa(dval): + ll = _double_as_longs(dval) + mantissa1 = ( ll[0] & 0xfffffL ) << 32 + mantissa2 = ll[1] + return mantissa1 + mantissa2 + +## +## Functions to test for IEEE 754 special values +## + +def is_NaN(value): + "Determine if the argument is a IEEE 754 NaN (Not a Number) value." + return ( exponent(value)==0x7ff and mantissa(value)!=0 ) + +def is_Infinite(value): + """Determine if the argument is an infinite IEEE 754 value (positive + or negative inifinity)""" + return ( exponent(value)==0x7ff and mantissa(value)== 0 ) + +def is_Finite(value): + """Determine if the argument is an finite IEEE 754 value (i.e., is + not NaN, positive or negative inifinity)""" + return ( exponent(value)!=0x7ff ) + + +def is_Inf(value): + "Determine if the argument is a IEEE 754 positive infinity value" + return ( sign(value)==0 and exponent(value)==0x7ff \ + and mantissa(value)== 0 ) + +is_PosInf = is_Inf + +def is_NegInf(value): + "Determine if the argument is a IEEE 754 negative infinity value" + return ( sign(value)==1 and exponent(value)==0x7ff and \ + mantissa(value)== 0 ) + + +