///|
/// An internal JVM binary class name, for example `java/lang/String`.
pub struct JniClass {
priv internal_name : String
} derive(Eq, Debug)
///|
pub fn JniClass::parse(internal_name : String) -> JniClass raise JniError {
if internal_name.is_empty() ||
internal_name.has_prefix("/") ||
internal_name.has_suffix("/") ||
internal_name.contains("//") ||
internal_name.contains(".") ||
internal_name.contains(";") ||
internal_name.contains("[") ||
internal_name.contains_code_unit(0) {
raise InvalidClassName(internal_name)
}
{ internal_name, }
}
///|
pub fn JniClass::internal_name(self : JniClass) -> String {
self.internal_name
}
///|
pub fn JniClass::descriptor(self : JniClass) -> String {
"L\{self.internal_name};"
}
///|
/// A non-void JNI value type. Its parameter-slot width is retained so method
/// descriptors cannot undercount `long` and `double`.
pub struct JniType {
priv descriptor : String
priv parameter_slots : Int
priv array_dimensions : Int
} derive(Eq, Debug)
///|
pub fn JniType::boolean() -> JniType {
{ descriptor: "Z", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::byte() -> JniType {
{ descriptor: "B", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::char() -> JniType {
{ descriptor: "C", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::short() -> JniType {
{ descriptor: "S", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::int() -> JniType {
{ descriptor: "I", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::long() -> JniType {
{ descriptor: "J", parameter_slots: 2, array_dimensions: 0 }
}
///|
pub fn JniType::float() -> JniType {
{ descriptor: "F", parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::double() -> JniType {
{ descriptor: "D", parameter_slots: 2, array_dimensions: 0 }
}
///|
pub fn JniType::object(class : JniClass) -> JniType {
{ descriptor: class.descriptor(), parameter_slots: 1, array_dimensions: 0 }
}
///|
pub fn JniType::array(element : JniType) -> JniType raise JniError {
if element.array_dimensions >= 255 {
raise TooManyArrayDimensions
}
{
descriptor: "[\{element.descriptor}",
parameter_slots: 1,
array_dimensions: element.array_dimensions + 1,
}
}
///|
pub fn JniType::descriptor(self : JniType) -> String {
self.descriptor
}
///|
/// A validated JVM method descriptor. The default return type is `void`.
pub struct JniMethod {
priv descriptor : String
} derive(Eq, Debug)
///|
pub fn JniMethod::new(
parameters : ArrayView[JniType],
return_type? : JniType,
) -> JniMethod raise JniError {
let mut descriptor = "("
let mut parameter_slots = 0
for parameter in parameters {
parameter_slots += parameter.parameter_slots
if parameter_slots > 255 {
raise TooManyParameterSlots
}
descriptor += parameter.descriptor
}
descriptor += ")"
descriptor += match return_type {
Some(value) => value.descriptor
None => "V"
}
if descriptor.length() > 65535 {
raise DescriptorTooLong
}
{ descriptor, }
}
///|
pub fn JniMethod::descriptor(self : JniMethod) -> String {
self.descriptor
}
///|
/// A native-method registration declaration without a raw function pointer.
pub struct NativeMethod {
priv name : String
priv signature : JniMethod
} derive(Eq, Debug)
///|
pub fn NativeMethod::new(
name : String,
signature : JniMethod,
) -> NativeMethod raise JniError {
if name.is_empty() ||
name.contains("/") ||
name.contains(".") ||
name.contains(";") ||
name.contains("[") ||
name.contains("<") ||
name.contains(">") ||
name.contains_code_unit(0) {
raise InvalidNativeMethodName(name)
}
{ name, signature }
}
///|
pub fn NativeMethod::name(self : NativeMethod) -> String {
self.name
}
///|
pub fn NativeMethod::descriptor(self : NativeMethod) -> String {
self.signature.descriptor()
}