JNA: How to access array of struct in struct? - arrays

I'm trying to access an array of struct inside a struct. This is the relevant C code reduced to the problem:
typedef struct {
int a;
int b;
} fileinfo_t;
typedef struct {
fileinfo_t **file;
int max_files;
} project_t;
In C accessing the array is as easy as this:
int var_a_of_file_0 = project.file[0].a;
int var_b_of_file_1 = project.file[1].b;
How do I implement this in Java? I'm asking this question because I'm new to JNA. So far I read the JNA documentation and tried every example which is somehow related to my problem but with no luck...
I used JNAerator for converting the header file. I don't know for shure if the result is correct:
package test;
import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
import com.ochafik.lang.jnaerator.runtime.Structure;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.ptr.PointerByReference;
/**
* JNA Wrapper for library <b>test</b><br>
* This file was autogenerated by JNAerator,<br>
* a tool written by Olivier Chafik that uses a few opensource projects..<br>
* For help, please visit NativeLibs4Java , Rococoa, or JNA.
*/
public interface TestLibrary extends Library {
public static final java.lang.String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("test", true, test.TestLibrary.class);
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(test.TestLibrary.JNA_LIBRARY_NAME, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
public static final TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary(test.TestLibrary.JNA_LIBRARY_NAME, test.TestLibrary.class, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
public static class fileinfo_t extends Structure<fileinfo_t, fileinfo_t.ByValue, fileinfo_t.ByReference > {
public int a;
public int b;
public fileinfo_t() {
super();
}
public fileinfo_t(int a, int b) {
super();
this.a = a;
this.b = b;
}
protected ByReference newByReference() { return new ByReference(); }
protected ByValue newByValue() { return new ByValue(); }
protected fileinfo_t newInstance() { return new fileinfo_t(); }
public static fileinfo_t[] newArray(int arrayLength) {
return Structure.newArray(fileinfo_t.class, arrayLength);
}
public static class ByReference extends fileinfo_t implements Structure.ByReference {
};
public static class ByValue extends fileinfo_t implements Structure.ByValue {
};
};
public static class project_t extends Structure<project_t, project_t.ByValue, project_t.ByReference > {
/// C type : fileinfo_t**
public PointerByReference file;
public int max_files;
public project_t() {
super();
}
/// #param file C type : fileinfo_t**
public project_t(PointerByReference file, int max_files) {
super();
this.file = file;
this.max_files = max_files;
}
protected ByReference newByReference() { return new ByReference(); }
protected ByValue newByValue() { return new ByValue(); }
protected project_t newInstance() { return new project_t(); }
public static project_t[] newArray(int arrayLength) {
return Structure.newArray(project_t.class, arrayLength);
}
public static class ByReference extends project_t implements Structure.ByReference {
};
public static class ByValue extends project_t implements Structure.ByValue {
};
};
}
Any help would be appreciated.

Since the array of structs does not overlay the containing struct's memory, you need a Pointer or equivalent type for that field. You can then manually derive the structure you need from the base pointer.
I don't think your usage example is valid, however.
Once you index with "[0]", you have a pointer to fileinfo_t, so you would have to use the following (have you actually compiled your example in C?):
int var_a_of_file_0 = project.file[0]->a;
int var_b_of_file_1 = project.file[1]->b;
Ultimately how you extract the actual structures depends on how they are laid out in memory, which is ambiguous in your current explanation.

Related

inheritance , enhanced loop and arraylist not running properly

I'm trying to put together a few things here and it isn't working correctly. I thought that each time through the loop, the loop would update and inherit for each class member. Instead, it is printing the "member" method 4 times.
import java.util.ArrayList;
public class toolband
{
public static void noise()
{
System.out.println("abc");
}
static class member extends toolband
{
public static void noise()
{
System.out.println("xyz");
}
}
static class maynard extends member
{
String namemaynard = "maynard";
public static void noise()
{
System.out.println("pow pow");
}
}
static class adam extends member
{
String nameadam = "adam";
public static void noise()
{
System.out.println("da dun da dun");
}
}
static class danny extends member
{
String namedanny = "danny";
public static void noise()
{
System.out.println("smash smash smash");
}
}
static class justin extends member
{
String namejustin = "justin";
public static void noise()
{
System.out.println("womp wa wa wo wo womp");
}
}
public static void main (String [] args)
{
ArrayList <member> members = new ArrayList <member> (4);
member m = new maynard();
member a = new adam();
member d = new danny();
member j = new justin();
members.add(m);
members.add(a);
members.add(d);
members.add(j);
for (member i : members)
i.noise();
}
}
Can someone help me understand what I am doing incorrectly. Should I be making these all static methods?
The problem is that noise method in toolband is static.In java static method is not overriden.
To make this work change noise method signature to public void noise() and same in the subclasses which override and it works.
public class toolband {
public void noise() {
System.out.println("abc");
}
}
class member extends toolband {
public void noise() {
System.out.println("xyz");
}
}
class maynard extends member {
String namemaynard = "maynard";
public void noise() {
System.out.println("pow pow");
}
}
class adam extends member {
String nameadam = "adam";
public void noise() {
System.out.println("da dun da dun");
}
}
class danny extends member {
String namedanny = "danny";
public void noise() {
System.out.println("smash smash smash");
}
}
class justin extends member {
String namejustin = "justin";
public void noise() {
System.out.println("womp wa wa wo wo womp");
}
}

testng how to dynamically set groups from Factory?

Before I setup a test class like the code below:
1. the Factory and test Dataprovider both used excel as the dataprovider.
2. In the Factory dataprovider table, it has a list of url
3. Each time, it will find one of the url in the factory dataprovider table, and run the test in each test methods..
public class Test {
WebDriver driver;
private String hostName;
private String url;
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url) {
this.hostName = hostName;
this.url = url;
}
#BeforeMethod
#Parameters("browser")
public void start(String browser) throws Exception {
driver = new FirefoxDriver();
driver.get(url);
Thread.sleep(1000);
}
#Test(priority = 10, dataProvider = "dataprovider Test A", dataProviderClass = xxx.class)
public void TestA(Variable1,
Variable2,Variable3) throws Exception {
some test here...
}
#Test(priority = 20, dataProvider = "dataprovider Test B", dataProviderClass = xxx.class)
public void TestB(Variable1,
Variable2,Variable3)
throws Exception {
some test here...
}
#AfterMethod
public void tearDown() {
driver.quit();
}
Now I want to dynamically assign different group for each test for different url. I am thinking add a variable 'flag' in the #Factory dataprovider:
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url, String flag) {
this.hostName = hostName;
this.url = url;
this.flag = flag;
}
That when flag.equals("A"), it will only run test cases in test groups={"A"}.
When flag.equals("B"), it will only run test cases in test groups ={"B"},
When flag.equals("A,B"), it will only run test cases in test groups ={"A","B"}
Is there any way I can do that?
Thank you!
TestNG groups provides "flexibility in how you partition your tests" but it isn't for conditional test sets. For that you simply use plain old Java.
You can use inheritance or composition (I recommend the latter, see Item 16: Favor composition over inheritance from Effective Java).
Either way the general idea is the same: use a Factory to create your test class instances dynamically creating the appropriate class type with the appropriate test annotations and/or methods that you want to run.
Examples:
Inheritance
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
/**
* Base test class with code for both A-tests and B-tests.
*
* Note that none of these test methods are annotated as tests so that
* subclasses may pick which ones to annotate.
*/
public static abstract class BaseTest {
protected void testA() {
// test something specific to flavor A
}
protected void testB() {
// test something specific to flavor B
}
}
// extend base but only annotate A-tests
public static class FlavorATest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
}
// extend base but only annotate B-tests
public static class FlavorBTest extends BaseTest {
#Test
#Override
public void testB() {
super.testB();
}
}
// extend base and annotate both A-tests and B-tests
public static class FlavorABTest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
#Test
#Override
public void testB() {
super.testB();
}
}
}
Composition
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
private static void testA() {
// test something specific to flavor A
}
private static void testB() {
// test something specific to flavor B
}
// only create A-test methods and delegate to shared code above
public static class FlavorATest {
#Test
public void testA() {
DemoTest.testA();
}
}
// only create B-test methods and delegate to shared code above
public static class FlavorBTest {
#Test
public void testB() {
DemoTest.testB();
}
}
// create A-test and B-test methods and delegate to shared code above
public static class FlavorABTest {
#Test
public void testA() {
DemoTest.testA();
}
#Test
public void testB() {
DemoTest.testB();
}
}
}
Your factory methods won't be as simple as you'll need to use your "flag" from your test data to switch off of and create instances of the appropriate test classes.

