From 677cf1a463e46e02ec4eaed4f4f73be573b3ec2e Mon Sep 17 00:00:00 2001 From: Andrew Druk Date: Wed, 17 Feb 2021 01:18:30 +0200 Subject: [PATCH 1/2] Dev: restore 32-bit support in Java Coder --- Sources/JavaCoderConfig.swift | 20 ++++++++++++++++++-- Sources/JavaDecoder.swift | 4 ++++ Sources/JavaPrimitive.swift | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Sources/JavaCoderConfig.swift b/Sources/JavaCoderConfig.swift index 4bbb144..3244042 100644 --- a/Sources/JavaCoderConfig.swift +++ b/Sources/JavaCoderConfig.swift @@ -91,10 +91,18 @@ public struct JavaCoderConfig { let context = EncodingError.Context(codingPath: $1, debugDescription: errorDescription) throw EncodingError.invalidValue(value, context) } + #if arch(x86_64) || arch(arm64) let args = [jvalue(i: jint(bitPattern: UInt32(value)))] + #else + let args = [jvalue(i: jint(value))] + #endif return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))) + #if arch(x86_64) || arch(arm64) + return UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))) + #else + return UInt(JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + #endif }) RegisterType(type: UInt8.self, javaClassname: ByteClassname, encodableClosure: { value, _ in @@ -112,10 +120,18 @@ public struct JavaCoderConfig { }) RegisterType(type: UInt32.self, javaClassname: IntegerClassname, encodableClosure: { value, _ in + #if arch(x86_64) || arch(arm64) let args = [jvalue(i: jint(bitPattern: value as! UInt32))] + #else + let args = [jvalue(i: jint(value as! UInt32))] + #endif return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + #if arch(x86_64) || arch(arm64) + return UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + #else + return UInt32(JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + #endif }) RegisterType(type: UInt64.self, javaClassname: LongClassname, encodableClosure: { value, _ in diff --git a/Sources/JavaDecoder.swift b/Sources/JavaDecoder.swift index 044f082..df7888a 100644 --- a/Sources/JavaDecoder.swift +++ b/Sources/JavaDecoder.swift @@ -151,7 +151,11 @@ fileprivate class JavaObjectContainer : KeyedDecodingContainerPro private func decodeInteger(forKey key: String) throws -> Int32 { let fieldID = try JNI.getJavaField(forClass: javaClass, field: key, sig: "I") + #if arch(x86_64) || arch(arm64) return JNI.api.GetIntField(JNI.env, javaObject, fieldID) + #else + return Int32(JNI.api.GetIntField(JNI.env, javaObject, fieldID)) + #endif } private func decodeLong(forKey key: String) throws -> Int64 { diff --git a/Sources/JavaPrimitive.swift b/Sources/JavaPrimitive.swift index 8e610b5..e59a3cd 100644 --- a/Sources/JavaPrimitive.swift +++ b/Sources/JavaPrimitive.swift @@ -80,7 +80,11 @@ extension Int64 { extension UInt { public init(fromJavaPrimitive javaPrimitive: jint) { + #if arch(x86_64) || arch(arm64) self.init(UInt32(bitPattern: javaPrimitive)) + #else + self.init(javaPrimitive) + #endif } public func javaPrimitive(codingPath: [CodingKey] = []) throws -> jint { @@ -90,7 +94,11 @@ extension UInt { throw EncodingError.invalidValue(self, context) } let uint32 = UInt32(self) + #if arch(x86_64) || arch(arm64) return jint(bitPattern: uint32) + #else + return jint(uint32) + #endif } } @@ -119,11 +127,19 @@ extension UInt16 { extension UInt32 { public init(fromJavaPrimitive javaPrimitive: jint) { + #if arch(x86_64) || arch(arm64) self.init(bitPattern: javaPrimitive) + #else + self.init(javaPrimitive) + #endif } public func javaPrimitive() throws -> jint { + #if arch(x86_64) || arch(arm64) return jint(bitPattern: self) + #else + return jint(self) + #endif } } From 328decd14703ebd2e44cd1d81386565d1b1f3877 Mon Sep 17 00:00:00 2001 From: Andrew Druk Date: Fri, 26 Mar 2021 00:43:23 +0200 Subject: [PATCH 2/2] Dev: fix primitive encode/decode for 32 bit --- Sources/JavaCoderConfig.swift | 124 ++++++++++++++++------------------ Sources/JavaPrimitive.swift | 13 ++-- 2 files changed, 66 insertions(+), 71 deletions(-) diff --git a/Sources/JavaCoderConfig.swift b/Sources/JavaCoderConfig.swift index 3244042..3cf7561 100644 --- a/Sources/JavaCoderConfig.swift +++ b/Sources/JavaCoderConfig.swift @@ -43,116 +43,112 @@ public struct JavaCoderConfig { public static func RegisterBasicJavaTypes() { - RegisterType(type: Int.self, javaClassname: IntegerClassname, encodableClosure: { - let value = $0 as! Int - if value < Int(Int32.min) || value > Int(Int32.max) { - let errorDescription = "Not enough bits to represent Int" - let context = EncodingError.Context(codingPath: $1, debugDescription: errorDescription) - throw EncodingError.invalidValue(value, context) - } - let args = [jvalue(i: jint(value))] + RegisterType(type: Int.self, javaClassname: IntegerClassname, encodableClosure: { any, codingPath in + let value = any as! Int + let primitive = try value.javaPrimitive(codingPath: codingPath) + let args = [jvalue(i: primitive)] return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - Int(JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + Int(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) }) - RegisterType(type: Int8.self, javaClassname: ByteClassname, encodableClosure: { value, _ in - let args = [jvalue(b: value as! Int8)] + RegisterType(type: Int8.self, javaClassname: ByteClassname, encodableClosure: { any, _ in + let value = any as! Int8 + let primitive = try value.javaPrimitive() + let args = [jvalue(b: primitive)] return JNI.NewObject(ByteClass, methodID: ByteConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallByteMethod(value, methodID: NumberByteValueMethod) + Int8(fromJavaPrimitive: JNI.CallByteMethod(value, methodID: NumberByteValueMethod)) }) - RegisterType(type: Int16.self, javaClassname: ShortClassname, encodableClosure: { value, _ in - let args = [jvalue(s: value as! Int16)] + RegisterType(type: Int16.self, javaClassname: ShortClassname, encodableClosure: { any, _ in + let value = any as! Int16 + let primitive = try value.javaPrimitive() + let args = [jvalue(s: primitive)] return JNI.NewObject(ShortClass, methodID: ShortConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallShortMethod(value, methodID: NumberShortValueMethod) + Int16(fromJavaPrimitive: JNI.CallShortMethod(value, methodID: NumberShortValueMethod)) }) - RegisterType(type: Int32.self, javaClassname: IntegerClassname, encodableClosure: { value, _ in - let args = [jvalue(i: jint(value as! Int32))] + RegisterType(type: Int32.self, javaClassname: IntegerClassname, encodableClosure: { any, _ in + let value = any as! Int32 + let primitive = try value.javaPrimitive() + let args = [jvalue(i: primitive)] return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallIntMethod(value, methodID: NumberIntValueMethod) + Int32(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) }) - RegisterType(type: Int64.self, javaClassname: LongClassname, encodableClosure: { value, _ in - let args = [jvalue(j: value as! Int64)] + RegisterType(type: Int64.self, javaClassname: LongClassname, encodableClosure: { any, _ in + let value = any as! Int64 + let primitive = try value.javaPrimitive() + let args = [jvalue(j: primitive)] return JNI.NewObject(LongClass, methodID: LongConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallLongMethod(value, methodID: NumberLongValueMethod) + Int64(fromJavaPrimitive: JNI.CallLongMethod(value, methodID: NumberLongValueMethod)) }) - RegisterType(type: UInt.self, javaClassname: IntegerClassname, encodableClosure: { - let value = $0 as! UInt - if value < UInt(UInt32.min) || value > Int(UInt32.max) { - let errorDescription = "Not enough bits to represent UInt" - let context = EncodingError.Context(codingPath: $1, debugDescription: errorDescription) - throw EncodingError.invalidValue(value, context) - } - #if arch(x86_64) || arch(arm64) - let args = [jvalue(i: jint(bitPattern: UInt32(value)))] - #else - let args = [jvalue(i: jint(value))] - #endif + RegisterType(type: UInt.self, javaClassname: IntegerClassname, encodableClosure: { any, codingPath in + let value = any as! UInt + let primitive = try value.javaPrimitive(codingPath: codingPath) + let args = [jvalue(i: primitive)] return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - #if arch(x86_64) || arch(arm64) - return UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))) - #else - return UInt(JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) - #endif + UInt(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) }) - RegisterType(type: UInt8.self, javaClassname: ByteClassname, encodableClosure: { value, _ in - let args = [jvalue(b: jbyte(bitPattern: value as! UInt8))] + RegisterType(type: UInt8.self, javaClassname: ByteClassname, encodableClosure: { any, _ in + let value = any as! UInt8 + let primitive = try value.javaPrimitive() + let args = [jvalue(b: primitive)] return JNI.NewObject(ByteClass, methodID: ByteConstructor, args: args)! }, decodableClosure: { value, _ in - UInt8(bitPattern: JNI.CallByteMethod(value, methodID: NumberByteValueMethod)) + UInt8(fromJavaPrimitive: JNI.CallByteMethod(value, methodID: NumberByteValueMethod)) }) - RegisterType(type: UInt16.self, javaClassname: ShortClassname, encodableClosure: { value, _ in - let args = [jvalue(s: jshort(bitPattern: value as! UInt16))] + RegisterType(type: UInt16.self, javaClassname: ShortClassname, encodableClosure: { any, _ in + let value = any as! UInt16 + let primitive = try value.javaPrimitive() + let args = [jvalue(s: primitive)] return JNI.NewObject(ShortClass, methodID: ShortConstructor, args: args)! }, decodableClosure: { value, _ in - UInt16(bitPattern: JNI.CallShortMethod(value, methodID: NumberShortValueMethod)) + UInt16(fromJavaPrimitive: JNI.CallShortMethod(value, methodID: NumberShortValueMethod)) }) - RegisterType(type: UInt32.self, javaClassname: IntegerClassname, encodableClosure: { value, _ in - #if arch(x86_64) || arch(arm64) - let args = [jvalue(i: jint(bitPattern: value as! UInt32))] - #else - let args = [jvalue(i: jint(value as! UInt32))] - #endif + RegisterType(type: UInt32.self, javaClassname: IntegerClassname, encodableClosure: { any, _ in + let value = any as! UInt32 + let primitive = try value.javaPrimitive() + let args = [jvalue(i: primitive)] return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)! }, decodableClosure: { value, _ in - #if arch(x86_64) || arch(arm64) - return UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) - #else - return UInt32(JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) - #endif + UInt32(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) }) - RegisterType(type: UInt64.self, javaClassname: LongClassname, encodableClosure: { value, _ in - let args = [jvalue(j: jlong(bitPattern: value as! UInt64))] + RegisterType(type: UInt64.self, javaClassname: LongClassname, encodableClosure: { any, _ in + let value = any as! UInt64 + let primitive = try value.javaPrimitive() + let args = [jvalue(j: primitive)] return JNI.NewObject(LongClass, methodID: LongConstructor, args: args)! }, decodableClosure: { value, _ in - UInt64(bitPattern: JNI.CallLongMethod(value, methodID: NumberLongValueMethod)) + UInt64(fromJavaPrimitive: JNI.CallLongMethod(value, methodID: NumberLongValueMethod)) }) - RegisterType(type: Float.self, javaClassname: FloatClassname, encodableClosure: { value, _ in - let args = [jvalue(f: value as! Float)] + RegisterType(type: Float.self, javaClassname: FloatClassname, encodableClosure: { any, _ in + let value = any as! Float + let primitive = try value.javaPrimitive() + let args = [jvalue(f: primitive)] return JNI.NewObject(FloatClass, methodID: FloatConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallFloatMethod(value, methodID: NumberFloatValueMethod) + Float(fromJavaPrimitive: JNI.CallFloatMethod(value, methodID: NumberFloatValueMethod)) }) - RegisterType(type: Double.self, javaClassname: DoubleClassname, encodableClosure: { value, _ in - let args = [jvalue(d: value as! Double)] + RegisterType(type: Double.self, javaClassname: DoubleClassname, encodableClosure: { any, _ in + let value = any as! Double + let primitive = try value.javaPrimitive() + let args = [jvalue(d: primitive)] return JNI.NewObject(DoubleClass, methodID: DoubleConstructor, args: args)! }, decodableClosure: { value, _ in - JNI.CallDoubleMethod(value, methodID: NumberDoubleValueMethod) + Double(fromJavaPrimitive: JNI.CallDoubleMethod(value, methodID: NumberDoubleValueMethod)) }) RegisterType(type: Bool.self, javaClassname: BooleanClassname, encodableClosure: { value, _ in diff --git a/Sources/JavaPrimitive.swift b/Sources/JavaPrimitive.swift index e59a3cd..047f4ad 100644 --- a/Sources/JavaPrimitive.swift +++ b/Sources/JavaPrimitive.swift @@ -83,21 +83,20 @@ extension UInt { #if arch(x86_64) || arch(arm64) self.init(UInt32(bitPattern: javaPrimitive)) #else - self.init(javaPrimitive) + self.init(bitPattern: javaPrimitive) #endif } public func javaPrimitive(codingPath: [CodingKey] = []) throws -> jint { - if self < UInt(UInt32.min) || self > Int(UInt32.max) { + 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) throw EncodingError.invalidValue(self, context) } - let uint32 = UInt32(self) #if arch(x86_64) || arch(arm64) - return jint(bitPattern: uint32) + return jint(bitPattern: UInt32(self)) #else - return jint(uint32) + return jint(bitPattern: self) #endif } } @@ -130,7 +129,7 @@ extension UInt32 { #if arch(x86_64) || arch(arm64) self.init(bitPattern: javaPrimitive) #else - self.init(javaPrimitive) + self.init(UInt(bitPattern: javaPrimitive)) #endif } @@ -138,7 +137,7 @@ extension UInt32 { #if arch(x86_64) || arch(arm64) return jint(bitPattern: self) #else - return jint(self) + return jint(bitPattern: UInt(self)) #endif } }