diff --git a/Sources/JavaCoderConfig.swift b/Sources/JavaCoderConfig.swift index 3cf7561..3652001 100644 --- a/Sources/JavaCoderConfig.swift +++ b/Sources/JavaCoderConfig.swift @@ -135,7 +135,7 @@ public struct JavaCoderConfig { RegisterType(type: Float.self, javaClassname: FloatClassname, encodableClosure: { any, _ in let value = any as! Float - let primitive = try value.javaPrimitive() + let primitive = jfloat(value) let args = [jvalue(f: primitive)] return JNI.NewObject(FloatClass, methodID: FloatConstructor, args: args)! }, decodableClosure: { value, _ in @@ -144,7 +144,7 @@ public struct JavaCoderConfig { RegisterType(type: Double.self, javaClassname: DoubleClassname, encodableClosure: { any, _ in let value = any as! Double - let primitive = try value.javaPrimitive() + let primitive = jdouble(value) let args = [jvalue(d: primitive)] return JNI.NewObject(DoubleClass, methodID: DoubleConstructor, args: args)! }, decodableClosure: { value, _ in diff --git a/Sources/JavaEncoder.swift b/Sources/JavaEncoder.swift index e24e36e..27c9210 100644 --- a/Sources/JavaEncoder.swift +++ b/Sources/JavaEncoder.swift @@ -263,11 +263,11 @@ fileprivate class JavaObjectContainer : KeyedEncodingContainerPro } func encode(_ value: Double, forKey key: K) throws { - try encodeDouble(try value.javaPrimitive(), key: key.stringValue) + try encodeDouble(jdouble(value), key: key.stringValue) } func encode(_ value: Float, forKey key: K) throws { - try encodeFloat(try value.javaPrimitive(), key: key.stringValue) + try encodeFloat(jfloat(value), key: key.stringValue) } func encode(_ value: Int, forKey key: K) throws { diff --git a/Sources/JavaPrimitive.swift b/Sources/JavaPrimitive.swift index 047f4ad..d043e66 100644 --- a/Sources/JavaPrimitive.swift +++ b/Sources/JavaPrimitive.swift @@ -6,24 +6,45 @@ import Foundation import java_swift import CJavaVM +public typealias JavaBoolean = jboolean +public typealias JavaByte = jbyte +public typealias JavaShort = jshort +public typealias JavaInt = jint +public typealias JavaLong = jlong + +#if arch(arm) +// Looks like calling convention for ARM32 is broken: probably soft-float vs hard-float +// https://android.googlesource.com/platform/ndk/+/master/docs/HardFloatAbi.md +// We will replace jfloat with 4-byte jint bit pattern +public typealias JavaFloat = jint +#else +public typealias JavaFloat = jfloat +#endif +#if arch(arm) +// We will replace jdouble with 8-byte jlong bit pattern +public typealias JavaDouble = jlong +#else +public typealias JavaDouble = jdouble +#endif + extension Bool { - public init(fromJavaPrimitive javaPrimitive: jboolean) { + public init(fromJavaPrimitive javaPrimitive: JavaBoolean) { self.init(javaPrimitive == JNI_TRUE) } - public func javaPrimitive() throws -> jboolean { + public func javaPrimitive() throws -> JavaBoolean { return jboolean(self ? JNI_TRUE : JNI_FALSE) } } extension Int { - public init(fromJavaPrimitive javaPrimitive: jint) { + public init(fromJavaPrimitive javaPrimitive: JavaInt) { self.init(javaPrimitive) } - public func javaPrimitive(codingPath: [CodingKey] = []) throws -> jint { + public func javaPrimitive(codingPath: [CodingKey] = []) throws -> JavaInt { if self < Int(Int32.min) || self > Int(Int32.max) { let errorDescription = "Not enough bits to represent Int" let context = EncodingError.Context(codingPath: codingPath, debugDescription: errorDescription) @@ -35,51 +56,51 @@ extension Int { extension Int8 { - public init(fromJavaPrimitive javaPrimitive: jbyte) { + public init(fromJavaPrimitive javaPrimitive: JavaByte) { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jbyte { + public func javaPrimitive() throws -> JavaByte { return jbyte(self) } } extension Int16 { - public init(fromJavaPrimitive javaPrimitive: jshort) { + public init(fromJavaPrimitive javaPrimitive: JavaShort) { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jshort { + public func javaPrimitive() throws -> JavaShort { return jshort(self) } } extension Int32 { - public init(fromJavaPrimitive javaPrimitive: jint) { + public init(fromJavaPrimitive javaPrimitive: JavaInt) { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jint { + public func javaPrimitive() throws -> JavaInt { return jint(self) } } extension Int64 { - public init(fromJavaPrimitive javaPrimitive: jlong) { + public init(fromJavaPrimitive javaPrimitive: JavaLong) { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jlong { + public func javaPrimitive() throws -> JavaLong { return jlong(self) } } extension UInt { - public init(fromJavaPrimitive javaPrimitive: jint) { + public init(fromJavaPrimitive javaPrimitive: JavaInt) { #if arch(x86_64) || arch(arm64) self.init(UInt32(bitPattern: javaPrimitive)) #else @@ -87,7 +108,7 @@ extension UInt { #endif } - public func javaPrimitive(codingPath: [CodingKey] = []) throws -> jint { + public func javaPrimitive(codingPath: [CodingKey] = []) throws -> JavaInt { if self < UInt(UInt32.min) || self > UInt(UInt32.max) { let errorDescription = "Not enough bits to represent UInt" let context = EncodingError.Context(codingPath: codingPath, debugDescription: errorDescription) @@ -103,29 +124,29 @@ extension UInt { extension UInt8 { - public init(fromJavaPrimitive javaPrimitive: jbyte) { + public init(fromJavaPrimitive javaPrimitive: JavaByte) { self.init(bitPattern: javaPrimitive) } - public func javaPrimitive() throws -> jbyte { + public func javaPrimitive() throws -> JavaByte { return jbyte(bitPattern: self) } } extension UInt16 { - public init(fromJavaPrimitive javaPrimitive: jshort) { + public init(fromJavaPrimitive javaPrimitive: JavaShort) { self.init(bitPattern: javaPrimitive) } - public func javaPrimitive() throws -> jshort { + public func javaPrimitive() throws -> JavaShort { return jshort(bitPattern: self) } } extension UInt32 { - public init(fromJavaPrimitive javaPrimitive: jint) { + public init(fromJavaPrimitive javaPrimitive: JavaInt) { #if arch(x86_64) || arch(arm64) self.init(bitPattern: javaPrimitive) #else @@ -133,7 +154,7 @@ extension UInt32 { #endif } - public func javaPrimitive() throws -> jint { + public func javaPrimitive() throws -> JavaInt { #if arch(x86_64) || arch(arm64) return jint(bitPattern: self) #else @@ -144,11 +165,11 @@ extension UInt32 { extension UInt64 { - public init(fromJavaPrimitive javaPrimitive: jlong) { + public init(fromJavaPrimitive javaPrimitive: JavaLong) { self.init(bitPattern: javaPrimitive) } - public func javaPrimitive() throws -> jlong { + public func javaPrimitive() throws -> JavaLong { return jlong(bitPattern: self) } } @@ -159,8 +180,18 @@ extension Float { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jfloat { - return jfloat(self) + #if arch(arm) + public init(fromJavaPrimitive javaPrimitive: jint) { + self.init(bitPattern: UInt32(bitPattern: Int32(javaPrimitive))) + } + #endif + + public func javaPrimitive() throws -> JavaFloat { + #if arch(arm) + return jint(Int32(bitPattern: bitPattern)) + #else + return self + #endif } } @@ -170,7 +201,64 @@ extension Double { self.init(javaPrimitive) } - public func javaPrimitive() throws -> jdouble { - return jdouble(self) + #if arch(arm) + public init(fromJavaPrimitive javaPrimitive: jlong) { + self.init(bitPattern: UInt64(javaPrimitive)) + } + #endif + + public func javaPrimitive() throws -> JavaDouble { + #if arch(arm) + return jlong(bitPattern: bitPattern) + #else + return self + #endif } -} \ No newline at end of file +} + + + +extension JavaBoolean { + public static func defaultValue() -> JavaBoolean { + return jboolean(JNI_FALSE) + } +} + +extension JavaByte { + public static func defaultValue() -> JavaByte { + return 0 + } +} + +extension JavaShort { + public static func defaultValue() -> JavaShort { + return 0 + } +} + +extension JavaInt { + public static func defaultValue() -> JavaInt { + return 0 + } +} + +extension JavaLong { + public static func defaultValue() -> JavaLong { + return 0 + } +} + +#if arch(arm) +#else +extension JavaFloat { + public static func defaultValue() -> JavaFloat { + return 0 + } +} + +extension JavaDouble { + public static func defaultValue() -> JavaDouble { + return 0 + } +} +#endif \ No newline at end of file