Skip to content

Commit a794ec4

Browse files
authored
Merge pull request #7 from readdle/dev/32-bit-support
Restore 32-bit support in Java Coder
2 parents b708c75 + 328decd commit a794ec4

File tree

3 files changed

+82
-51
lines changed

3 files changed

+82
-51
lines changed

Sources/JavaCoderConfig.swift

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,100 +43,112 @@ public struct JavaCoderConfig {
4343

4444
public static func RegisterBasicJavaTypes() {
4545

46-
RegisterType(type: Int.self, javaClassname: IntegerClassname, encodableClosure: {
47-
let value = $0 as! Int
48-
if value < Int(Int32.min) || value > Int(Int32.max) {
49-
let errorDescription = "Not enough bits to represent Int"
50-
let context = EncodingError.Context(codingPath: $1, debugDescription: errorDescription)
51-
throw EncodingError.invalidValue(value, context)
52-
}
53-
let args = [jvalue(i: jint(value))]
46+
RegisterType(type: Int.self, javaClassname: IntegerClassname, encodableClosure: { any, codingPath in
47+
let value = any as! Int
48+
let primitive = try value.javaPrimitive(codingPath: codingPath)
49+
let args = [jvalue(i: primitive)]
5450
return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)!
5551
}, decodableClosure: { value, _ in
56-
Int(JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
52+
Int(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
5753
})
5854

59-
RegisterType(type: Int8.self, javaClassname: ByteClassname, encodableClosure: { value, _ in
60-
let args = [jvalue(b: value as! Int8)]
55+
RegisterType(type: Int8.self, javaClassname: ByteClassname, encodableClosure: { any, _ in
56+
let value = any as! Int8
57+
let primitive = try value.javaPrimitive()
58+
let args = [jvalue(b: primitive)]
6159
return JNI.NewObject(ByteClass, methodID: ByteConstructor, args: args)!
6260
}, decodableClosure: { value, _ in
63-
JNI.CallByteMethod(value, methodID: NumberByteValueMethod)
61+
Int8(fromJavaPrimitive: JNI.CallByteMethod(value, methodID: NumberByteValueMethod))
6462
})
6563

66-
RegisterType(type: Int16.self, javaClassname: ShortClassname, encodableClosure: { value, _ in
67-
let args = [jvalue(s: value as! Int16)]
64+
RegisterType(type: Int16.self, javaClassname: ShortClassname, encodableClosure: { any, _ in
65+
let value = any as! Int16
66+
let primitive = try value.javaPrimitive()
67+
let args = [jvalue(s: primitive)]
6868
return JNI.NewObject(ShortClass, methodID: ShortConstructor, args: args)!
6969
}, decodableClosure: { value, _ in
70-
JNI.CallShortMethod(value, methodID: NumberShortValueMethod)
70+
Int16(fromJavaPrimitive: JNI.CallShortMethod(value, methodID: NumberShortValueMethod))
7171
})
7272

73-
RegisterType(type: Int32.self, javaClassname: IntegerClassname, encodableClosure: { value, _ in
74-
let args = [jvalue(i: jint(value as! Int32))]
73+
RegisterType(type: Int32.self, javaClassname: IntegerClassname, encodableClosure: { any, _ in
74+
let value = any as! Int32
75+
let primitive = try value.javaPrimitive()
76+
let args = [jvalue(i: primitive)]
7577
return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)!
7678
}, decodableClosure: { value, _ in
77-
JNI.CallIntMethod(value, methodID: NumberIntValueMethod)
79+
Int32(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
7880
})
7981

80-
RegisterType(type: Int64.self, javaClassname: LongClassname, encodableClosure: { value, _ in
81-
let args = [jvalue(j: value as! Int64)]
82+
RegisterType(type: Int64.self, javaClassname: LongClassname, encodableClosure: { any, _ in
83+
let value = any as! Int64
84+
let primitive = try value.javaPrimitive()
85+
let args = [jvalue(j: primitive)]
8286
return JNI.NewObject(LongClass, methodID: LongConstructor, args: args)!
8387
}, decodableClosure: { value, _ in
84-
JNI.CallLongMethod(value, methodID: NumberLongValueMethod)
88+
Int64(fromJavaPrimitive: JNI.CallLongMethod(value, methodID: NumberLongValueMethod))
8589
})
8690

87-
RegisterType(type: UInt.self, javaClassname: IntegerClassname, encodableClosure: {
88-
let value = $0 as! UInt
89-
if value < UInt(UInt32.min) || value > Int(UInt32.max) {
90-
let errorDescription = "Not enough bits to represent UInt"
91-
let context = EncodingError.Context(codingPath: $1, debugDescription: errorDescription)
92-
throw EncodingError.invalidValue(value, context)
93-
}
94-
let args = [jvalue(i: jint(bitPattern: UInt32(value)))]
91+
RegisterType(type: UInt.self, javaClassname: IntegerClassname, encodableClosure: { any, codingPath in
92+
let value = any as! UInt
93+
let primitive = try value.javaPrimitive(codingPath: codingPath)
94+
let args = [jvalue(i: primitive)]
9595
return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)!
9696
}, decodableClosure: { value, _ in
97-
UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)))
97+
UInt(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
9898
})
9999

100-
RegisterType(type: UInt8.self, javaClassname: ByteClassname, encodableClosure: { value, _ in
101-
let args = [jvalue(b: jbyte(bitPattern: value as! UInt8))]
100+
RegisterType(type: UInt8.self, javaClassname: ByteClassname, encodableClosure: { any, _ in
101+
let value = any as! UInt8
102+
let primitive = try value.javaPrimitive()
103+
let args = [jvalue(b: primitive)]
102104
return JNI.NewObject(ByteClass, methodID: ByteConstructor, args: args)!
103105
}, decodableClosure: { value, _ in
104-
UInt8(bitPattern: JNI.CallByteMethod(value, methodID: NumberByteValueMethod))
106+
UInt8(fromJavaPrimitive: JNI.CallByteMethod(value, methodID: NumberByteValueMethod))
105107
})
106108

107-
RegisterType(type: UInt16.self, javaClassname: ShortClassname, encodableClosure: { value, _ in
108-
let args = [jvalue(s: jshort(bitPattern: value as! UInt16))]
109+
RegisterType(type: UInt16.self, javaClassname: ShortClassname, encodableClosure: { any, _ in
110+
let value = any as! UInt16
111+
let primitive = try value.javaPrimitive()
112+
let args = [jvalue(s: primitive)]
109113
return JNI.NewObject(ShortClass, methodID: ShortConstructor, args: args)!
110114
}, decodableClosure: { value, _ in
111-
UInt16(bitPattern: JNI.CallShortMethod(value, methodID: NumberShortValueMethod))
115+
UInt16(fromJavaPrimitive: JNI.CallShortMethod(value, methodID: NumberShortValueMethod))
112116
})
113117

114-
RegisterType(type: UInt32.self, javaClassname: IntegerClassname, encodableClosure: { value, _ in
115-
let args = [jvalue(i: jint(bitPattern: value as! UInt32))]
118+
RegisterType(type: UInt32.self, javaClassname: IntegerClassname, encodableClosure: { any, _ in
119+
let value = any as! UInt32
120+
let primitive = try value.javaPrimitive()
121+
let args = [jvalue(i: primitive)]
116122
return JNI.NewObject(IntegerClass, methodID: IntegerConstructor, args: args)!
117123
}, decodableClosure: { value, _ in
118-
UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
124+
UInt32(fromJavaPrimitive: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
119125
})
120126

121-
RegisterType(type: UInt64.self, javaClassname: LongClassname, encodableClosure: { value, _ in
122-
let args = [jvalue(j: jlong(bitPattern: value as! UInt64))]
127+
RegisterType(type: UInt64.self, javaClassname: LongClassname, encodableClosure: { any, _ in
128+
let value = any as! UInt64
129+
let primitive = try value.javaPrimitive()
130+
let args = [jvalue(j: primitive)]
123131
return JNI.NewObject(LongClass, methodID: LongConstructor, args: args)!
124132
}, decodableClosure: { value, _ in
125-
UInt64(bitPattern: JNI.CallLongMethod(value, methodID: NumberLongValueMethod))
133+
UInt64(fromJavaPrimitive: JNI.CallLongMethod(value, methodID: NumberLongValueMethod))
126134
})
127135

128-
RegisterType(type: Float.self, javaClassname: FloatClassname, encodableClosure: { value, _ in
129-
let args = [jvalue(f: value as! Float)]
136+
RegisterType(type: Float.self, javaClassname: FloatClassname, encodableClosure: { any, _ in
137+
let value = any as! Float
138+
let primitive = try value.javaPrimitive()
139+
let args = [jvalue(f: primitive)]
130140
return JNI.NewObject(FloatClass, methodID: FloatConstructor, args: args)!
131141
}, decodableClosure: { value, _ in
132-
JNI.CallFloatMethod(value, methodID: NumberFloatValueMethod)
142+
Float(fromJavaPrimitive: JNI.CallFloatMethod(value, methodID: NumberFloatValueMethod))
133143
})
134144

135-
RegisterType(type: Double.self, javaClassname: DoubleClassname, encodableClosure: { value, _ in
136-
let args = [jvalue(d: value as! Double)]
145+
RegisterType(type: Double.self, javaClassname: DoubleClassname, encodableClosure: { any, _ in
146+
let value = any as! Double
147+
let primitive = try value.javaPrimitive()
148+
let args = [jvalue(d: primitive)]
137149
return JNI.NewObject(DoubleClass, methodID: DoubleConstructor, args: args)!
138150
}, decodableClosure: { value, _ in
139-
JNI.CallDoubleMethod(value, methodID: NumberDoubleValueMethod)
151+
Double(fromJavaPrimitive: JNI.CallDoubleMethod(value, methodID: NumberDoubleValueMethod))
140152
})
141153

142154
RegisterType(type: Bool.self, javaClassname: BooleanClassname, encodableClosure: { value, _ in

Sources/JavaDecoder.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ fileprivate class JavaObjectContainer<K : CodingKey> : KeyedDecodingContainerPro
151151

152152
private func decodeInteger(forKey key: String) throws -> Int32 {
153153
let fieldID = try JNI.getJavaField(forClass: javaClass, field: key, sig: "I")
154+
#if arch(x86_64) || arch(arm64)
154155
return JNI.api.GetIntField(JNI.env, javaObject, fieldID)
156+
#else
157+
return Int32(JNI.api.GetIntField(JNI.env, javaObject, fieldID))
158+
#endif
155159
}
156160

157161
private func decodeLong(forKey key: String) throws -> Int64 {

Sources/JavaPrimitive.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,24 @@ extension Int64 {
8080
extension UInt {
8181

8282
public init(fromJavaPrimitive javaPrimitive: jint) {
83+
#if arch(x86_64) || arch(arm64)
8384
self.init(UInt32(bitPattern: javaPrimitive))
85+
#else
86+
self.init(bitPattern: javaPrimitive)
87+
#endif
8488
}
8589

8690
public func javaPrimitive(codingPath: [CodingKey] = []) throws -> jint {
87-
if self < UInt(UInt32.min) || self > Int(UInt32.max) {
91+
if self < UInt(UInt32.min) || self > UInt(UInt32.max) {
8892
let errorDescription = "Not enough bits to represent UInt"
8993
let context = EncodingError.Context(codingPath: codingPath, debugDescription: errorDescription)
9094
throw EncodingError.invalidValue(self, context)
9195
}
92-
let uint32 = UInt32(self)
93-
return jint(bitPattern: uint32)
96+
#if arch(x86_64) || arch(arm64)
97+
return jint(bitPattern: UInt32(self))
98+
#else
99+
return jint(bitPattern: self)
100+
#endif
94101
}
95102
}
96103

@@ -119,11 +126,19 @@ extension UInt16 {
119126
extension UInt32 {
120127

121128
public init(fromJavaPrimitive javaPrimitive: jint) {
129+
#if arch(x86_64) || arch(arm64)
122130
self.init(bitPattern: javaPrimitive)
131+
#else
132+
self.init(UInt(bitPattern: javaPrimitive))
133+
#endif
123134
}
124135

125136
public func javaPrimitive() throws -> jint {
137+
#if arch(x86_64) || arch(arm64)
126138
return jint(bitPattern: self)
139+
#else
140+
return jint(bitPattern: UInt(self))
141+
#endif
127142
}
128143
}
129144

0 commit comments

Comments
 (0)