001    /*******************************************************************************
002     * Copyright (c) 2009 Progress Software, Inc.
003     * 
004     * All rights reserved. This program and the accompanying materials
005     * are made available under the terms of the Eclipse Public License v1.0
006     * which accompanies this distribution, and is available at
007     * http://www.eclipse.org/legal/epl-v10.html
008     *******************************************************************************/
009    package test;
010    
011    import java.util.Arrays;
012    
013    import org.fusesource.hawtjni.runtime.ClassFlag;
014    import org.fusesource.hawtjni.runtime.JniArg;
015    import org.fusesource.hawtjni.runtime.JniClass;
016    import org.fusesource.hawtjni.runtime.JniField;
017    import org.fusesource.hawtjni.runtime.JniMethod;
018    import org.fusesource.hawtjni.runtime.Library;
019    
020    import static org.fusesource.hawtjni.runtime.ArgFlag.*;
021    import static org.fusesource.hawtjni.runtime.FieldFlag.*;
022    import static org.fusesource.hawtjni.runtime.MethodFlag.*;
023    
024    /**
025     * 
026     * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027     */
028    @JniClass
029    public class Example {
030        
031        private static final Library LIBRARY = new Library("hawtjni-example", Example.class);    
032            static {
033            LIBRARY.load();
034            init();
035            }
036    
037        public static final void main(String args[]) {
038    
039            System.out.println("Checking Operating System Constants:");
040            System.out.println(" O_RDONLY: "+O_RDONLY);
041            System.out.println(" O_WRONLY: "+O_WRONLY);
042            System.out.println("   O_RDWR: "+O_RDWR);
043            System.out.println("");
044    
045            System.out.println("Allocating c structures on the heap...");
046            int COUNT = 10;
047            // We track memory pointers with longs.
048            long []ptrArray = new long[COUNT];        
049            long last=0;
050            for( int i=0; i < COUNT; i++ ) {
051                // Allocate heap space of the structure..
052                ptrArray[i] = malloc(foo.SIZEOF);
053    
054                // Configure some data for a structure...
055                foo f = new foo();
056                f.a = i;
057                f.b = 1;
058                
059                byte[] src = "hello world".getBytes();
060                System.arraycopy(src, 0, f.c, 0, src.length);
061                
062                f.c5 = 0;
063                f.prev = last;
064                
065                // Copy the data values into the allocated space.
066                memmove(ptrArray[i], f, foo.SIZEOF);
067                
068                last = ptrArray[i];
069            }
070            
071            // Display a couple of structures...
072            System.out.println("Dump of the first 2 structures:");
073            print_foo(ptrArray[0]);
074            print_foo(ptrArray[1]);
075            
076            System.out.println("Passing a pointer array to a c function...");
077            long rc = foowork(ptrArray, COUNT);
078            System.out.println("Function result (expecting 55): "+rc);
079            
080            System.out.println("freein up allocated memory.");
081            for( int i=0; i < COUNT; i++ ) {
082                free(ptrArray[i]);
083            }
084        }
085    
086        // Example of how to load constants.
087        @JniMethod(flags={CONSTANT_INITIALIZER})
088        private static final native void init();
089    
090        @JniField(flags={CONSTANT})
091        public static int O_RDONLY;
092        @JniField(flags={CONSTANT})
093        public static int O_WRONLY;
094        @JniField(flags={CONSTANT})
095        public static int O_RDWR;
096        
097        @JniMethod(cast="void *")
098        public static final native long malloc(
099                @JniArg(cast="size_t") long size);
100        
101        public static final native void free(
102                @JniArg(cast="void *") long ptr);
103        
104    
105        public static final native void memmove (
106                @JniArg(cast="void *") long dest, 
107                @JniArg(cast="const void *") long src, 
108                @JniArg(cast="size_t") long size);
109    
110        public static final native void memmove (
111                @JniArg(cast="void *") long dest, 
112                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 
113                @JniArg(cast="size_t") long size);
114    
115        public static final native void memmove (
116                @JniArg(cast="void *") long dest, 
117                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) char[] src, 
118                @JniArg(cast="size_t") long size);
119    
120        public static final native void memmove (
121                @JniArg(cast="void *") long dest, 
122                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL})  short[] src, 
123                @JniArg(cast="size_t") long size);
124    
125        public static final native void memmove (
126                @JniArg(cast="void *") long dest, 
127                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL})  int[] src, 
128                @JniArg(cast="size_t") long size);
129    
130        public static final native void memmove (
131                @JniArg(cast="void *") long dest, 
132                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) long[] src, 
133                @JniArg(cast="size_t") long size);
134    
135        public static final native void memmove (
136                @JniArg(cast="void *") long dest, 
137                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) float[] src, 
138                @JniArg(cast="size_t") long size);
139    
140        public static final native void memmove (
141                @JniArg(cast="void *") long dest, 
142                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) double[] src, 
143                @JniArg(cast="size_t") long size);
144    
145        
146        
147        public static final native void memmove (
148                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 
149                @JniArg(cast="const void *") long src, 
150                @JniArg(cast="size_t") long size);
151    
152        public static final native void memmove (
153                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) char[] dest, 
154                @JniArg(cast="const void *") long src, 
155                @JniArg(cast="size_t") long size);
156    
157        public static final native void memmove (
158                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) short[] dest, 
159                @JniArg(cast="const void *") long src, 
160                @JniArg(cast="size_t") long size);
161    
162        public static final native void memmove (
163                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 
164                @JniArg(cast="const void *") long src, 
165                @JniArg(cast="size_t") long size);
166    
167        public static final native void memmove (
168                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) long[] dest, 
169                @JniArg(cast="const void *") long src, 
170                @JniArg(cast="size_t") long size);
171        
172        public static final native void memmove (
173                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) float[] dest, 
174                @JniArg(cast="const void *") long src, 
175                @JniArg(cast="size_t") long size);
176    
177        public static final native void memmove (
178                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) double[] dest, 
179                @JniArg(cast="const void *") long src, 
180                @JniArg(cast="size_t") long size);
181    
182        public static final native void memmove (
183                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) byte[] dest, 
184                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL})  char[] src, 
185                @JniArg(cast="size_t") long size);
186    
187        public static final native void memmove (
188                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) int[] dest, 
189                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) byte[] src, 
190                @JniArg(cast="size_t") long size);
191    
192        @JniMethod(cast="void *")
193        public static final native long memset (
194                @JniArg(cast="void *") long buffer, 
195                int c, 
196                @JniArg(cast="size_t") long num);
197        
198        public static final native int strlen(
199                @JniArg(cast="char *")long s);
200        
201        @JniClass(flags={ClassFlag.STRUCT})
202        static public class foo {
203            
204            static {
205                LIBRARY.load();
206                init();
207            }
208            
209            @JniMethod(flags={CONSTANT_INITIALIZER})
210            private static final native void init();
211    
212    //        public static final native int foo_sizeof ();
213            
214            @JniField(flags={CONSTANT}, accessor="sizeof(struct foo)")
215            public static int SIZEOF;
216    
217            public int a;
218            
219            @JniField(cast="size_t")
220            public long b;
221            
222            public byte c[] = new byte[20];
223    
224            @JniField(accessor="c[5]")
225            public byte c5;
226            
227            @JniField(cast="void *")
228            public long prev;
229    
230            @Override
231            public int hashCode() {
232                final int prime = 31;
233                int result = 1;
234                result = prime * result + a;
235                result = prime * result + (int) (b ^ (b >>> 32));
236                result = prime * result + Arrays.hashCode(c);
237                result = prime * result + c5;
238                result = prime * result + (int) (prev ^ (prev >>> 32));
239                return result;
240            }
241    
242            @Override
243            public boolean equals(Object obj) {
244                if (this == obj)
245                    return true;
246                if (obj == null)
247                    return false;
248                if (getClass() != obj.getClass())
249                    return false;
250                foo other = (foo) obj;
251                if (a != other.a)
252                    return false;
253                if (b != other.b)
254                    return false;
255                if (!Arrays.equals(c, other.c))
256                    return false;
257                if (c5 != other.c5)
258                    return false;
259                if (prev != other.prev)
260                    return false;
261                return true;
262            }
263    
264            @Override
265            public String toString() {
266                return "foo [a=" + a + ", b=" + b + ", c=" + Arrays.toString(c) + ", c5=" + c5 + ", prev=" + prev + "]";
267            }
268            
269        }    
270        
271        public static final native void memmove (
272                @JniArg(cast="void *") long dest, 
273                @JniArg(cast="const void *", flags={NO_OUT, CRITICAL}) foo src, 
274                @JniArg(cast="size_t") long size);
275        
276        public static final native void memmove (
277                @JniArg(cast="void *", flags={NO_IN, CRITICAL}) foo dest, 
278                @JniArg(cast="const void *") long src, 
279                @JniArg(cast="size_t") long size);
280    
281        public static final native void print_foo(@JniArg(cast="struct foo *")long ptr);
282        public static final native long foowork (@JniArg(cast="struct foo **") long[] foos, int count);
283    
284        @JniClass(flags={ClassFlag.STRUCT, ClassFlag.TYPEDEF})
285        static public class point {
286            static {
287                LIBRARY.load();
288                init();
289            }
290            
291            @JniMethod(flags={CONSTANT_INITIALIZER})
292            private static final native void init();
293    
294            @JniField(flags={CONSTANT}, accessor="sizeof(point)")
295            public static int SIZEOF;
296    
297            public int x;
298            public int y;
299        }
300        
301        public static final native void callmeback(@JniArg(cast="void *")long ptr);
302        
303    }