@@ -301,14 +301,6 @@ private struct JSONWriter {
301301 let pretty : Bool
302302 let sortedKeys : Bool
303303 let writer : ( String ? ) -> Void
304-
305- private lazy var _numberformatter : CFNumberFormatter = {
306- let formatter : CFNumberFormatter
307- formatter = CFNumberFormatterCreate ( nil , CFLocaleCopyCurrent ( ) , kCFNumberFormatterNoStyle)
308- CFNumberFormatterSetProperty ( formatter, kCFNumberFormatterMaxFractionDigits, NSNumber ( value: 15 ) )
309- CFNumberFormatterSetFormat ( formatter, " 0.############### " . _cfObject)
310- return formatter
311- } ( )
312304
313305 init ( pretty: Bool = false , sortedKeys: Bool = false , writer: @escaping ( String ? ) -> Void ) {
314306 self . pretty = pretty
@@ -334,75 +326,49 @@ private struct JSONWriter {
334326 case let str as String :
335327 try serializeString ( str)
336328 case let boolValue as Bool :
337- serializeBool ( boolValue)
329+ writer ( boolValue. description )
338330 case let num as Int :
339- serializeInteger ( value : num)
331+ writer ( num. description )
340332 case let num as Int8 :
341- serializeInteger ( value : num)
333+ writer ( num. description )
342334 case let num as Int16 :
343- serializeInteger ( value : num)
335+ writer ( num. description )
344336 case let num as Int32 :
345- serializeInteger ( value : num)
337+ writer ( num. description )
346338 case let num as Int64 :
347- serializeInteger ( value : num)
339+ writer ( num. description )
348340 case let num as UInt :
349- serializeInteger ( value : num)
341+ writer ( num. description )
350342 case let num as UInt8 :
351- serializeInteger ( value : num)
343+ writer ( num. description )
352344 case let num as UInt16 :
353- serializeInteger ( value : num)
345+ writer ( num. description )
354346 case let num as UInt32 :
355- serializeInteger ( value : num)
347+ writer ( num. description )
356348 case let num as UInt64 :
357- serializeInteger ( value : num)
349+ writer ( num. description )
358350 case let array as Array < Any ? > :
359351 try serializeArray ( array)
360352 case let dict as Dictionary < AnyHashable , Any ? > :
361353 try serializeDictionary ( dict)
362354 case let num as Float :
363- try serializeNumber ( NSNumber ( value : num) )
355+ try serializeFloat ( num)
364356 case let num as Double :
365- try serializeNumber ( NSNumber ( value : num) )
357+ try serializeFloat ( num)
366358 case let num as Decimal :
367359 writer ( num. description)
368360 case let num as NSDecimalNumber :
369361 writer ( num. description)
370362 case is NSNull :
371363 try serializeNull ( )
372364 case _ where __SwiftValue. store ( obj) is NSNumber :
373- try serializeNumber ( __SwiftValue. store ( obj) as! NSNumber )
365+ let num = __SwiftValue. store ( obj) as! NSNumber
366+ writer ( num. description)
374367 default :
375368 throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . propertyListReadCorrupt. rawValue, userInfo: [ " NSDebugDescription " : " Invalid object cannot be serialized " ] )
376369 }
377370 }
378371
379- private func serializeInteger< T: UnsignedInteger > ( value: T , isNegative: Bool = false ) {
380- let maxIntLength = 22 // 20 digits in UInt64 + optional sign + trailing '\0'
381- let asciiZero : CChar = 0x30 // ASCII '0' == 0x30
382- let asciiMinus : CChar = 0x2d // ASCII '-' == 0x2d
383-
384- var number = UInt64 ( value)
385- var buffer = Array < CChar > ( repeating: 0 , count: maxIntLength)
386- var pos = maxIntLength - 1
387-
388- repeat {
389- pos -= 1
390- buffer [ pos] = asciiZero + CChar( number % 10 )
391- number /= 10
392- } while number != 0
393-
394- if isNegative {
395- pos -= 1
396- buffer [ pos] = asciiMinus
397- }
398- let output = String ( cString: Array ( buffer. suffix ( from: pos) ) )
399- writer ( output)
400- }
401-
402- private func serializeInteger< T: SignedInteger > ( value: T ) {
403- serializeInteger ( value: UInt64 ( value. magnitude) , isNegative: value < 0 )
404- }
405-
406372 func serializeString( _ str: String ) throws {
407373 writer ( " \" " )
408374 for scalar in str. unicodeScalars {
@@ -434,37 +400,24 @@ private struct JSONWriter {
434400 writer ( " \" " )
435401 }
436402
437- func serializeBool( _ bool: Bool ) {
438- switch bool {
439- case true :
440- writer ( " true " )
441- case false :
442- writer ( " false " )
403+ private func serializeFloat< T: FloatingPoint & LosslessStringConvertible > ( _ num: T ) throws {
404+ guard num. isFinite else {
405+ throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . propertyListReadCorrupt. rawValue, userInfo: [ " NSDebugDescription " : " Invalid number value ( \( num) ) in JSON write " ] )
443406 }
407+ var str = num. description
408+ if str. hasSuffix ( " .0 " ) {
409+ str. removeLast ( 2 )
410+ }
411+ writer ( str)
444412 }
445413
446414 mutating func serializeNumber( _ num: NSNumber ) throws {
447415 if CFNumberIsFloatType ( num. _cfObject) {
448- let dv = num. doubleValue
449- if !dv. isFinite {
450- let value : String
451- if dv. isNaN {
452- value = " NaN "
453- } else if dv. isInfinite {
454- value = " infinite "
455- } else {
456- value = String ( dv)
457- }
458-
459- throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . propertyListReadCorrupt. rawValue, userInfo: [ " NSDebugDescription " : " Invalid number value ( \( value) ) in JSON write " ] )
460- }
461-
462- let string = CFNumberFormatterCreateStringWithNumber ( nil , _numberformatter, num. _cfObject) . _swiftObject
463- writer ( string)
416+ try serializeFloat ( num. doubleValue)
464417 } else {
465418 switch num. _cfTypeID {
466419 case CFBooleanGetTypeID ( ) :
467- serializeBool ( num. boolValue)
420+ writer ( num. boolValue. description )
468421 default :
469422 writer ( num. stringValue)
470423 }
0 commit comments