From 125e7c25dcc1736cadec0cffa6a1c6e180002c91 Mon Sep 17 00:00:00 2001
From: Gregory Warnes <gregory.r.warnes@pfizer.com>
Date: Thu, 24 Apr 2003 17:45:10 +0000
Subject: [PATCH] - Moved XMLname.py and ieee754.py into the wstools CVS
 package from   SOAPpy/SOAPpy.

---
 XMLname.py  |  86 +++++++++++++++++++++++++++++++++++++++
 __init__.py |   2 +
 ieee754.py  | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 202 insertions(+)
 create mode 100644 XMLname.py
 create mode 100644 ieee754.py

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, <http://www.w3.org/TR/soap12-part2/#namemap>
+
+Also see <http://www.w3.org/2000/xp/Group/xmlp-issues>.
+
+Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com>
+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 <http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html>
+for a description of the IEEE 754 floating point standard.
+
+Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com>
+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 ) 
+
+
+