113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
##############################################################################
|
|
# #
|
|
# 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
|