############################################################################## # # # Copyright 2006-2019 WebPKI.org (http://webpki.org). # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # # You may obtain a copy of the License at # # # # https://www.apache.org/licenses/LICENSE-2.0 # # # # Unless required by applicable law or agreed to in writing, software # # distributed under the License is distributed on an "AS IS" BASIS, # # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # # See the License for the specific language governing permissions and # # limitations under the License. # # # ############################################################################## ################################################################## # Convert a Python double/float into an ES6/V8 compatible string # ################################################################## def convert2Es6Format(value): # Convert double/float to str using the native Python formatter fvalue = float(value) # Zero is a special case. The following line takes "-0" case as well if fvalue == 0: return '0' # The rest of the algorithm works on the textual representation only pyDouble = str(fvalue) # The following line catches the "inf" and "nan" values returned by str(fvalue) if pyDouble.find('n') >= 0: raise ValueError("Invalid JSON number: " + pyDouble) # Save sign separately, it doesn't have any role in the algorithm pySign = '' if pyDouble.find('-') == 0: pySign = '-' pyDouble = pyDouble[1:] # Now we should only have valid non-zero values pyExpStr = '' pyExpVal = 0 q = pyDouble.find('e') if q > 0: # Grab the exponent and remove it from the number pyExpStr = pyDouble[q:] if pyExpStr[2:3] == '0': # Supress leading zero on exponents pyExpStr = pyExpStr[:2] + pyExpStr[3:] pyDouble = pyDouble[0:q] pyExpVal = int(pyExpStr[1:]) # Split number in pyFirst + pyDot + pyLast pyFirst = pyDouble pyDot = '' pyLast = '' q = pyDouble.find('.') if q > 0: pyDot = '.' pyFirst = pyDouble[:q] pyLast = pyDouble[q + 1:] # Now the string is split into: pySign + pyFirst + pyDot + pyLast + pyExpStr if pyLast == '0': # Always remove trailing .0 pyDot = '' pyLast = '' if pyExpVal > 0 and pyExpVal < 21: # Integers are shown as is with up to 21 digits pyFirst += pyLast pyLast = '' pyDot = '' pyExpStr = '' q = pyExpVal - len(pyFirst) while q >= 0: q -= 1 pyFirst += '0' elif pyExpVal < 0 and pyExpVal > -7: # Small numbers are shown as 0.etc with e-6 as lower limit pyLast = pyFirst + pyLast pyFirst = '0' pyDot = '.' pyExpStr = '' q = pyExpVal while q < -1: q += 1 pyLast = '0' + pyLast # The resulting sub-strings are concatenated return pySign + pyFirst + pyDot + pyLast + pyExpStr