implementing the comparable interface for the type File to sort by length of the filename

I would like to define a new class FileSorter that extends the type File and implements the comparable interface by defining a compareTo() to sort by the length of the filename.
public class FileSorter extends File implements Comparable<File>
{
private int size;
public FileSorter(String pathname)
{
super(pathname);
// TODO Auto-generated constructor stub
}
public int compareTo(File b)
{
if (this.length() == b.length())
return 0;
else if (this.length() > b.length())
return 1;
else
return -1;
}
}
public class FileSorterDemo {
public static void main(String[] args)
{
FileSorter directory = new FileSorter(args[0]);
FileSorter[] files = ((FileSorter) directory).listFiles();
Arrays.sort(files);
for (int i = 0; i < files.length; i++)
System.out.println(files[i].getName());
}
}
I got the following working solution using comparator. Is this acceptable?
Can this be implemented using Comparable Interface?
import java.io.File;
import java.util.*;
public class FileSortByFilenameLength implements Comparator<File>
{
#Override
public int compare(File arg0, File arg1) {
// TODO Auto-generated method stub
if (arg0.getName().length() > arg1.getName().length())
return 1;
else if (arg0.getName().length() < arg1.getName().length())
return -1;
else
return 0;
}
}
public class FileSorterDemo {
public static void main(String[] args)
{
File directory = new File(args[0]);
File[] files = directory.listFiles();
Arrays.sort(files, new FileSortByFilenameLength());
for (int i = 0; i < files.length; i++)
System.out.println(files[i].getName() + " - " + files[i].getName().length());
}
}

