Skip to content

Instantly share code, notes, and snippets.

@jlandure
Created December 4, 2012 15:01
Show Gist options
  • Select an option

  • Save jlandure/4204879 to your computer and use it in GitHub Desktop.

Select an option

Save jlandure/4204879 to your computer and use it in GitHub Desktop.
Gen SNI
import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.lang.StringUtils;
public class Gen {
private final static String TYPE_BUFFER = "byte[]";// "char[]"
private final static String NAME_DEFAULT_INOUT_BUFFER = "return";// "char[]"
private final static String SUFFIX_BUFFER = "Buf";
private final static String SUFFIX_METHOD = "Native";
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
LineIterator lineIterator = FileUtils
.lineIterator(new File(
"/home/actility/git/acti/jxo-jni/src/test/java/CopyOfJniXoNativeLayerSni.java"));
boolean returnString = false;
boolean hasAlreadyString = false;
boolean hasStringParameter = false;
boolean returnBoolean = false;
boolean returnInt = false;
boolean returnLong = false;
boolean returnVoid = false;
boolean exception = false;
boolean quit = false;
String line;
StringBuilder declarationBuffer = new StringBuilder();
StringBuilder setBuffer = new StringBuilder();
StringBuilder releaseBuffer = new StringBuilder();
StringBuilder callBuffer = new StringBuilder();
StringBuilder nativemethod = new StringBuilder();
//variable internes aux traitements
String[] parameterAllOneSplit = null;
while (lineIterator.hasNext()) {
line = lineIterator.nextLine();
if (StringUtils.startsWith(line, "\tpublic")
&& StringUtils.contains(line, "native")) {
String[] separatedLine = StringUtils.split(line, "(");
String declaration = separatedLine[0];
// treat declaration
declaration = StringUtils.replace(declaration, "native ", "");
if (StringUtils.contains(declaration, "String")) {
returnString = true;
} else if (StringUtils.contains(declaration, "boolean")) {
returnBoolean = true;
} else if (StringUtils.contains(declaration, "int")) {
returnInt = true;
} else if (StringUtils.contains(declaration, "long")) {
returnLong = true;
} else if (StringUtils.contains(declaration, "void")) {
returnVoid = true;
}
if (StringUtils.contains(line, "Exception")) {
exception = true;
}
if (StringUtils.contains(line, "String")) {
hasStringParameter = true;
}
if (exception || returnString || hasStringParameter) {
System.out.print(declaration);
} else {
String line2 = StringUtils.replace(line, " native ", " static native ");
line2 = StringUtils.replace(line2, "(", SUFFIX_METHOD+ "(" );
line = StringUtils.replace(line, " native ", " ");
line = StringUtils.replace(line, ";", "{\n" + line2+ "\n" +"}\n");
line = StringUtils.replace(line,"public static native int ","");
System.out.print(line);
System.out.print(line2);
quit = true;
}
if (!quit) {
callBuffer.append(StringUtils.substringAfterLast(declaration, " "))//
.append(SUFFIX_METHOD)//
.append("(");
// declaration de la methode sni
String lineNativeMethod = StringUtils.replace(declaration,
"public ", "private final native ");
lineNativeMethod = StringUtils.replace(lineNativeMethod,
"String ", "int ");
lineNativeMethod = StringUtils.replace(lineNativeMethod,
"boolean ", "int ");
nativemethod.append(lineNativeMethod)//
.append(SUFFIX_METHOD)//
.append("(");
// treat parameters
String parameters = separatedLine[1];
System.out.print("(");
if (parameters != null
&& !StringUtils.equals(parameters, ");")) {
// String toto, boolean tata
parameters = StringUtils.replace(parameters, ";", "");
String[] parametersOneToOne = StringUtils.split(
parameters, ",");
for (int p = 0; p < parametersOneToOne.length; p++) {
// String toto
String parameterAllOne = parametersOneToOne[p];
if (parameterAllOne != null) {
parameterAllOneSplit = StringUtils
.split(parameterAllOne, " ");
String type = parameterAllOneSplit[0];
String name = parameterAllOneSplit[1];
name = StringUtils.replace(name, ")", "");
if (StringUtils.contains(type, "String")) {
// on flag pour savoir si un String est
// utilisable en in out parameter
hasAlreadyString = true;
// declaration buffer
generateBufferElement(name,
declarationBuffer, releaseBuffer,
callBuffer);
generateSetBufferElement(name, setBuffer);
} else if (StringUtils.contains(type, "byte[]")) {
// on flag pour savoir si un byte[] est
// utilisable en in out parameter
hasAlreadyString = true;
callBuffer.append(name);
} else {
callBuffer.append(name);
}
System.out.print(type + " " + name);
}
if (!StringUtils.endsWith(parameterAllOne, ")")//
&& !StringUtils.endsWith(parameterAllOne,
"Exception")) {
System.out.print(", ");
callBuffer.append(", ");
} else {
// dans le cas ou on est à la fin
// on genere la declaration de la methode sni
String lineNativeMethod2 = StringUtils.substringBeforeLast(parameters, " throws");
lineNativeMethod2 = StringUtils.replace(
lineNativeMethod2, "String ", TYPE_BUFFER
+ " ");
// et s'il faut retourner un String
// supplémentaire en in out
if (returnString && !hasAlreadyString) {
lineNativeMethod2 = StringUtils.replace(
lineNativeMethod2, ")", ", "
+ TYPE_BUFFER + " "
+ NAME_DEFAULT_INOUT_BUFFER
+ SUFFIX_BUFFER + ")");
callBuffer.append(", ");
generateBufferElement(
NAME_DEFAULT_INOUT_BUFFER,
declarationBuffer, releaseBuffer,
callBuffer);
}
nativemethod.append(lineNativeMethod2)//
.append(";");
System.out.print(") ");
if(exception) {
if(parameterAllOneSplit.length == 4) {
//type name) throws Exception
System.out.print(parameterAllOneSplit[2] + " " + parameterAllOneSplit[3]);
}
}
System.out.print(" {\n");
}
}
} else {
// ou on doit générer ce qu'il faut pour un inout
// parameter
if (returnString) {
String lineNativeMethod2 = TYPE_BUFFER + " "
+ NAME_DEFAULT_INOUT_BUFFER + SUFFIX_BUFFER
+ ")";
generateBufferElement(NAME_DEFAULT_INOUT_BUFFER,
declarationBuffer, releaseBuffer,
callBuffer);
nativemethod.append(lineNativeMethod2)//
.append(";");
} else {
// pas de paramètre : on ferme pour la native method
nativemethod.append(");");
}
System.out.print(") {\n");
}
// paramètre avec string donc mapping à faire
// string à convertir
System.out.print(declarationBuffer.toString());
/*
* if (returnBoolean) {
* System.out.print("boolean returnValue = false;\n"); }
* else
*/
if (returnInt || returnBoolean || returnString) {
System.out.print("int returnValue = 0;\n");
} else if (returnLong) {
System.out.print("long returnValue = 0;\n");
}
if (declarationBuffer.length() != 0) {
System.out.print("try {\n");
System.out.print(setBuffer.toString());
}
if (returnBoolean || returnInt || returnLong
|| returnString) {
System.out.print("returnValue = ");
System.out.print(callBuffer.toString());
System.out.print(");\n");
System.out.print("if(returnValue < 0) {\n");
System.out.print("// TODO handle error\n");
if (returnBoolean) {
System.out.print("}\n");
System.out.print("// -1 error\n");
System.out.print("// 0 false\n");
System.out.print("// 1 true\n");
System.out.print("return (returnValue == 1);\n");
} else if (returnString) {
System.out.print("} else {\n");
if (!hasAlreadyString) {
System.out.print("return SNI.toJavaString("
+ NAME_DEFAULT_INOUT_BUFFER
+ SUFFIX_BUFFER + ");\n");
} else {
System.out
.print("return SNI.toJavaString(AAAA);\n");
}
System.out.print("}\n");
} else {
System.out.print("}\n");
System.out.print("return returnValue;\n");
}
} else if (returnVoid) {
System.out.print(callBuffer.toString());
System.out.print(");\n");
}
if (declarationBuffer.length() != 0) {
System.out.print("} finally {\n");
System.out.print(releaseBuffer.toString());
System.out.print("}\n");
if (returnString) {
System.out.print("return null;\n");
}
}
System.out.print("}\n\n");
// TODO vérifier comportement avec
// if (declarationBuffer.length() == 0) {
// System.out.print(StringUtils.replace(nativemethod.toString(),
// "private ", "public "));
// } else {
// }
System.out.print(nativemethod.toString() + "\n\n");
}
System.out.print("\n\n");
declarationBuffer = new StringBuilder();
setBuffer = new StringBuilder();
releaseBuffer = new StringBuilder();
callBuffer = new StringBuilder();
nativemethod = new StringBuilder();
returnString = false;
hasAlreadyString = false;
returnBoolean = false;
returnInt = false;
returnLong = false;
returnVoid = false;
quit = false;
exception = false;
hasStringParameter = false;
}
}
}
private static void generateBufferElement(String name, //
StringBuilder declarationBuffer, //
StringBuilder releaseBuffer, //
StringBuilder callBuffer) {
// declaration buffer
declarationBuffer.append(TYPE_BUFFER)//
.append(" ")//
.append(name)//
.append(SUFFIX_BUFFER)//
.append(" = (")//
.append(TYPE_BUFFER)//
.append(") buffers.newResource();\n");
releaseBuffer.append("buffers.release(")//
.append(name)//
.append(SUFFIX_BUFFER)//
.append(");\n");
callBuffer.append(name)//
.append(SUFFIX_BUFFER);
}
private static void generateSetBufferElement(String name, //
StringBuilder setBuffer) {
setBuffer.append("SNI.toCString(")//
.append(name)//
.append(", ")//
.append(name)//
.append(SUFFIX_BUFFER)//
.append(");\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment