/****************************************************************************
*
* Main.java
*
* This code is used as a driver program to demonstrate the native methods
* declared in Native.java.
*
* The countPrimes algorithm was taken from Microsoft's documentation of
* their Raw Native Interface (RNI).
*
*
*/
public class Main {
static int a, b;
static final int size = 1000000;
static final int array_size = 10000;
static final int func_calls = 1000000;
static final int rectangles = 500;
static byte[] c = new byte[size];
static byte[] d = new byte[array_size];
public static void main(String[] args)
{
String str;
long start, stop, elapsed;
int t;
int x;
byte value = 123;
// static member
Native.z = 47;
// Create an object from Native.java
Native nat = new Native();
// Print version
nat.printVersion();
// Test all data types and show that Delphi floats won't work correctly with JNI methods
// that can accept a variable number of arguments.
System.out.println("This should print out the following (but the float field will be incorrect):");
System.out.print("boolean = true, byte = 11, char = J, int = 123456, ");
System.out.println("long = 987654321, float = 47.56, double = 898.87678 ");
nat.testAllTypesD(true, (byte)11, 'J', 123456, 987654321L, 47.56F, 898.87678D);
System.out.println("\n******* Test A: Native.multiplyIntegers(3, 7)");
System.out.println("Multiply: 3 x 7 = " + nat.multiplyIntegers(3, 7));
// Simple test
System.out.println("\n******* Test 1: Native.displayHelloWorld");
nat.displayHelloWorld();
// Prints out all members of the Java Object by calling
// back into the nat object's 'toString' method
System.out.println("\n******* Test 2: Native.toStringWithPrint");
nat.toStringWithPrint();
// Prints a Java string passed in and also returns a Java string
System.out.println("\n******* Test 3: Native.printLine");
str = "This is from Java";
str = nat.printLine(str);
System.out.println("In Java code, string is: " + str);
// Prints out the w, x, y, and z members of the nat object
// all from native code
System.out.println("\n******* Test 4: Native.printWXYZ");
nat.printWXYZ();
// An array of Rectangles is created and passed to the native code
// to be printed
System.out.println("\n******* Test 5: Native.printObjectArray(Rectangle[3])");
java.awt.Rectangle[] rects = new java.awt.Rectangle[3];
for (int i = 0; i < rects.length; i++)
rects[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i);
nat.printObjectArray(rects, true);
// An array of Native objects are passed to Delphi for printing
// Demonstrates how the native method works on any 'thing' derived
// from a Java Object.
System.out.println("\n******* Test 6: Native.printObjectArray(Native[2])");
Native[] nats = new Native[2];
for (int i = 0; i < nats.length; i++)
nats[i] = new Native();
nat.printObjectArray(nats, true);
// The Delphi code allocates and initializes an array of Rectangles
// that get passed back to Java and printed here.
System.out.println("\n******* Test 7: Native.returnRectArray(3)");
java.awt.Rectangle[] rects2 = nat.returnRectArray(3);
for (int i = 0; i < rects2.length; i++)
System.out.println(rects2[i].toString());
// Some exception handling examples
// Notice that we must catch 'Throwable' objects and not
// Exception objects. It turns out that these tests are
// actually returning Error objects, but both Error and
// Exception derive from Throwable.
System.out.println("\n******* Test 8: Native.handleException");
try
{
nat.handleException();
}
catch (Throwable e)
{
System.out.println("Exception in Native code not handled: " + e);
}
System.out.println("\n******* Test 9: Native.causeException");
try
{
nat.causeException();
}
catch (Throwable e)
{
System.out.println("Exception in Native code not handled: " + e);
}
// 12-18-98
System.out.println("\n******* Test 10: Native.pass2DByteArray(array2D)");
int dim1 = 2, dim2 = 3;
byte count = 0;
byte[][] array2D = new byte[dim1][dim2];
for (int i = 0; i < dim1; i++)
for (int j = 0; j < dim2; j++)
array2D[i][j] = ++count;
// Call Native code to initialize an array to a specific value many times
nat.pass2DByteArray(array2D);
System.out.println("\nIn Java printing array that was changed by native method.");
for (int i = 0; i < dim1; i++)
for (int j = 0; j < dim2; j++)
System.out.println(i + "," + j + " = " + array2D[i][j]);
System.out.println("\n\n********** Timings **********\n");
System.out.print("Native countPrimes up to " + size + " ....");
start = System.currentTimeMillis();
nat.countPrimes(c);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
System.out.print(" Java countPrimes up to " + size + " ....");
start = System.currentTimeMillis();
countPrimes(c);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Call a Native 'void func(void)'
System.out.print("Native function calls " + func_calls + " ....");
start = System.currentTimeMillis();
for (x = 0; x < func_calls; x++)
nat.VoidVoid();
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Call a Java method 'void method(void)'
System.out.print(" Java function calls " + func_calls + " ....");
start = System.currentTimeMillis();
for (x = 0; x < func_calls; x++)
VoidVoid();
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
t = 1000;
// Call Native code to initialize an array to a specific value many times
System.out.print("Native initialize array[" + array_size + "] " + t + " times ....");
start = System.currentTimeMillis();
nat.initializeByteArray(d, t, value);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Initialize an array to a specific value many times within Java
System.out.print(" Java initialize array[" + array_size + "] " + t + " times ....");
start = System.currentTimeMillis();
for (int i = 0; i < t; i++)
for (int j = 0; j < d.length; j++)
d[j] = value;
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// From native code, call a constructor for a Java object many times
java.awt.Rectangle[] rects4 = new java.awt.Rectangle[rectangles];
for (int i = 0; i < rects4.length; i++)
rects4[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i);
System.out.print("Native callbacks into Java constructor " + rectangles + " rectangles ....");
start = System.currentTimeMillis();
nat.printObjectArray(rects4, false);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Call a constructor from Java many times
java.awt.Rectangle[] rects5 = new java.awt.Rectangle[rectangles];
for (int i = 0; i < rects5.length; i++)
rects5[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i);
System.out.print("Java method calls to constructor " + rectangles + " rectangles ....");
start = System.currentTimeMillis();
printObjectArray(rects5, false);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Call a Java 'void method(void)' from Native code many times
System.out.print("Native callbacks to Java void method " + func_calls + " ....");
start = System.currentTimeMillis();
nat.callbackVoid(func_calls);
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
// Call a Native 'void func(void)' from Java many times
System.out.print("Java calls to Native void function " + func_calls + " ....");
start = System.currentTimeMillis();
for (x = 0; x < func_calls; x++)
nat.VoidVoid();
stop = System.currentTimeMillis();
elapsed = stop - start;
System.out.println(" " + elapsed + " milliseconds");
}
// Test method for function-call overhead
public static void VoidVoid()
{
return;
}
// Sieving prime numbers
public static long countPrimes(byte[] array)
{
int count = 0;
int i;
for (i = 0; i < array.length; i++)
array[i] = 1;
for (i = 2; i < array.length; i++)
{
if (array[i] != 0)
{
int k;
for (k = i + i; k < array.length; k += i)
array[k] = 0;
count++;
}
}
return count;
}
public static java.awt.Rectangle[] returnRectArray(int size)
{
// Allocate the array of Rectangles
java.awt.Rectangle[] array = new java.awt.Rectangle[size];
// Now initialize each one to a Rectangle
for (int i = 0; i < size; i++)
{
// Create a new Rectangle object
java.awt.Rectangle element = new java.awt.Rectangle(0, 0, 5 * i, 10 * i);
// Assign the Rectangle to an element of the array
array[i] = element;
}
// Return whole array to caller
return array;
}
public static void printObjectArray(Object[] objArray, boolean Print)
{
// Loop the the array of objects and print out each one using
// the 'toString' method of its ancestor class Object
for (int i = 0; i < objArray.length; i++)
{
String s = objArray[i].toString();
if (Print)
System.out.println(s);
}
}
}