actionscript 3 - using array in multiple classes

So I have 2 files, where I want to be able to access an array from 1 file in the other.
package code {
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.ui.Keyboard;
import code.*;
public class Init extends MovieClip {
public var _solidObjects: Array;
public function Init() {
_solidObjects = [wall01, wall02, wall03, wall04];
}
}
}
How would I be able to access the _solidObjects array from another class in a seperate file?
Any help would be appreciated as I have been trying for a while with no success, thanks.
Constructors can be passed variables. For example:
First class:
package code {
public class Init extends MovieClip {
public var solidObjects: Array;
public function Init() {
solidObjects = [wall01, wall02, wall03, wall04];
}
}
Second class:
package code {
public class SomeClass extends MovieClip {
public var solidObjects: Array;
public function SomeClass(param:Array) {
this.solidObjects = param;
}
}
}
Usage context:
var initObj:Init = new Init();
var secondObject:SomeClass = new SomeClass(initObj.solidObjects);

Encapsulation in Java when returning an object

Consider below example:
public class sample{
private Map myMap;
public Map getMap(){
return myMap;
}
}
In above example, we are returning the map to some other calling class. So my question is how we can say that this class encapsulates/protects its data. The Map that will be returned will be available for modification by other classes.
Thanks,
Rajan
Consider this class Person, which have 2 attributes (name and age).
package app;
/**
*
* #author salathielgenese
*/
public final class Person
{
public Person()
{
setAge(age);
setName(name);
}
public Person(String name, long age)
{
setName(name);
setAge(age);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public long getAge()
{
return age;
}
public void setAge(long age)
{
this.age = age;
}
private String name;
private long age;
}
Now imagine that some one (let say the calling class) set the age to -19. This will generate inconsistency in your that.
So when you protect your data, your controlling wich kind of action are made possible these data.
You may decide that if the given age is lower than 0 then the age will be set to 0 for example. The code may become...
public void setAge(long age)
{
this.age = age;
if (age < 0)
{
this.age = 0;
}
}
You can do the same with name attribute to prevent setting it to null.
public void setName(String name)
{
this.name = name;
if (name == null || name == "")
{
this.name = "NO NAME";
}
}
We'll say that encapsulation help protecting data.
··························································································
Now let's imagine a class called Carpenter. When you need a table, you just ask it to him. Thus the Carpenter class should provide a method which takes a description of the table you need, and return the build table. Assuming that the method is called buildTable, this method will be declared with public access because it's useful to call it from another Class.
When you ask to the Carpenter to build up your Table, he will need to check some material as well as saw, needle and so on and so far. We (calling class) don't care about this internal mechanism and all methods as well as attributes involved in this process will be declared with private access. i.e to prevents external classes from modifying them, i.e to encapsulate our fields and methods for better protection.
Encapsulating a field let us control access to our data.
Comming back to your code, giving public access to getMap() doesn't prevent calling class to modify its content.
Now look at this Example
Person.java
package app;
/**
*
* #author salathielgenese
*/
public final class Person
{
public Person()
{
setAge(age);
setName(name);
}
public Person(String name, long age)
{
setName(name);
setAge(age);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
if (name == null || name == "")
{
this.name = "NO NAME";
}
}
public long getAge()
{
return age;
}
public void setAge(long age)
{
this.age = age;
if (age < 0)
{
this.age = 0;
}
}
#Override
public String toString()
{
return "Person{" + "name=" + name + ", age=" + age + '}';
}
private String name;
private long age;
}
Example.java
package app;
/**
*
* #author salathielgenese
*/
public class Example
{
public Example()
{
}
public Example(Person person)
{
this.person = person;
}
public Person getPerson()
{
return person;
}
public void setPerson(Person person)
{
this.person = person;
}
private Person person;
}
**Main class (Loader.java)
package app;
/**
*
* #author salathielgenese
*/
public class Loader
{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// Instantiate an Example with a new created Person
Example example = new Example(new Person("Rajan", 19));
// Retrive person in example and print its description (printing result of implicit call to person.toString() )
Person person = example.getPerson();
System.out.println(person);
// Assigning a new reference to the variable **person** and print its description
person = new Person("Salathiel", 20);
System.out.println(person);
// Print description of Person containning in Example instance
System.out.println(example.getPerson());
}
}
If you look closed this code, you'll understand that you can change attribute of your Map but not the reference to it.
Maybe you can use an unmodifiable map from Java Collection API's :
public class sample{
private Map myMap;
public Map getMap(){
return Collections.unmodifiableMap(myMap));
}
}

Resources