Pivot to a handled API, update common js and native generators

This commit is contained in:
Ugljesa Jovanovic authored and Ugljesa Jovanovic committed 2020-08-08 16:20:56 +02:00
1 parent d8b92a6970
commit 1f0eaf59ca
12 files changed
+419 -258

No files matched your search

@@ -35,9 +35,13 @@ class ClassDefinition(
operator fun FunctionDefinition.unaryPlus() {
methods.add(this)
}
operator fun List<FunctionDefinition>.unaryPlus() {
methods.addAll(this)
}
}
class InnerClassDefinition (
class InnerClassDefinition(
val name: String,
val javaName: String,
val jsName: String,
@@ -51,7 +55,10 @@ class FunctionDefinition(
val jsName: String,
val nativeName: String,
val parameterList: MutableList<ParameterDefinition> = mutableListOf(),
val returnType: GeneralTypeDefinition
val returnType: GeneralTypeDefinition,
val dynamicJsReturn: Boolean = false,
val isStateCreationFunction: Boolean = false,
val outputLengthWhenArray: Int = -1
) {
operator fun ParameterDefinition.unaryPlus() {
parameterList.add(this)
@@ -61,11 +68,14 @@ class FunctionDefinition(
class ParameterDefinition(
val parameterName: String,
val parameterType: GeneralTypeDefinition,
val modifiesReturn: Boolean = false
val modifiesReturn: Boolean = false,
val isActuallyAnOutputParam: Boolean = false,
val isStateType: Boolean = false,
val dropParameterFromDefinition: Boolean = false,
)
interface GeneralTypeDefinition {
val typeName : TypeName
val typeName: TypeName
}
data class CustomTypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition
@@ -80,7 +90,7 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti
UNIT(Unit::class.asTypeName())
}
fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit) : KotlinFileDefinition {
fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefinition {
val commonKotlinFileInstance = KotlinFileDefinition(name)
commonKotlinFileInstance.body()
return commonKotlinFileInstance
@@ -99,7 +109,7 @@ fun innerClassDef(
jsName: String,
nativeName: String,
body: InnerClassDefinition.() -> Unit = {}
) : InnerClassDefinition {
): InnerClassDefinition {
val genClass = InnerClassDefinition(
name,
javaName,
@@ -116,9 +126,21 @@ fun funcDef(
jsName: String,
nativeName: String,
returnType: GeneralTypeDefinition,
dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1,
body: FunctionDefinition.() -> Unit
): FunctionDefinition {
val function = FunctionDefinition(name, javaName, jsName, nativeName, returnType = returnType)
val function = FunctionDefinition(
name,
javaName,
jsName,
nativeName,
returnType = returnType,
dynamicJsReturn = dynamicJsReturn,
isStateCreationFunction = isStateCreationFunction,
outputLengthWhenArray = outputLengthWhenArray
)
function.body()
return function
}
@@ -126,9 +148,22 @@ fun funcDef(
fun funcDef(
name: String,
returnType: GeneralTypeDefinition,
dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1,
body: FunctionDefinition.() -> Unit
): FunctionDefinition {
val function = FunctionDefinition(name, name, name, name, returnType = returnType)
val function =
FunctionDefinition(
name,
name,
name,
name,
returnType = returnType,
dynamicJsReturn = dynamicJsReturn,
isStateCreationFunction = isStateCreationFunction,
outputLengthWhenArray = outputLengthWhenArray
)
function.body()
return function
}
@@ -8,82 +8,8 @@ package com.ionspin.kotlin.crypto.generator.libsodium.definitions
object LibSodiumDefinitions {
val testKotlinFile = fileDef("DebugTest") {
+classDef("Crypto") {
/*
--------------- SHA256
*/
+innerClassDef(
"Sha256State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State256",
"Sha256State",
"crypto_hash_sha256_state"
)
+funcDef(
"crypto_hash_sha256_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
}
+funcDef("crypto_hash_sha256_update", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha256_final", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE)
}
/*
--------------- SHA512
*/
+innerClassDef(
"Sha512State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State512",
"Sha512State",
"crypto_hash_sha512_state"
)
+funcDef(
"crypto_hash_sha512_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
}
+funcDef("crypto_hash_sha512_update", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha512_final", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE)
}
/*
* ------------- GENERIC HASH (BLAKE2B)
*/
+innerClassDef(
"GenericHashState",
"ByteArray",
"Uint8Array",
"crypto_generichash_blake2b_state"
)
+funcDef(
"crypto_generichash_init",
TypeDefinition.INT
) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("GenericHashState"))))
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true)
}
defineHashFunctions()
defineGenericHashFunctions()
}
}
}
@@ -0,0 +1,37 @@
package com.ionspin.kotlin.crypto.generator.libsodium.definitions
import com.squareup.kotlinpoet.ClassName
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 04-Aug-2020
*/
fun ClassDefinition.defineGenericHashFunctions() {
/*
* ------------- GENERIC HASH (BLAKE2B)
*/
+innerClassDef(
"GenericHashState",
"ByteArray",
"Uint8Array",
"crypto_generichash_blake2b_state"
)
+funcDef(
"crypto_generichash_init",
CustomTypeDefinition(ClassName(packageName, "GenericHashState")),
true,
isStateCreationFunction = true
) {
+ParameterDefinition(
"state",
CustomTypeDefinition((withPackageName("GenericHashState"))),
isStateType = true,
dropParameterFromDefinition = true
)
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true)
}
}
@@ -0,0 +1,80 @@
package com.ionspin.kotlin.crypto.generator.libsodium.definitions
import com.squareup.kotlinpoet.ClassName
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 04-Aug-2020
*/
fun ClassDefinition.defineHashFunctions() {
/*
--------------- SHA256
*/
+innerClassDef(
"Sha256State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State256",
"Sha256State",
"crypto_hash_sha256_state"
)
+funcDef(
"crypto_hash_sha256_init",
CustomTypeDefinition(ClassName(packageName, "Sha256State")),
dynamicJsReturn = true,
isStateCreationFunction = true
) {
+ParameterDefinition(
"state",
CustomTypeDefinition((withPackageName("Sha256State"))),
dropParameterFromDefinition = true,
isStateType = true
)
}
+funcDef("crypto_hash_sha256_update", TypeDefinition.UNIT) {
+ParameterDefinition(
"state",
CustomTypeDefinition((withPackageName("Sha256State"))),
isStateType = true
)
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha256_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 32) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true)
}
/*
--------------- SHA512
*/
+innerClassDef(
"Sha512State",
"com.goterl.lazycode.lazysodium.interfaces.Hash.State512",
"Sha512State",
"crypto_hash_sha512_state"
)
+funcDef(
"crypto_hash_sha512_init",
CustomTypeDefinition(ClassName(packageName, "Sha512State")),
true,
isStateCreationFunction = true
) {
+ParameterDefinition(
"state",
CustomTypeDefinition((withPackageName("Sha512State"))),
dropParameterFromDefinition = true,
isStateType = true
)
}
+funcDef("crypto_hash_sha512_update", TypeDefinition.UNIT) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE)
}
+funcDef("crypto_hash_sha512_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 64) {
+ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State"))))
+ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true)
}
}
@@ -51,12 +51,24 @@ object CommonLibsodiumGenerator {
fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec {
val methodBuilder = FunSpec.builder(methodDefinition.name)
var actualReturnType : TypeName = Any::class.asTypeName()
var actualReturnTypeFound : Boolean = false
for (paramDefinition in methodDefinition.parameterList) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.dropParameterFromDefinition.not()) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
}
if (paramDefinition.isActuallyAnOutputParam) {
actualReturnTypeFound = true
actualReturnType = paramDefinition.parameterType.typeName
}
}
if (actualReturnTypeFound) {
methodBuilder.returns(actualReturnType)
} else {
methodBuilder.returns(methodDefinition.returnType.typeName)
}
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
@@ -14,6 +14,7 @@ object JsLibsodiumGenerator {
fun createJsFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec {
val fileBuilder = FileSpec.builder(packageName, fileDefinition.name)
fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array")
fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray")
fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium")
for (commonClassDefinition in fileDefinition.commonClassList) {
//Create type-aliases
@@ -48,10 +49,14 @@ object JsLibsodiumGenerator {
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false
var returnModifierName = ""
var actualReturnType: TypeName = DYNAMIC
var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
}
if (paramDefinition.modifiesReturn) {
if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found")
@@ -59,53 +64,51 @@ object JsLibsodiumGenerator {
returnModifierFound = true
returnModifierName = paramDefinition.parameterName
}
if (paramDefinition.isActuallyAnOutputParam) {
actualReturnTypeFound = true
actualReturnType = paramDefinition.parameterType.typeName
}
}
methodBuilder.addStatement("println(\"Debug\")")
val constructJsCall = StringBuilder()
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()")
}
TypeDefinition.INT -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append(paramsToString(methodDefinition))
}
TypeDefinition.UNIT -> {
constructJsCall.append("getSodium().${methodDefinition.javaName}")
constructJsCall.append(paramsToString(methodDefinition))
}
is CustomTypeDefinition -> {
constructJsCall.append("return getSodium().${methodDefinition.javaName}")
constructJsCall.append(paramsToString(methodDefinition))
}
}
methodBuilder.addStatement(constructJsCall.toString())
if (actualReturnTypeFound) {
methodBuilder.returns(actualReturnType)
return methodBuilder.build()
}
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
if (methodDefinition.dynamicJsReturn) {
methodBuilder.returns(Dynamic)
} else {
methodBuilder.returns(methodDefinition.returnType.typeName)
}
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.UNIT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
fun paramsToString(methodDefinition: FunctionDefinition) : String {
fun paramsToString(methodDefinition: FunctionDefinition): String {
val paramsBuilder = StringBuilder()
paramsBuilder.append("(")
methodDefinition.parameterList.forEachIndexed { index, paramDefinition ->
val separator = if (index == methodDefinition.parameterList.size - 1) {
val jsParams = methodDefinition.parameterList.filter { it.dropParameterFromDefinition.not() }
jsParams.forEachIndexed { index, paramDefinition ->
val separator = if (index == jsParams.size - 1) {
""
} else {
", "
@@ -114,12 +117,12 @@ object JsLibsodiumGenerator {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
if (paramDefinition.parameterType is TypeDefinition) {
when(paramDefinition.parameterType) {
when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + paramDefinition.parameterName + ".size" + separator)
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + paramDefinition.parameterName + ".size.toLong()" + separator)
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator)
@@ -136,11 +139,11 @@ object JsLibsodiumGenerator {
}
}
}
paramsBuilder.append(')')
return paramsBuilder.toString()
}
}
@@ -62,42 +62,27 @@ object JvmLibsodiumGenerator {
}
}
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
TypeDefinition.INT -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
TypeDefinition.UNIT -> {
constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
is CustomTypeDefinition -> {
constructJvmCall.append("return sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
}
}
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.UNIT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
@@ -1,7 +1,19 @@
package com.ionspin.kotlin.crypto.generator.libsodium.generator
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.*
import com.squareup.kotlinpoet.*
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition
import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeAliasSpec
import com.squareup.kotlinpoet.asTypeName
/**
* Created by Ugljesa Jovanovic
@@ -18,6 +30,9 @@ object NativeLibsodiumGenerator {
fileBuilder.addImport("kotlinx.cinterop", "ptr")
fileBuilder.addImport("kotlinx.cinterop", "pin")
fileBuilder.addImport("kotlinx.cinterop", "addressOf")
fileBuilder.addImport("kotlinx.cinterop", "reinterpret")
fileBuilder.addImport("kotlinx.cinterop", "pointed")
fileBuilder.addImport("libsodium", "sodium_malloc")
for (commonClassDefinition in fileDefinition.commonClassList) {
//Create type-aliases
@@ -33,7 +48,7 @@ object NativeLibsodiumGenerator {
//Workarounds for native not emitting types
val byteEmitter = PropertySpec.builder("_emitByte", Byte::class.asTypeName())
byteEmitter.initializer(CodeBlock.of("0"))
val byteArrayEmitter = PropertySpec.builder("_emitByteArray", Byte::class.asTypeName())
val byteArrayEmitter = PropertySpec.builder("_emitByteArray", ByteArray::class.asTypeName())
byteArrayEmitter.initializer(CodeBlock.of("ByteArray(0) {}"))
commonClassSpec.addProperty(byteEmitter.build())
commonClassSpec.addProperty(byteArrayEmitter.build())
@@ -60,10 +75,17 @@ object NativeLibsodiumGenerator {
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false
var returnModifierName = ""
lateinit var actualReturnParameterDefinition: ParameterDefinition
var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) {
createStateParam(paramDefinition, methodBuilder)
}
if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) {
val parameterSpec =
ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName)
methodBuilder.addParameter(parameterSpec.build())
}
if (paramDefinition.modifiesReturn) {
if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found")
@@ -71,52 +93,103 @@ object NativeLibsodiumGenerator {
returnModifierFound = true
returnModifierName = paramDefinition.parameterName
}
if (paramDefinition.isActuallyAnOutputParam) {
actualReturnParameterDefinition = paramDefinition
actualReturnTypeFound = true
}
}
if (actualReturnTypeFound) {
if (returnModifierFound) {
createOutputParam(actualReturnParameterDefinition, returnModifierName, methodBuilder)
} else {
if (methodDefinition.outputLengthWhenArray == -1) {
throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}")
}
createOutputParam(actualReturnParameterDefinition, methodDefinition.outputLengthWhenArray.toString(), methodBuilder)
}
}
pinParams(methodDefinition, methodBuilder)
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
if (methodDefinition.returnType == TypeDefinition.UNIT) {
val constructNativeCall = StringBuilder()
val constructNativeCall = StringBuilder()
if (methodDefinition.isStateCreationFunction) {
constructNativeCall.append("libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return state")
} else if (actualReturnTypeFound) {
constructNativeCall.append("libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return out")
} else {
when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return result")
}
TypeDefinition.INT -> {
constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return result")
}
TypeDefinition.UNIT -> {
constructNativeCall.append("libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
}
is CustomTypeDefinition -> {
constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return result")
}
}
}
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return libsodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
}
unpinParams(methodDefinition, methodBuilder)
methodBuilder.returns(methodDefinition.returnType.typeName)
return methodBuilder.build()
}
fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) {
/*
val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!!
state = allocated.reinterpret<crypto_hash_sha256_state>().pointed
*/
methodBuilder.addStatement("val allocated = sodium_malloc(${stateParameterDefinition.parameterType.typeName}.size.convert())!!")
methodBuilder.addStatement("val state = allocated.reinterpret<${stateParameterDefinition.parameterType.typeName}>().pointed")
}
fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) {
/*
val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES)
val hashResultPinned = hashResult.pin()
crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0))
sodium_free(state.ptr)
return hashResult
*/
when (outputParam.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
methodBuilder.addStatement("val out = UByteArray($length)")
}
else -> {
throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}")
}
}
}
fun pinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) {
methodDefinition.parameterList.forEachIndexed { index, paramDefinition ->
if (paramDefinition.parameterType is TypeDefinition) {
@@ -188,10 +261,10 @@ object NativeLibsodiumGenerator {
if (paramDefinition.parameterType is TypeDefinition) {
when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), "+ paramDefinition.parameterName + ".size.convert()" + separator)
paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), "+ paramDefinition.parameterName + ".size.convert()" + separator)
paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0)" + separator)