diff --git a/Sources/JavaCoderConfig.swift b/Sources/JavaCoderConfig.swift index 4bbb144..3cf7561 100644 --- a/Sources/JavaCoderConfig.swift +++ b/Sources/JavaCoderConfig.swift @@ -43,100 +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) - } - let args = [jvalue(i: jint(bitPattern: UInt32(value)))] + 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 - UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))) + 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 - let args = [jvalue(i: jint(bitPattern: value as! UInt32))] + 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 - UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)) + 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/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..047f4ad 100644 --- a/Sources/JavaPrimitive.swift +++ b/Sources/JavaPrimitive.swift @@ -80,17 +80,24 @@ extension Int64 { extension UInt { public init(fromJavaPrimitive javaPrimitive: jint) { + #if arch(x86_64) || arch(arm64) self.init(UInt32(bitPattern: javaPrimitive)) + #else + 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) - return jint(bitPattern: uint32) + #if arch(x86_64) || arch(arm64) + return jint(bitPattern: UInt32(self)) + #else + return jint(bitPattern: self) + #endif } } @@ -119,11 +126,19 @@ extension UInt16 { extension UInt32 { public init(fromJavaPrimitive javaPrimitive: jint) { + #if arch(x86_64) || arch(arm64) self.init(bitPattern: javaPrimitive) + #else + self.init(UInt(bitPattern: javaPrimitive)) + #endif } public func javaPrimitive() throws -> jint { + #if arch(x86_64) || arch(arm64) return jint(bitPattern: self) + #else + return jint(bitPattern: UInt(self)) + #endif } }